-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Reset backoff when connectivity status changes #5857
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
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.
Is it possible to test the new behavior? (I think all existing tests that emulate connectivity changes are in test/unit/remote/grpc_connection_test.cc
, see if it's possible to write similar tests for this)
Firestore/CHANGELOG.md
Outdated
@@ -1,3 +1,8 @@ | |||
# Unreleased | |||
- [fixed] Removed a delay that may have prevented Firestore from immediately | |||
establishing a network connections if a connectivity change occurred while |
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.
Nit: either "a network connection" or "network connections".
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.
Fixed
Datastore::Datastore(const DatabaseInfo& database_info, | ||
const std::shared_ptr<AsyncQueue>& worker_queue, | ||
std::shared_ptr<CredentialsProvider> credentials, | ||
std::unique_ptr<ConnectivityMonitor> connectivity_monitor) | ||
ConnectivityMonitor* connectivity_monitor) | ||
: worker_queue_{NOT_NULL(worker_queue)}, | ||
credentials_{std::move(credentials)}, | ||
rpc_executor_{CreateExecutor()}, | ||
connectivity_monitor_{std::move(connectivity_monitor)}, |
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.
Nit: this move is now extraneous (moving a built-in, such as a pointer, is the same as copying it).
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.
Fixed
@@ -59,13 +59,15 @@ using util::Status; | |||
constexpr int kMaxPendingWrites = 10; | |||
|
|||
RemoteStore::RemoteStore( | |||
LocalStore* local_store, | |||
local::LocalStore* local_store, |
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.
Nit: qualifying LocalStore
with its namespace shouldn't be necessary given the using
directive above.
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.
Fixed
if (CanUseNetwork()) { | ||
LOG_DEBUG("RemoteStore %s restarting streams as connectivity changed", | ||
this); | ||
RestartNetwork(); |
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.
This doesn't create any undesirable interactions with the existing logic on connectivity change, right? (I don't think it should, just checking)
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.
The existing logic invalidates the GRPC channel, which speeds up reconnects already and is the foundation this PR is based on.
@@ -77,6 +79,15 @@ void RemoteStore::Start() { | |||
// For now, all setup is handled by `EnableNetwork`. We might expand on this | |||
// in the future. | |||
EnableNetwork(); | |||
|
|||
connectivity_monitor_->AddCallback( | |||
[this](ConnectivityMonitor::NetworkStatus /*ignored*/) { |
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.
Is it necessary/desirable to run this logic when the network status is "unavailable"?
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.
Probably not - but note that
grpc_channel_.reset(); |
DisableNetworkInternal(); | ||
online_state_tracker_.UpdateState(OnlineState::Unknown); | ||
EnableNetwork(); | ||
RestartNetwork(); |
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.
Looks like this PR could also make reconnection faster upon credentials' change? If correct, perhaps it's worth mentioning in the PR's description?
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.
Only if the credential change happened while offline, which is probably uncommon (since Auth needs a network connection as well).
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 addressed the easy comments.
I don't know how to unit test this - let's talk about this on Monday. This code affects the RemoteStore, so we should test it there. The only tests for the RemoteStore, however, are the Spec tests, which right now don't handle connectivity. I think writing a unit test would entail porting this PR to Web and then adding the credential change listener to the Spec tests suite. That's something we can do, but maybe we can come up with an easier and more direct way to test.
In the meantime, I will verify via test app that my recent change to ignore Unavailable
didn't affect the functionality.
Firestore/CHANGELOG.md
Outdated
@@ -1,3 +1,8 @@ | |||
# Unreleased | |||
- [fixed] Removed a delay that may have prevented Firestore from immediately | |||
establishing a network connections if a connectivity change occurred while |
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.
Fixed
Datastore::Datastore(const DatabaseInfo& database_info, | ||
const std::shared_ptr<AsyncQueue>& worker_queue, | ||
std::shared_ptr<CredentialsProvider> credentials, | ||
std::unique_ptr<ConnectivityMonitor> connectivity_monitor) | ||
ConnectivityMonitor* connectivity_monitor) | ||
: worker_queue_{NOT_NULL(worker_queue)}, | ||
credentials_{std::move(credentials)}, | ||
rpc_executor_{CreateExecutor()}, | ||
connectivity_monitor_{std::move(connectivity_monitor)}, |
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.
Fixed
@@ -59,13 +59,15 @@ using util::Status; | |||
constexpr int kMaxPendingWrites = 10; | |||
|
|||
RemoteStore::RemoteStore( | |||
LocalStore* local_store, | |||
local::LocalStore* local_store, |
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.
Fixed
@@ -77,6 +79,15 @@ void RemoteStore::Start() { | |||
// For now, all setup is handled by `EnableNetwork`. We might expand on this | |||
// in the future. | |||
EnableNetwork(); | |||
|
|||
connectivity_monitor_->AddCallback( | |||
[this](ConnectivityMonitor::NetworkStatus /*ignored*/) { |
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.
Probably not - but note that
grpc_channel_.reset(); |
if (CanUseNetwork()) { | ||
LOG_DEBUG("RemoteStore %s restarting streams as connectivity changed", | ||
this); | ||
RestartNetwork(); |
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.
The existing logic invalidates the GRPC channel, which speeds up reconnects already and is the foundation this PR is based on.
DisableNetworkInternal(); | ||
online_state_tracker_.UpdateState(OnlineState::Unknown); | ||
EnableNetwork(); | ||
RestartNetwork(); |
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.
Only if the credential change happened while offline, which is probably uncommon (since Auth needs a network connection as well).
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 agree that testing this is a hard problem, so I don't want to block this PR on that (it can be done in a follow-up, and for now doing manual testing seems sufficient).
Verified manually. |
This is a follow up to #4985 and addresses an additional problem that I saw in the test app. If the SDK was already in the background and we were in a backoff phase, the SDK waited for the backoff to finish before reconnecting, which could take up to a minute. This PR plumbs the connectivity handler through to RemoteStore and resets the backoff when a connectivity change occurred.
cc @wu-hui
Fixes #5783