Skip to content

RCORE-1872 Sync client should allow server bootstrapping at any time #7440

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

Merged
merged 71 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
d09e4a3
First round of changes for server-initiated bootstraps
Mar 27, 2024
ae2574e
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 3, 2024
43391ca
Added test for role change bootstraps
Apr 10, 2024
35b1483
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 10, 2024
3424431
Updated test for handle role bootstraps
Apr 11, 2024
e0d6ac1
Updated baas/baasaas to use branch with fixes
Apr 11, 2024
f3eb7e0
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 11, 2024
7356ba2
updated changelog
Apr 11, 2024
9e32480
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 12, 2024
4431985
Updated test to verify bootstrap actually occurred
Apr 12, 2024
b87bc65
Fixed tsan warning
Apr 12, 2024
8447461
Move instead of copy
Apr 12, 2024
75a1d13
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 15, 2024
44d8e12
Updates from review; added comments to clarify bootstrap detection logic
Apr 15, 2024
944fb30
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 19, 2024
a9807d3
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 26, 2024
c0b1a49
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 27, 2024
60cb61e
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 27, 2024
37acf98
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 30, 2024
8d9557d
Updates from review
Apr 30, 2024
400aeba
Reworked test to fix msvc failure
Apr 30, 2024
4924597
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Apr 30, 2024
5ea89e2
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
May 2, 2024
3ad02b6
Reverted baas branch to master and protocol version to 12
May 2, 2024
06bdc01
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
May 2, 2024
3198ebd
Added comments to changes needed when merging to master; update baas …
May 3, 2024
7902db0
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
May 10, 2024
fe86341
Merging in recommended changes
May 14, 2024
7a5269b
Pulled over changes from other branch and tweaking download params
May 16, 2024
0a26a71
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
May 16, 2024
c7a4739
Refactored tests to validate different bootstrap types
May 17, 2024
2355dd9
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
May 17, 2024
509c97b
Address test failures
May 17, 2024
8a00447
Updated tests to get passing using the server params
May 20, 2024
b7b7180
Updated debug statements role change tests
May 21, 2024
484f526
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
May 21, 2024
f29542b
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
May 24, 2024
4f09342
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
May 28, 2024
3c193ec
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
May 30, 2024
4a4f13f
Updated to support new batch_state protocol changes; updated tests
Jun 3, 2024
a497259
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 3, 2024
8ecfe34
Updated role change tests and merged test from separate PR
Jun 4, 2024
f1d9425
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 4, 2024
e375bfd
Fixed issue with flx query verion 0 not being treated as a bootstrap
Jun 4, 2024
c4f0344
Cleaned up the tests a bit and reworked query version 0 handling
Jun 4, 2024
2aa76d9
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 4, 2024
39af9d6
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 4, 2024
165a651
Added TODO to query 0 bootstrap detection
Jun 4, 2024
a72e158
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 4, 2024
b850cac
Updates from review; updated batch_state for schema bootstraps
Jun 5, 2024
e2cd353
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 5, 2024
9c7b7af
Removed extra mutex in favor of state machine's mutex
Jun 5, 2024
2fcdbec
Increased timeout when waiting for app initial sync to complete
Jun 5, 2024
83d2a5c
Updated role change test to use test commands
Jun 6, 2024
5f2a7e1
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 6, 2024
51b54eb
Fixed lint warning
Jun 6, 2024
93386d4
Update resume and ident message handling
Jun 6, 2024
7e2c5a7
Updated future waits for the pause/resume test command
Jun 6, 2024
b2fcf51
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 6, 2024
239d162
Added session connected event for when session multiplexing is disabled
Jun 7, 2024
841f1d8
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 7, 2024
0f00b92
Updates from review; updated baas commit to include timing fix
Jun 7, 2024
1ffddd0
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 7, 2024
04624e9
Removed todo comment
Jun 7, 2024
84a4c23
Added wait_until() to state machine to wait for callback; updated rol…
Jun 7, 2024
3e97840
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 7, 2024
c4e6a9e
Updates from review
Jun 7, 2024
3649284
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 7, 2024
aede51b
Updated changelog after release
Jun 7, 2024
0d55022
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 10, 2024
a40bafc
Merge branch 'feature/role-change' of github.com:realm/realm-core int…
Jun 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
### Enhancements
* <New feature description> (PR [#????](https://github.com/realm/realm-core/pull/????))
* Performance has been improved for range queries on integers and timestamps. Requires that you use the "BETWEEN" operation in MQL or the Query::between() method when you build the query. (PR [#7785](https://github.com/realm/realm-core/pull/7785))
* None.
* Add support for server initiated bootstraps. ([PR #7440](https://github.com/realm/realm-core/pull/7440))

### Fixed
* <How do the end-user experience this issue? what was the impact?> ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?)
Expand All @@ -19,7 +19,7 @@
-----------

### Internals
* None.
* Protocol version has been updated to v14 to support server intiated bootstraps and role change updates without a client reset. ([PR #7440](https://github.com/realm/realm-core/pull/7440))

----------------------------------------------

Expand Down
5 changes: 3 additions & 2 deletions dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ VERSION: 14.10.0
OPENSSL_VERSION: 3.2.0
ZLIB_VERSION: 1.2.13
# https://github.com/10gen/baas/commits
# 9d1b4d6 is 2024 May 8
BAAS_VERSION: 9d1b4d628babadfb606ebcadb93b1e5cae3c9565
# 30c10fd is 2024 June 6
BAAS_VERSION: 30c10fd8e9400fc77e594340422d8b75c210e18d
BAAS_VERSION_TYPE: githash
3 changes: 2 additions & 1 deletion evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,9 @@ functions:
shell: bash
env:
BAASAAS_API_KEY: "${baasaas_api_key}"
# BAAS_VERSION and VERSION_TYPE are set by realm-core/dependencies.yml
BAASAAS_REF_SPEC: "${BAAS_VERSION}"
BAASAAS_START_MODE: "githash"
BAASAAS_START_MODE: "${BAAS_VERSION_TYPE|githash}"
script: |-
set -o errexit
set -o verbose
Expand Down
4 changes: 3 additions & 1 deletion src/realm/object-store/sync/sync_session.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
#include <realm/util/future.hpp>
#include <realm/version_id.hpp>

#include <map>
#include <mutex>
#include <unordered_map>
#include <map>

namespace realm {
class DB;
Expand Down Expand Up @@ -345,6 +345,8 @@ class SyncSession : public std::enable_shared_from_this<SyncSession> {
return session.get_appservices_connection_id();
}

// Supported commands can be found in `handleTestCommandMessage()`
// in baas/devicesync/server/qbs_client_handler_functions.go
static util::Future<std::string> send_test_command(SyncSession& session, std::string request)
{
return session.send_test_command(std::move(request));
Expand Down
41 changes: 6 additions & 35 deletions src/realm/sync/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -803,12 +803,8 @@ void SessionImpl::update_subscription_version_info()
bool SessionImpl::process_flx_bootstrap_message(const SyncProgress& progress, DownloadBatchState batch_state,
int64_t query_version, const ReceivedChangesets& received_changesets)
{
// Ignore the call if the session is not active
if (m_state != State::Active) {
return false;
}

if (is_steady_state_download_message(batch_state, query_version)) {
// Ignore the message if the session is not active or a steady state message
if (m_state != State::Active || batch_state == DownloadBatchState::SteadyState) {
return false;
}

Expand Down Expand Up @@ -904,7 +900,7 @@ void SessionImpl::process_pending_flx_bootstrap()
auto pending_batch = bootstrap_store->peek_pending(m_wrapper.m_flx_bootstrap_batch_size_bytes);
if (!pending_batch.progress) {
logger.info("Incomplete pending bootstrap found for query version %1", pending_batch.query_version);
// Close the write transation before clearing the bootstrap store to avoid a deadlock because the
// Close the write transaction before clearing the bootstrap store to avoid a deadlock because the
// bootstrap store requires a write transaction itself.
transact->close();
bootstrap_store->clear();
Expand Down Expand Up @@ -1047,7 +1043,7 @@ SyncClientHookAction SessionImpl::call_debug_hook(SyncClientHookEvent event, con
return call_debug_hook(data);
}

SyncClientHookAction SessionImpl::call_debug_hook(SyncClientHookEvent event, const ProtocolErrorInfo& error_info)
SyncClientHookAction SessionImpl::call_debug_hook(SyncClientHookEvent event, const ProtocolErrorInfo* error_info)
{
if (REALM_LIKELY(!m_wrapper.m_debug_hook)) {
return SyncClientHookAction::NoAction;
Expand All @@ -1061,37 +1057,12 @@ SyncClientHookAction SessionImpl::call_debug_hook(SyncClientHookEvent event, con
data.batch_state = DownloadBatchState::SteadyState;
data.progress = m_progress;
data.num_changesets = 0;
data.query_version = 0;
data.error_info = &error_info;
data.query_version = m_last_sent_flx_query_version;
data.error_info = error_info;

return call_debug_hook(data);
}

SyncClientHookAction SessionImpl::call_debug_hook(SyncClientHookEvent event)
{
return call_debug_hook(event, m_progress, m_last_sent_flx_query_version, DownloadBatchState::SteadyState, 0);
}

bool SessionImpl::is_steady_state_download_message(DownloadBatchState batch_state, int64_t query_version)
{
// Should never be called if session is not active
REALM_ASSERT_EX(m_state == State::Active, m_state);
if (batch_state == DownloadBatchState::SteadyState) {
return true;
}

if (!m_is_flx_sync_session) {
return true;
}

// If this is a steady state DOWNLOAD, no need for special handling.
if (batch_state == DownloadBatchState::LastInBatch && query_version == m_wrapper.m_flx_active_version) {
return true;
}

return false;
}

void SessionImpl::init_progress_handler()
{
if (m_state != State::Unactivated && m_state != State::Active)
Expand Down
3 changes: 3 additions & 0 deletions src/realm/sync/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ enum class SyncClientHookEvent {
ErrorMessageReceived,
SessionActivating,
SessionSuspended,
SessionConnected,
SessionResumed,
BindMessageSent,
IdentMessageSent,
ClientResetMergeComplete,
BootstrapBatchAboutToProcess,
};
Expand Down
39 changes: 18 additions & 21 deletions src/realm/sync/noinst/client_impl_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1824,12 +1824,7 @@ void Session::send_message()
if (!m_bind_message_sent)
return send_bind_message(); // Throws

if (!m_ident_message_sent) {
if (have_client_file_ident())
send_ident_message(); // Throws
return;
}

// Pending test commands can be sent any time after the BIND message is sent
const auto has_pending_test_command = std::any_of(m_pending_test_commands.begin(), m_pending_test_commands.end(),
[](const PendingTestCommand& command) {
return command.pending;
Expand All @@ -1838,6 +1833,12 @@ void Session::send_message()
return send_test_command_message();
}

if (!m_ident_message_sent) {
if (have_client_file_ident())
send_ident_message(); // Throws
return;
}

if (m_error_to_send)
return send_json_error_message(); // Throws

Expand Down Expand Up @@ -1908,7 +1909,6 @@ void Session::send_bind_message()
bool need_client_file_ident = !have_client_file_ident();
const bool is_subserver = false;


ClientProtocol& protocol = m_conn.get_client_protocol();
int protocol_version = m_conn.get_negotiated_protocol_version();
OutputBuffer& out = m_conn.get_output_buffer();
Expand Down Expand Up @@ -1992,6 +1992,7 @@ void Session::send_ident_message()
m_conn.initiate_write_message(out, this); // Throws

m_ident_message_sent = true;
call_debug_hook(SyncClientHookEvent::IdentMessageSent);

// Other messages may be waiting to be sent
enlist_to_send(); // Throws
Expand Down Expand Up @@ -2392,22 +2393,17 @@ Status Session::receive_download_message(const DownloadMessage& message)
if (!is_flx || query_version > 0)
enable_progress_notifications();

// If this is a PBS connection, then every download message is its own complete batch.
bool last_in_batch = is_flx ? *message.last_in_batch : true;
auto batch_state = last_in_batch ? sync::DownloadBatchState::LastInBatch : sync::DownloadBatchState::MoreToCome;
if (is_steady_state_download_message(batch_state, query_version))
batch_state = DownloadBatchState::SteadyState;

auto&& progress = message.progress;
if (is_flx) {
logger.debug("Received: DOWNLOAD(download_server_version=%1, download_client_version=%2, "
"latest_server_version=%3, latest_server_version_salt=%4, "
"upload_client_version=%5, upload_server_version=%6, progress_estimate=%7, "
"last_in_batch=%8, query_version=%9, num_changesets=%10, ...)",
"batch_state=%8, query_version=%9, num_changesets=%10, ...)",
progress.download.server_version, progress.download.last_integrated_client_version,
progress.latest_server_version.version, progress.latest_server_version.salt,
progress.upload.client_version, progress.upload.last_integrated_server_version,
message.progress_estimate, last_in_batch, query_version, message.changesets.size()); // Throws
message.progress_estimate, message.batch_state, query_version,
message.changesets.size()); // Throws
}
else {
logger.debug("Received: DOWNLOAD(download_server_version=%1, download_client_version=%2, "
Expand Down Expand Up @@ -2451,6 +2447,7 @@ Status Session::receive_download_message(const DownloadMessage& message)
changeset.remote_version, server_version, progress.download.server_version)};
}
server_version = changeset.remote_version;

// Check that per-changeset last integrated client version is "weakly"
// increasing.
bool good_client_version =
Expand All @@ -2476,7 +2473,7 @@ Status Session::receive_download_message(const DownloadMessage& message)
}

auto hook_action = call_debug_hook(SyncClientHookEvent::DownloadMessageReceived, progress, query_version,
batch_state, message.changesets.size());
message.batch_state, message.changesets.size());
if (hook_action == SyncClientHookAction::EarlyReturn) {
return Status::OK();
}
Expand All @@ -2485,16 +2482,16 @@ Status Session::receive_download_message(const DownloadMessage& message)
if (is_flx)
update_download_estimate(message.progress_estimate);

if (process_flx_bootstrap_message(progress, batch_state, query_version, message.changesets)) {
if (process_flx_bootstrap_message(progress, message.batch_state, query_version, message.changesets)) {
clear_resumption_delay_state();
return Status::OK();
}

uint64_t downloadable_bytes = is_flx ? 0 : message.downloadable_bytes;
initiate_integrate_changesets(downloadable_bytes, batch_state, progress, message.changesets); // Throws
initiate_integrate_changesets(downloadable_bytes, message.batch_state, progress, message.changesets); // Throws

hook_action = call_debug_hook(SyncClientHookEvent::DownloadMessageIntegrated, progress, query_version,
batch_state, message.changesets.size());
message.batch_state, message.changesets.size());
if (hook_action == SyncClientHookAction::EarlyReturn) {
return Status::OK();
}
Expand Down Expand Up @@ -2604,7 +2601,7 @@ Status Session::receive_error_message(const ProtocolErrorInfo& info)
// Can't process debug hook actions once the Session is undergoing deactivation, since
// the SessionWrapper may not be available
if (m_state == Active) {
auto debug_action = call_debug_hook(SyncClientHookEvent::ErrorMessageReceived, info);
auto debug_action = call_debug_hook(SyncClientHookEvent::ErrorMessageReceived, &info);
if (debug_action == SyncClientHookAction::EarlyReturn) {
return Status::OK();
}
Expand Down Expand Up @@ -2664,7 +2661,7 @@ void Session::suspend(const SessionErrorInfo& info)
// Notify the application of the suspension of the session if the session is
// still in the Active state
if (m_state == Active) {
call_debug_hook(SyncClientHookEvent::SessionSuspended, info);
call_debug_hook(SyncClientHookEvent::SessionSuspended, &info);
m_conn.one_less_active_unsuspended_session(); // Throws
on_suspended(info); // Throws
}
Expand Down
15 changes: 10 additions & 5 deletions src/realm/sync/noinst/client_impl_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ class ClientImpl::Session {
/// To be used in connection with implementations of
/// initiate_integrate_changesets().
void integrate_changesets(const SyncProgress&, std::uint_fast64_t downloadable_bytes, const ReceivedChangesets&,
VersionInfo&, DownloadBatchState last_in_batch);
VersionInfo&, DownloadBatchState batch_state);

/// To be used in connection with implementations of
/// initiate_integrate_changesets().
Expand Down Expand Up @@ -1179,11 +1179,8 @@ class ClientImpl::Session {

SyncClientHookAction call_debug_hook(SyncClientHookEvent event, const SyncProgress&, int64_t, DownloadBatchState,
size_t);
SyncClientHookAction call_debug_hook(SyncClientHookEvent event, const ProtocolErrorInfo&);
SyncClientHookAction call_debug_hook(SyncClientHookEvent event, const ProtocolErrorInfo* = nullptr);
SyncClientHookAction call_debug_hook(const SyncClientHookData& data);
SyncClientHookAction call_debug_hook(SyncClientHookEvent event);

bool is_steady_state_download_message(DownloadBatchState batch_state, int64_t query_version);

void init_progress_handler();
void enable_progress_notifications();
Expand Down Expand Up @@ -1470,6 +1467,10 @@ inline void ClientImpl::Session::connection_established(bool fast_reconnect)
++m_target_download_mark;
}

// Notify the debug hook of the SessionConnected event before sending
// the bind messsage
call_debug_hook(SyncClientHookEvent::SessionConnected);

if (!m_suspended) {
// Ready to send BIND message
enlist_to_send(); // Throws
Expand Down Expand Up @@ -1540,6 +1541,10 @@ inline void ClientImpl::Session::initiate_rebind()

reset_protocol_state();

// Notify the debug hook of the SessionResumed event before sending
// the bind messsage
call_debug_hook(SyncClientHookEvent::SessionResumed);

// Ready to send BIND message
enlist_to_send(); // Throws
}
Expand Down
14 changes: 9 additions & 5 deletions src/realm/sync/noinst/pending_bootstrap_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ void PendingBootstrapStore::add_batch(int64_t query_version, util::Optional<Sync
BinaryData compressed_data(compressed_changesets[idx].data(), compressed_changesets[idx].size());
cur_changeset.set(m_changeset_data, compressed_data);
}
size_t total_changesets = changesets_list.size();

tr->commit();

Expand All @@ -183,15 +184,18 @@ void PendingBootstrapStore::add_batch(int64_t query_version, util::Optional<Sync
}

if (did_create) {
m_logger.debug(util::LogCategory::changeset, "Created new pending bootstrap object for query version %1",
query_version);
m_logger.debug(util::LogCategory::changeset,
"Created new pending bootstrap object with %1 changesets for query version %2",
total_changesets, query_version);
}
else {
m_logger.debug(util::LogCategory::changeset, "Added batch to pending bootstrap object for query version %1",
query_version);
m_logger.debug(util::LogCategory::changeset,
"Added batch of %1 changesets (%2 total) to pending bootstrap object for query version %3",
changesets.size(), total_changesets, query_version);
}
if (progress) {
m_logger.debug(util::LogCategory::changeset, "Finalized pending bootstrap object for query version %1",
m_logger.debug(util::LogCategory::changeset,
"Finalized pending bootstrap object with %1 changesets for query version %2", total_changesets,
query_version);
}
m_has_pending = true;
Expand Down
15 changes: 10 additions & 5 deletions src/realm/sync/noinst/protocol_codec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,8 @@ class ClientProtocol {

struct DownloadMessage {
SyncProgress progress;
std::optional<int64_t> query_version;
std::optional<bool> last_in_batch;
std::optional<int64_t> query_version; // FLX sync only
sync::DownloadBatchState batch_state = sync::DownloadBatchState::SteadyState;
union {
uint64_t downloadable_bytes = 0;
double progress_estimate;
Expand Down Expand Up @@ -439,10 +439,15 @@ class ClientProtocol {
if (is_flx) {
message.query_version = msg.read_next<int64_t>();
if (message.query_version < 0)
return report_error(ErrorCodes::SyncProtocolInvariantFailed, "Bad query version",
return report_error(ErrorCodes::SyncProtocolInvariantFailed, "Bad query version: %1",
message.query_version);

message.last_in_batch = msg.read_next<bool>();
int batch_state = msg.read_next<int>();
if (batch_state != static_cast<int>(sync::DownloadBatchState::MoreToCome) &&
batch_state != static_cast<int>(sync::DownloadBatchState::LastInBatch) &&
batch_state != static_cast<int>(sync::DownloadBatchState::SteadyState)) {
return report_error(ErrorCodes::SyncProtocolInvariantFailed, "Bad batch state: %1", batch_state);
}
message.batch_state = static_cast<sync::DownloadBatchState>(batch_state);

message.progress_estimate = msg.read_next<double>();
if (message.progress_estimate < 0 || message.progress_estimate > 1)
Expand Down
Loading
Loading