-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Network Cleanup: Isolate "persisted " queue from "main" queue #8312
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall super stoked about these changes and very impressed by how much you've been able to unpack our Network code to make it more approachable. Really, excellent work. Did have a few comments, questions, and suggestions.
let networkReady = false; | ||
let hasReadRequiredData = false; | ||
let authenticating = false; | ||
let isOffline = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do all this later (as part of offline-first doc) if you prefer, but should we assume that we're offline unless we know otherwise?
let isOffline = false; | |
let isOffline = true; |
Further, if we made that change, could we remove the self-proclaimed hack for checkRequiredData
?
- We assume that we're offline until we know otherwise
- We won't know otherwise (and set
isOffline = false
unless Onyx has triggered theOnyx.connect
callback for theNETWORK
key - So we don't have to check if Onyx has read the
authToken
andcredentials
from storage before clearing the network lib to make request
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good thoughts. I don't have a clear answer about which would be better from an Offline First Doc perspective and would have to weigh some pros/cons.
I don't think we can remove that hack if we do this anyway as there's no guarantee we won't set isOffline
to true
before the credentials
and authToken
are ready. It's maybe adding some delay, but not the same as the guarantee we have now.
src/libs/Network/processRequest.js
Outdated
*/ | ||
export default function processRequest(request) { | ||
const finalParameters = enhanceParameters(request.command, request.data); | ||
const cancelRequestTimeoutTimer = NetworkEvents.startRequestTimeoutTimer(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, what happens if the request times out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We "trigger a connection recheck", but I'll leave a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kinda move this so we wouldn't have to explain what happens and just emit and event. But the event is hardcoded in :D
persistedRequestsQueueRunning = true; | ||
|
||
// Ensure persistedRequests are read from storage before proceeding with the queue | ||
const connectionId = Onyx.connect({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, it's probably just a me problem, but I'm confused how this is working and have a few questions:
- Why connect and disconnect instead of just relying on
Onyx.connect
to keep the persisted requests up-to-date? This feels like a hack b/c we're simulatingOnyx.get
here, though I'm sure it's a necessary one for now. - What triggers the
PersistedRequestsQueue
to flush? The only usage I see is here, and that seems like it would only run on app init?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. It's a hack that ensures we don't start processing the queue until the requests have been read from storage. This mostly only matters on app init so we could probably improve this further (as we are subscribing in PersistedRequests
as well and could use that). We might be able to use the createOnReadyTask
to workaround this for now (but I'm not gonna add that here).
What triggers the PersistedRequestsQueue to flush? The only usage I see is here, and that seems like it would only run on app init?
Main usage here and runs when we go from offline to online
App/src/libs/Network/PersistedRequestsQueue.js
Lines 90 to 91 in f4c1cb2
// Flush the queue when the connection resumes | |
NetworkEvents.onConnectivityResumed(flush); |
Thanks for the review @roryabraham. Updated and hopefully answered all the questions you had! |
Sounds like there are a few more improvements we could make, but we can do that in a follow-up PR(s). Thanks again for cleaning this up. |
return Network.post(originalCommand, originalParameters, originalType); | ||
} | ||
|
||
// Prevent any more requests from being processed while authentication happens | ||
Network.pauseRequestQueue(); | ||
isAuthenticating = true; | ||
NetworkStore.setIsAuthenticating(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB: I think we can use NetworkStore.isAuthenticating()
and NetworkStore.setAuthenticating(value)
for this boolean value, no? https://airbnb.io/javascript/#accessors--boolean-prefix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe - though unsure if we follow that guidance strictly. I had it like that but changed it as I couldn't think of a way to do that without changing the variable name here...
App/src/libs/Network/NetworkStore.js
Line 11 in c39f2cf
let isAuthenticating = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't see a problem renaming it to authenticating
since it's only used as a private variable and the NetworkStore
is a small file, but that's just my opinion :)
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by @marcaaron in version: 1.1.47-0 🚀
|
🚀 Deployed to production by @roryabraham in version: 1.1.49-1 🚀
|
Hey, I'm slightly concerned that this PR may have introduced this exception (or at least, made the error more visible). This is the only recent PR I can see which touches the network code in the last couple of releases. Specifically, I believe we're seeing one of these functions being called before being defined. Does that seem at all possible to you? |
Yes, and it's probably this one -> App/src/libs/NetworkConnection.js Line 123 in 8419bd4
Is it possible that this has existed before? I don't think we changed anything about when the recheck callback should run and this PR mostly was a re-organization of existing logic. |
I'm slightly hesitant to move forward without better evidence, but yeah that does seem to be the case. With the occurrences spiking on a single day and no specific code changes which directly modified the problematic area I think it's okay to continue with the release and continue to monitor the crash. |
FYI I submitted a quick PR and I'm moving on with the release. |
Thanks @Julesssss ! |
This PR might have caused #14584 regression. |
Thanks @sobitneupane. To clarify, it might have caused it or did cause it? If so, how? Can we figure it out? |
I thought introduction of following code in PersistedRequests.js might have caused the issue.
But it was there even before and introduced by 5cd8b4a commit. |
Got it, thanks for looking into that and clarifying. I think these changes are old enough that there's nothing actionable and I checked off the steps here. |
Details
Another round of Network refactoring. For this one, I focused on making the "persisted requests queue" more distinct from the "main request queue" with renames and making files more modular.
ONYXKEYS.NETWORK_REQUEST_QUEUE
toPERSISTED_REQUESTS
because that's what we use it for and "network request queue" is ambiguousNetworkEvents
filehasReadRequiredDataFromStorage()
RetryCounter
classprocessRequest()
method to it's own fileNetwork/index.js
and extracted the logic that pulls requests out of the main queue and into the persist queue and the logic for retrying main queue requests when they failactions/NetworkRequestQueue
toPersistedRequests
and gave it a separate "retry counter" instance (h/t @roryabraham) as that got a little mixed up in this PR, but seems like a fine addition to have for now. Though I am a little unsure how this would look for users who get a fetch error while making a blocking request. Seems like by perpetually retrying it would take a long time for them to see something "stop loading".Fixed Issues
No issue but related to Offline First project
Tests
Automated tests should cover most of these changes as we are mainly refactoring
QA Steps
No specific QA as no behavior has changed, but keep a lookout for anything like loading spinners, offline stuff that was working not working, etc.