Skip to content
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

Deliver appropriate subscription state change notifications in DiscardLocal client resets #7119

Merged
merged 3 commits into from
Nov 13, 2023

Conversation

tgoyne
Copy link
Member

@tgoyne tgoyne commented Nov 6, 2023

#7110 accidentally made it so that we no longer complete subscription state notifications in DiscardLocal client resets. I uncovered this while writing tests for a separate set of changes, so this includes some refactoring which those tests depend on.

No changelog entry since the bug hasn't been shipped.

@tgoyne tgoyne self-assigned this Nov 6, 2023
///
/// This function is guaranteed to not be called before activation, and also
/// not after initiation of deactivation.
ClientReplication& access_realm();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

access_realm() should have gone away in #4839, as it was part of the MRU cache that the sync client used to have. These days it was just confusing and weird (and claimed to do something quite different from what it did).

Comment on lines -128 to -129
// we don't mind leaving the fresh lock file around because trying to delete it
// here could cause a race if there are multiple resets ongoing
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this code breaks horribly in any scenario where deleting the lockfile would be a problem. The sync agent claiming on the parent realm is supposed to ensure only one process can be performing a client reset on the realm, and if that's violated very bad things happen, so we don't really need to account for that possiblity.

// If we've already been superceded by another version getting completed, then we should skip registering
// a notification because it may never fire.
if (mgr->m_min_outstanding_version > version()) {
return util::Future<State>::make_ready(State::Superseded);
}

// Begin by blocking process_notifications from starting to fill futures. No matter the outcome, we'll
// unblock process_notifications() at the end of this function via the guard we construct below.
mgr->m_outstanding_requests++;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that the goal of this semaphore was to allow multiple concurrent calls to get_state_change_notification() to be refreshing at the same time. That doesn't seem like a very important thing to optimize for, and waiting on a condition variable is much more expensive than waiting on a mutex.

return mut.commit();
}

TEST(ClientReset_DiscardLocal_DiscardsPendingSubscriptions)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two tests are the ones which were failing without the change to set_active_as_latest().

Copy link

coveralls-official bot commented Nov 6, 2023

Pull Request Test Coverage Report for Build github_pull_request_283788

  • 516 of 522 (98.85%) changed or added relevant lines in 12 files are covered.
  • 93 unchanged lines in 12 files lost coverage.
  • Overall coverage increased (+0.007%) to 91.671%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/realm/sync/subscriptions.cpp 43 44 97.73%
src/realm/sync/noinst/client_impl_base.cpp 70 72 97.22%
test/util/test_path.hpp 3 6 50.0%
Files with Coverage Reduction New Missed Lines %
src/realm/sync/subscriptions.cpp 1 94.34%
src/realm/array_string.cpp 2 88.0%
src/realm/object-store/shared_realm.cpp 2 93.74%
src/realm/query_expression.hpp 2 93.51%
src/realm/util/file.cpp 2 81.73%
src/realm/query_expression.cpp 3 87.01%
src/realm/sync/noinst/client_history_impl.hpp 3 93.62%
src/realm/sync/noinst/protocol_codec.hpp 3 76.72%
src/realm/util/assert.hpp 4 87.1%
src/realm/sync/noinst/client_impl_base.cpp 7 85.0%
Totals Coverage Status
Change from base Build 1819: 0.007%
Covered Lines: 231079
Relevant Lines: 252074

💛 - Coveralls

@tgoyne tgoyne requested a review from ironage November 7, 2023 03:49
m_logger.debug("ClientResetOperation::finalize, realm_path = %1, local_realm_exists = %2, mode = %3",
m_db->get_path(), local_realm_exists, m_mode);
auto latest_version = db.get_version_id_of_latest_snapshot();
bool local_realm_exists = latest_version.version > 1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this check be >=?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the old check was incorrect. The version number for a never-written-to file is 1 and the first write produces version 2.

{
util::CheckedLockGuard lk(mgr->m_pending_notifications_mutex);
splice_if(mgr->m_pending_notifications, to_finish, [&](auto& req) {
return (req.version == m_version &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should either use m_version or my_version everywhere.

@tgoyne tgoyne force-pushed the tg/client-reset-flx-notifications branch from 3abd6a7 to c933533 Compare November 10, 2023 15:47
@tgoyne tgoyne force-pushed the tg/client-reset-flx-notifications branch from c933533 to 9e5d133 Compare November 10, 2023 16:02
Copy link
Collaborator

@danieltabacaru danieltabacaru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@tgoyne tgoyne merged commit 662ae67 into master Nov 13, 2023
1 of 2 checks passed
@tgoyne tgoyne deleted the tg/client-reset-flx-notifications branch November 13, 2023 04:39
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 21, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants