Repository navigation
connections: live refresh driven by an address-book change counter - #270
jseifeddine wants to merge 1 commit into
Conversation
3997caa to
e454936
Compare
|
My main concern here is load. Every open Connections tab polls every 3 seconds, and on any change, plus every 2 minutes regardless, reloads everything including the search index, which reads every entry from Vault. With NetBox webhooks firing and a few dozen tabs open, that's a lot of Vault reads on a big address book. Could the 2 minute refresh go, and the search index refresh only when search is actually used, or per changed folder? Also, Also, since the PRs are stacked, could you rebase this onto main on its own so it can be taken separately? |
e454936 to
0921985
Compare
|
Rebased onto main as its own change, and reworked for load. The 2-minute refresh is gone; nothing reloads on a timer any more. The version endpoint now answers from memory with the folders that changed since the version a tab last saw, and a tab only re-reads the folder it has open, or the folder list (no entries) when a folder came or went; a change in a folder you aren't looking at reads nothing. The search index is never rebuilt on a poll: it's marked stale and rebuilt only when the search box is next used, and while results are showing just the changed folder's rows are patched. /api/me/credentials no longer touches the counter at all; the saving tab refreshes its own status. Worst case per change per tab is one folder's entries plus one folder listing, however many tabs are open, and a poll costs no Vault read. The CI audit failure on this branch is the new quinn-proto advisories, not this change; #283 bumps the lockfile and the run goes green once that is in. |
connections: live refresh from a per-folder address-book change counter The Connections page keeps itself current without reloading. rustguac keeps an in-memory change log of the address book: every successful write through its API (entries, folders, folder config, moves, copies, bulk) is logged against the folders it touched under a version counter. The page polls GET /api/addressbook/version?since=N every 3 seconds while visible and gets back only what changed after the version it last saw: one row per folder, saying whether its entries or the folder itself moved. The poll is answered from memory; it reads nothing from Vault. A tab acts only on what it shows. Entries changed in the open folder: that folder is re-read. Entries changed elsewhere: the cached copy is forgotten and nothing is read until the folder is opened. A folder created, deleted or reconfigured: the folder list is re-read (no entries), plus the open folder if it was in that subtree. The search index is never rebuilt on a poll: it is marked stale and rebuilt the next time the box is focused or typed in; while results are showing, only the changed folder's rows are re-read and patched in. So one change costs a tab at most one folder's entries plus one folder-list listing, never the whole book, however many tabs are open. There is no timed refresh. A null answer (first poll, restart, or a tab further behind than the 512-entry log reaches) refreshes what is shown once, under the same bound. Folders are attributed from the request path; the four routes whose folders only the body knows (create folder, move, copy, bulk) report them from the handler through a response extension, and a handler that reports nothing is logged as `all` so a page refreshes rather than misses it. A user's own credential variables (/api/me/credentials) are not address-book changes and never reach the log: the saving tab reloads its own status, and no other tab needs to know. Hidden tabs do not poll and catch up with an immediate check when shown; a tab with a dialog open does not poll either, so the change waits for the dialog instead of being missed. Tests: the attribution table, the log's since/dedup/eviction/restart answers, the middleware on a router (a credentials save logs nothing, a failed write logs nothing, reported folders are logged precisely), and a plain-node test pinning what the page re-reads for each change. Closes sol1#253 (part 3/3).
0921985 to
d3641b6
Compare
Based on current
mainon its own: one commit, nothing from any other open PR. Nothing from #268 or #269 and no need of them.Closes #253 (part 3/3).
What it does
The Connections page keeps itself current without reloading. rustguac keeps an in-memory change log of the address book: every successful write through its API (entries, folders, folder config, moves, copies, bulk) is logged against the folders it touched, under a version counter. The page polls
GET /api/addressbook/version?since=Nevery 3 seconds and gets back only what changed after the version it last saw: one row per folder, saying whether the folder's entries or the folder itself (created, deleted, config) moved.The page then acts only on what it shows:
Worst-case Vault reads per address-book change, per open tab: one folder's entries (the open folder) plus one folder-list listing (when a folder came or went). Never the whole book, never the search walk. A poll reads nothing from Vault.
changes: null(first poll, server restart, or a tab that fell further behind than the log's 512 entries reach) makes the tab refresh what it shows once: the folder list and the open folder, same bound. Hidden tabs do not poll and catch up with an immediate check when shown; a tab with a dialog open does not poll either, so the change waits for the dialog instead of being missed. There is no timed refresh of any kind.A user's own credential variables (
PUT /api/me/credentials) are not address-book changes and never reach the log. The tab that saved them already reloads its own credential status, which is the only tab that needs to know.Attribution is by request path for the routes that name their folder; the four whose folders only the body knows (create folder, move, copy, bulk) report them from the handler through a response extension, and a handler that reports nothing is logged as
allso the page refreshes rather than misses it. The log is per process, as before.Review changes
Dave's review, point by point:
nullanswer, moves anything.searchIndexStale) and it is rebuilt only when search is next used (focus or typing in the box). While results are showing, the changed folder's entries are re-read and its rows patched into the index, bounded to the changed folders. A folder re-read for the view patches the index for free.GET /api/addressbook(which reads every top-level folder's entries) is not called by the live refresh at all./api/me/credentialsbumping the global counter: removed. It is not an address-book change;ab_changes_for_requestreturnsNonefor it, and the middleware test proves a successfulPUT /api/me/credentialsleaves the log untouched. The saving tab reloads its own status locally, as it already did.mainas its own change.Also: the version endpoint is answered from memory (
AddressBookChanges::since); the handler touches neither Vault nor disk. The request still passes through the auth layer like every API call (a session-cookie lookup in SQLite), which this PR does not change.Tests
Rust (
src/api.rs):address_book_change_attribution: which method and path mean which change, folder segments decoded (a%2Fb), connects and reads are not changes,/api/me/credentialsis not a change.address_book_change_log_since: the log answers exactly what came after the version the page saw, collapses repeats,allswallows the rest, and a page ahead of the log (restart) is told to refresh.address_book_change_log_forgets_the_oldest: a range the ring no longer holds in full answersnullrather than a partial list.address_book_change_track_middleware: on a real router, a credentials save logs nothing, an entry write is logged against its decoded folder, a failed write logs nothing, a handler-reported folder is logged precisely, and an unreported body-dependent route is logged asall.Plain node (
tests/connections-live.mjs, picked up by the CI client-tests loop): pins what the page re-reads for each kind of change, in particular that a change in a folder you are not looking at reads nothing, that no change rebuilds the index, and that the folder list is re-read only when a folder came or went.The browser spec from the earlier version of this PR relied on the Playwright harness from #266, which is not on
main; it is not included.