Skip to content

fix(app): a requested refresh can coalesce onto an older in-flight api() request (invalidateApiCache does not clear _inflight) #243

Description

@dborup

Relates to #232, #238

Problem

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).
  • Keep the request token from fix(channels): drop stale channel-list responses and show the unread badge on mobile (#154, #155) #225 (channelsRequestId), so that an older response is still dropped.
  • 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions