New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial fetch timeout (with working tests) #4193
Initial fetch timeout (with working tests) #4193
Commits on May 19, 2021
-
jest config [nfc]: Use a new
projectForPlatform
instead ofcommon
.Soon, there'll be a kind of annoying thing we have to do with custom Jest presets, and we want to have a good place to put a single long-ish comment about it. So, make it so that we only have to say `preset: ` once, and plan to put the comment just above that.
Configuration menu - View commit details
-
Copy full SHA for 3ccc3ba - Browse repository at this point
Copy the full SHA 3ccc3baView commit details -
jest config [nfc]: Move
displayName
,preset
to the top.And remove a blank line that looks like it shouldn't be there.
Configuration menu - View commit details
-
Copy full SHA for b9e5b0a - Browse repository at this point
Copy the full SHA b9e5b0aView commit details -
fetchActions tests: Mock fetch response for fetchNewer/fetchOlder tests.
We don't actually use this response (hence why we choose the boring mock), but it's cleaner not to have unhandled promise rejections from the `.json` property being missing on the response.
Configuration menu - View commit details
-
Copy full SHA for fff1d37 - Browse repository at this point
Copy the full SHA fff1d37View commit details -
fetchActions tests: Use
reduxStatePlus
.This is our more "batteries-included" Redux state, with standard example data like `selfUser`; see its jsdoc.
Configuration menu - View commit details
-
Copy full SHA for 7fd0b08 - Browse repository at this point
Copy the full SHA 7fd0b08View commit details -
jest: Fix jestjs/jest#10221 locally.
This is much easier than forking React Native, as we considered in zulip/react-native#5. See jestjs/jest#10221 (comment).
Configuration menu - View commit details
-
Copy full SHA for 8e897b9 - Browse repository at this point
Copy the full SHA 8e897b9View commit details -
fetchActions tests: Remove a trivial test.
`tryFetch` requires the passed function to have a `Promise` return type; it's unnecessary to check its behavior when the passed function doesn't have a `Promise` return type.
Configuration menu - View commit details
-
Copy full SHA for 7bb6e3b - Browse repository at this point
Copy the full SHA 7bb6e3bView commit details -
Configuration menu - View commit details
-
Copy full SHA for c913d09 - Browse repository at this point
Copy the full SHA c913d09View commit details -
fetchActions tests: Make the
tryFetchFunc
s more parallel.So it's easier to compare the inputs we're testing. 10ms is a realistic amount of time for an API request to take. It's also less than 100ms, which had been used for one of these. So, our tests will run a bit faster (and they'll run a lot faster when we switch over to fake timers soon).
Configuration menu - View commit details
-
Copy full SHA for 2c5e614 - Browse repository at this point
Copy the full SHA 2c5e614View commit details -
fetchActions tests: Use fake timers for
tryFetch
's tests.And make the tests more rigorous while we're at it. When we add a timeout to `tryFetch`, we'll want to use fake timers so that the tests don't try to do inconvenient things like waiting a whole minute for something to happen.
Configuration menu - View commit details
-
Copy full SHA for d02d78c - Browse repository at this point
Copy the full SHA d02d78cView commit details -
Configuration menu - View commit details
-
Copy full SHA for 1f4fd49 - Browse repository at this point
Copy the full SHA 1f4fd49View commit details -
fetchActions tests: Test retry logic with a more representative error.
The fact that this test passes isn't good -- it means a basically arbitrary, unexpected kind of error will let the retry loop continue without propagating to `tryFetch`'s caller. We'll fix that logic soon, and add a test case with an error like that. But for now, test that we get the right behavior with representative inputs.
Configuration menu - View commit details
-
Copy full SHA for 3c1596e - Browse repository at this point
Copy the full SHA 3c1596eView commit details -
We'll use this in `tryFetch`, in an upcoming commit, so that we can interrupt in-progress attempts to contact a server when they take too long. See discussion [1]. [1]: https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/Stuck.20on.20loading.20screen/near/907693
Configuration menu - View commit details
-
Copy full SHA for b09d24a - Browse repository at this point
Copy the full SHA b09d24aView commit details -
Configuration menu - View commit details
-
Copy full SHA for d695252 - Browse repository at this point
Copy the full SHA d695252View commit details -
Configuration menu - View commit details
-
Copy full SHA for 387dc53 - Browse repository at this point
Copy the full SHA 387dc53View commit details -
redux: Add boilerplate for
INITIAL_FETCH_ABORT
action.To be dispatched when it doesn't seem like we'll get a response from the server, or when the server responds with a 5xx error. It navigates to the 'accounts' screen so a user can try a different account and server. Logging out wouldn't be good; the credentials may be perfectly fine, and we'd like to keep them around to try again later. It sets `needsInitialFetch` to `false` [1], just like `INITIAL_FETCH_COMPLETE`, while retaining a different meaning than that action (i.e., that the fetch was aborted instead of completed). Setting `needsInitialFetch` to false is necessary to ensure that a subsequent initial fetch can be triggered when we want it to be. As also noted in 7caa4d0, `needsInitialFetch` is "edge-triggered". (That edge-triggering logic seems complex and fragile, and it would be nice to fix that.) See also discussion [1]. [1]: https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/Stuck.20on.20loading.20screen/near/907591
Configuration menu - View commit details
-
Copy full SHA for 70cf1ad - Browse repository at this point
Copy the full SHA 70cf1adView commit details -
fetchActions: Fail early on all non-5xx errors in
tryFetch
.Change the condition for exiting the retry loop from `isClientError(e)` to `!isServerError(e)`.
Configuration menu - View commit details
-
Copy full SHA for d8818f6 - Browse repository at this point
Copy the full SHA d8818f6View commit details -
Configuration menu - View commit details
-
Copy full SHA for cebac50 - Browse repository at this point
Copy the full SHA cebac50View commit details -
fetchActions: Add a timeout to
tryFetch
.So far, `tryFetch`'s only callers are in the initial fetch; so, add handling for the `TimeoutError` there. The choice of value for `requestLongTimeoutMs` comes from a suggestion in zulip#4165's description: > As a minimal version, if the initial fetch takes a completely > unreasonable amount of time (maybe one minute), we should give up > and take you to the account-picker screen so you can try a > different account and server. Fixes: zulip#4165
Configuration menu - View commit details
-
Copy full SHA for 83bd132 - Browse repository at this point
Copy the full SHA 83bd132View commit details -
fetchActions: Pull
await backoffMachine.wait()
out ofcatch
block.As Greg points out [1], this makes the most sense conceptually; it's happening at the bottom of the loop, just before a new iteration starts. The `return` in the `try` block is enough to ensure that this wait won't interfere with a successful fetch. [1]: zulip#4166 (comment)
Configuration menu - View commit details
-
Copy full SHA for 04a0507 - Browse repository at this point
Copy the full SHA 04a0507View commit details -
fetchActions: Stop retrying on server errors in the initial fetch.
Greg points out that the initial fetch isn't actually a place where we want to retry on 5xx errors [1]: > Ah, I think in #M4165 the point is that if the server isn't > responding, we want to give you the option to go choose some other > account. The context there is that we're in the initial fetch, so > showing the loading screen, and as long as we're doing that > there's no other UI. > So yeah, I think basically we don't want to do any retrying here. > Instead we can kick you to the account-picker screen, with a toast > or something to indicate an error, and then you might manually > retry a time or two or you might bail and switch to some other > account. > And in particular if you didn't even want to be using that account > anymore -- maybe you even know that it's a server which is > permanently shut down, but it just happened to be the last one > you'd been using in the app and so it's the one we tried loading > data from on startup -- then you can go use whatever other account > you were actually opening the app to use. This does mean that `tryFetch` now has no callsites. It's a useful function, so we'll add a useful callsite soon so the function still gets exercised and maintained as appropriate. [1] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/Stuck.20on.20loading.20screen/near/1178689
Configuration menu - View commit details
-
Copy full SHA for b85b46b - Browse repository at this point
Copy the full SHA b85b46bView commit details -
fetchActions: Retry message fetch with a timeout.
A `TimeoutError` will be handled the same way other errors in `fetchMessages` are handled; if it's a timeout in the fetch `ChatScreen` does on mount, `ChatScreen` will show the `FetchError` component we set up in zulip#4205. There's also been a passing mention on CZO of doing a timeout like this [1]: > After a long time, probably like a minute, we'll want that [...] > fetch to time out and fail in any case. [1] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.23M4156.20Message.20List.20placeholders/near/950853
Configuration menu - View commit details
-
Copy full SHA for 7b408b5 - Browse repository at this point
Copy the full SHA 7b408b5View commit details -
FetchError: Show a specific message if the error is a
TimeoutError
.And add that message and the existing message to messages_en.json; looks like we forgot to add the existing one.
Configuration menu - View commit details
-
Copy full SHA for d812dd1 - Browse repository at this point
Copy the full SHA d812dd1View commit details -
Use Jest's "modern" fake timers instead of our Lolex wrapper. Also, remove one `describe` block for tests that examine an edge-case safety feature that we built into our Lolex wrapper, but that doesn't seem to exist in Jest. Ah, well.
Configuration menu - View commit details
-
Copy full SHA for 2d59731 - Browse repository at this point
Copy the full SHA 2d59731View commit details -
queueMarkAsRead tests: Remove Lolex.
Use Jest's "modern" fake timers instead of our Lolex wrapper.
Configuration menu - View commit details
-
Copy full SHA for c6095e2 - Browse repository at this point
Copy the full SHA c6095e2View commit details -
heartbeat tests: Remove Lolex.
Use Jest's "modern" fake timers instead of our Lolex wrapper.
Configuration menu - View commit details
-
Copy full SHA for 81326ac - Browse repository at this point
Copy the full SHA 81326acView commit details -
Use Jest's "modern" fake timers instead of our Lolex wrapper.
Configuration menu - View commit details
-
Copy full SHA for 5e1726d - Browse repository at this point
Copy the full SHA 5e1726dView commit details -
backoffMachine tests: Remove Lolex.
Use Jest's "modern" fake timers instead of our Lolex wrapper.
Configuration menu - View commit details
-
Copy full SHA for f6f6669 - Browse repository at this point
Copy the full SHA f6f6669View commit details -
tests: Remove our Lolex wrapper, uninstall Lolex.
We've entirely switched over to Jest's "modern" fake timers, which landed in jestjs/jest#7776.
Configuration menu - View commit details
-
Copy full SHA for 6f592c7 - Browse repository at this point
Copy the full SHA 6f592c7View commit details -
jest: Make "modern" fake-timer implementation the default.
Also, remove several now-unnecessary calls of `jest.useFakeTimers('modern')`, but keep a few assertions that the "modern" timers are actually being used. In particular, our `jestSetup` is a central place where we make the assertion. Not only is it good to check that we still intentionally set the "modern" implementation, but we want to make sure that the setting is correctly applied. See the note in fb23341 about it being silently not applied until we added @jest/source-map as a direct dependency. We have an ESLint rule, from 2faad06, preventing imports from '**/__tests__/**'; the rule is active in all files not matching that same pattern. Add an additional override so that we can make the "modern"-timers assertion from within `jest/jestSetup.js`.
Configuration menu - View commit details
-
Copy full SHA for 2fb95b3 - Browse repository at this point
Copy the full SHA 2fb95b3View commit details -
async tests [nfc]: Put BackoffMachine tests where they belong.
Follow and delete a code comment at the top of `backoffMachine-test`, suggesting that we move these tests.
Configuration menu - View commit details
-
Copy full SHA for 8c20c8b - Browse repository at this point
Copy the full SHA 8c20c8bView commit details