Description
As described in #184, when a long-poll for events fails, the current prototype just stops polling. That issue is about transient failures; this one is for an important, non-transient, but recoverable, class of error.
Namely, if the long-poll fails because the event queue is gone, we should create a new event queue and go from there. Here's from zulip-mobile at startEventPolling
:
while (true) {
// …
try {
const response = await api.pollForEvents(auth, queueId, lastEventId);
// …
} catch (errorIllTyped) {
const e: mixed = errorIllTyped; // https://github.com/facebook/flow/issues/2470
// We had an error polling the server for events.
// …
if (e instanceof ApiError && e.code === 'BAD_EVENT_QUEUE_ID') {
// The event queue is too old or has been garbage collected.
dispatch(deadQueue()); // eslint-disable-line no-use-before-define
break;
and we can use similar logic for detecting this condition.
For what to do once the condition is detected, zulip-mobile is not as good a model and we should think it through afresh. We'll need to register a new event queue, get a new initial snapshot, re-initialize data from there, and resume polling. For any open message lists, we'll also want to re-fetch messages, as that's the one major area of the data model that isn't covered by the initial snapshot. (For any minor such areas, we'll want to similarly refresh any data we have.)
I think the cleanest way to approach this will be to actually create a new PerAccountStore
for the fresh data, and then tell each PerAccountStoreWidget
that had the old store to replace it with the new one. Further thoughts:
- For the bulk of our application code, this should work smoothly straight out of the box. That's because the normal pattern is to say
final store = PerAccountStoreWidget.of(context);
whenever in need of aPerAccountStore
, and never to hang on to aPerAccountStore
beyond the end of the build method or UI-event handler. That.of
method creates a dependency on the ancestor widget; so when there's a new store, the descendant element will get notified and rebuilt. The rebuild will get the store afresh, as always, and therefore use the new store and won't even notice that it isn't the same object as the old store.- This underlines why the proper idiom is to always get a
PerAccountStore
fresh like that, and not to hang onto one or pass one around. Instead, pass around aBuildContext
.
- This underlines why the proper idiom is to always get a
- After creating a fresh
PerAccountStore
, we can go on to create freshMessageListView
objects corresponding to each of those that are currently registered, and have them fetch messages corresponding to the range of messages the existing views have.- This is one of the advantages of making a fresh
PerAccountStore
— thoseMessageListView
s can refer to the newPerAccountStore
while the oldMessageListView
s continue to refer to the old store, and there's no risk of inconsistent data from having an old view-model refer to a store with new data or vice versa. - → Split this extra bit of polish out as msglist: On new event queue, try to re-fetch messages before switching to new store #464.
- This is one of the advantages of making a fresh
- The
PerAccountStore
can also grow a field likebool isStale
, which can be set to true immediately when the expired queue is detected, while we're still working on fetching data for the new store. Then that field can drive a "Connecting…" banner, or equivalent UI for letting the user know that the data they're looking at may be out of date and the app is working on it.- → Split this out as a followup Show "Connecting…" banner (or equivalent) when server data is stale #465.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Activity
autocomplete [nfc]: Use new mixin for ComposeAutocomplete's state
autocomplete [nfc]: Use new mixin for ComposeAutocomplete's state
autocomplete [nfc]: Use new mixin for ComposeAutocomplete's state
autocomplete [nfc]: Use new mixin for ComposeAutocomplete's state
autocomplete [nfc]: Use new mixin for ComposeAutocomplete's state
14 remaining items