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

RCORE-2092 Simplify the SessionWrapper lifecycle a bit #7609

Merged
merged 5 commits into from
May 29, 2024

Conversation

tgoyne
Copy link
Member

@tgoyne tgoyne commented Apr 19, 2024

Some preparatory refactoring before adding a bunch of complexity around handling not being able to acquire the sync agent.

Initializing a sync::Session was a multi-step process of creating the Session with a config, configuring some additional things via mutation functions, and then calling bind(). Over time we've gradually reduced how many things were set via mutation functions or parameters to bind(), and now there was only two left. Both of them can easily be pushed to the Config struct, so the explicit bind() step is no longer needed and SessionWrapper can initialize immediately, eliminating one of the states that it can be in and letting us make more of the members const.

@tgoyne tgoyne self-assigned this Apr 19, 2024
@cla-bot cla-bot bot added the cla: yes label Apr 19, 2024
Comment on lines -69 to -71
// IMPORTANT: If a function is supplied that handles the exception, it must
// call abort() or cause the application to crash since the SyncClient will
// be in a bad state if this occurs and will not be able to shut down properly.
Copy link
Member Author

Choose a reason for hiding this comment

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

This comment was once true but was very out of date.

@@ -44,47 +29,35 @@ using ProxyConfig = SyncConfig::ProxyConfig;

// Life cycle states of a session wrapper:
//
// - Uninitiated
Copy link
Member Author

Choose a reason for hiding this comment

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

This comment was significantly out of date and not all the changes in the rewritten version are specifically related to this PR.

// session wrapper (initiate()) will always find that `m_actualized` is
// true. This is the case, because the scheduling of such a post handler
// will have been preceded by the triggering of
// `ClientImpl::m_actualize_and_finalize` (in
Copy link
Member Author

Choose a reason for hiding this comment

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

The specific details of where in ClientImpl these things happen had gotten stale and I didn't think it was worth trying to describe here.

try {
for (auto& p : m_server_slots) {
ServerSlot& slot = p.second;
if (m_one_connection_per_session) {
REALM_ASSERT(!slot.connection);
for (const auto& p : slot.alt_connections) {
ClientImpl::Connection& conn = *p.second;
if (conn.get_state() == ConnectionState::disconnected) {
Copy link
Member Author

Choose a reason for hiding this comment

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

I pushed this check into voluntary_disconnect().

Comment on lines -463 to -467
post([this](Status status) mutable {
if (status == ErrorCodes::OperationAborted)
return;
else if (!status.is_ok())
throw Exception(status);
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 checks appeared a lot, so I added a helper function rather than repeat them every time.


/// The reason this synchronization session is used for.
/// Set a handler to monitor the state of download and upload progress.
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 docs are stale (they should have been updated in the flx progress project) and I just moved them unchanged.

state_wait_for(lock, State::Stopped);
m_thread.join();
Copy link
Member Author

Choose a reason for hiding this comment

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

Restarting a socket provider didn't work due to missing join() here, as it's required to reassign a std::thread even if the old thread happens to have exited.

m_thread = std::thread{&DefaultSocketProvider::event_loop, this};
// Wait for the thread to start before continuing
state_wait_for(lock, State::Running);
}

void DefaultSocketProvider::OnlyForTesting::run_event_loop_on_current_thread(DefaultSocketProvider* provider)
Copy link
Member Author

Choose a reason for hiding this comment

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

This is now done via an observer instead.

@@ -2009,21 +2011,10 @@ class Service::PostOper : public PostOperBase {
// Recycle the operation object before the handler is exceuted, such
// that the memory is available for a new post operation that might be
// initiated during the execution of the handler.
bool was_recycled = false;
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 error handling was just for the possibility of a handler that isn't nothrow moveable, which it turns out we don't need.

@@ -328,25 +324,22 @@ class ClientImpl {
// approach would be to allow for per-endpoint SSL parameters to be
// specifiable through public member functions of ClientImpl from where they
// could then be picked up as new connections are created on demand.
//
// FIXME: `session_multiplex_ident` should be eliminated from ServerEndpoint
Copy link
Member Author

Choose a reason for hiding this comment

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

This isn't completely not an issue with user_id in ServerEndpoint, but it'd require very strange circumstances.

Copy link
Contributor

Choose a reason for hiding this comment

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

i'm not even sure what this meant.

Copy link
Member Author

Choose a reason for hiding this comment

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

If we set one_connection_per_session = false and then assigned each session a unique session_multiplex_ident we'd end up with a separate connection per session but tracked somewhat differently from when one_connection_per_session = true (one ServerSlot per connection rather than multiple connections in one ServerSlot), and this resulted in reconnect delays behaving differently..

@tgoyne tgoyne changed the title Simplify the SessionWrapper lifecycle a bit RCORE-2092 Simplify the SessionWrapper lifecycle a bit Apr 19, 2024
Copy link

coveralls-official bot commented Apr 19, 2024

Pull Request Test Coverage Report for Build thomas.goyne_376

Details

  • 506 of 544 (93.01%) changed or added relevant lines in 14 files are covered.
  • 46 unchanged lines in 13 files lost coverage.
  • Overall coverage increased (+0.03%) to 90.832%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/realm/object-store/sync/sync_session.cpp 28 29 96.55%
src/realm/sync/binding_callback_thread_observer.hpp 2 4 50.0%
src/realm/sync/network/default_socket.cpp 20 22 90.91%
src/realm/sync/noinst/client_impl_base.cpp 30 32 93.75%
src/realm/sync/noinst/client_impl_base.hpp 1 3 33.33%
test/test_sync.cpp 201 204 98.53%
test/test_util_scope_exit.cpp 40 44 90.91%
src/realm/sync/client.cpp 134 145 92.41%
test/sync_fixtures.hpp 7 18 38.89%
Files with Coverage Reduction New Missed Lines %
src/realm/array_string.cpp 1 87.23%
src/realm/sort_descriptor.cpp 1 94.06%
src/realm/sync/binding_callback_thread_observer.hpp 1 33.33%
src/realm/util/serializer.cpp 1 90.43%
test/sync_fixtures.hpp 1 75.56%
src/realm/sync/network/default_socket.cpp 2 72.2%
test/fuzz_group.cpp 2 48.33%
src/realm/sync/noinst/server/server.cpp 3 73.85%
src/realm/sync/noinst/client_reset.cpp 4 91.93%
src/realm/sync/client.cpp 5 91.39%
Totals Coverage Status
Change from base Build 2349: 0.03%
Covered Lines: 214438
Relevant Lines: 236081

💛 - Coveralls

@tgoyne tgoyne requested review from jbreams and michael-wb April 23, 2024 15:14
src/realm/sync/noinst/client_impl_base.hpp Outdated Show resolved Hide resolved
@@ -328,25 +324,22 @@ class ClientImpl {
// approach would be to allow for per-endpoint SSL parameters to be
// specifiable through public member functions of ClientImpl from where they
// could then be picked up as new connections are created on demand.
//
// FIXME: `session_multiplex_ident` should be eliminated from ServerEndpoint
Copy link
Contributor

Choose a reason for hiding this comment

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

i'm not even sure what this meant.


drain_connections_on_loop();
}


void ClientImpl::register_unactualized_session_wrapper(SessionWrapper* wrapper, ServerEndpoint endpoint)
Copy link
Contributor

Choose a reason for hiding this comment

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

I actually had a branch I was working on in the past few days that did this same change as part of figuring out some base url stuff. 👍

@tgoyne tgoyne force-pushed the tg/session-lifecycle branch 2 times, most recently from d199a08 to db9a599 Compare April 30, 2024 19:22
tgoyne added 4 commits May 29, 2024 11:26
It was both virtual and stored callbacks, which was redundant. Subclasses can
store their own callbacks if desired (as the C API implementation already did).
@tgoyne tgoyne force-pushed the tg/session-lifecycle branch 2 times, most recently from 56919c2 to 3425497 Compare May 29, 2024 21:50
Initializing a sync::Session was a multi-step process of creating the Session
with a config, configuring some addition things via mutation functions, and
then calling bind(). We can simplify this a bit by pushing everything into the
config struct and binding inside the wrapper's constructor, eliminating the
constructed-but-not-initialized state and letting us make more of the members
const.
@tgoyne tgoyne force-pushed the tg/session-lifecycle branch from 3425497 to 8a68a7f Compare May 29, 2024 21:55
@tgoyne tgoyne merged commit 4a8f415 into master May 29, 2024
37 checks passed
@tgoyne tgoyne deleted the tg/session-lifecycle branch May 29, 2024 23:05
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 29, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants