You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(app): a requested refresh can coalesce onto an older in-flight api() request (invalidateApiCache does not clear _inflight) #243
invalidateApiCache('/channels') in public/app.js clears only the TTL cache. It does not clear api()'s _inflight map.
If a /channels request is already in flight when a refresh is requested, the refresh coalesces onto the older request and can render without the newly approved channel until the next refresh. A refresh is requested by onApproved after an admin decision or an auto-approve (#238). A request can already be in flight because of a region change, the encrypted toggle, or a second approval within one round-trip.
This existed on the admin path before #238. #238 adds a second trigger, and the window is small: a status poll waits at least one poll delay. It was found in the #238 review and has not been reproduced.
The same review found a test gap: nothing pins that ChannelProposals.unmount() cancels the suggest poller. A mutant that drops state.suggestPoller.cancel() survives the proposals and client-state tests.
Proposed fix
Give api() a way to bypass _inflight for an explicit refresh, e.g. api(path, { bust: true }), or an in-flight generation that a refresh bumps. Use it from loadChannels(true).
Add a unit test with controlled api() timing: a refresh during an in-flight request must render the newer data.
Add a test that unmount() cancels the suggest poller.
Acceptance
A refresh requested while a /channels request is in flight results in a list that includes the newly approved channel, with no extra request in the normal case.
Both new tests fail before the fix, and the mutants named above are killed.
Relates to #232, #238
Problem
invalidateApiCache('/channels')inpublic/app.jsclears only the TTL cache. It does not clearapi()'s_inflightmap.If a
/channelsrequest is already in flight when a refresh is requested, the refresh coalesces onto the older request and can render without the newly approved channel until the next refresh. A refresh is requested byonApprovedafter an admin decision or an auto-approve (#238). A request can already be in flight because of a region change, the encrypted toggle, or a second approval within one round-trip.This existed on the admin path before #238. #238 adds a second trigger, and the window is small: a status poll waits at least one poll delay. It was found in the #238 review and has not been reproduced.
The same review found a test gap: nothing pins that
ChannelProposals.unmount()cancels the suggest poller. A mutant that dropsstate.suggestPoller.cancel()survives the proposals and client-state tests.Proposed fix
api()a way to bypass_inflightfor an explicit refresh, e.g.api(path, { bust: true }), or an in-flight generation that a refresh bumps. Use it fromloadChannels(true).channelsRequestId), so that an older response is still dropped.api()timing: a refresh during an in-flight request must render the newer data.unmount()cancels the suggest poller.Acceptance
/channelsrequest is in flight results in a list that includes the newly approved channel, with no extra request in the normal case.