Skip to content

Commit

Permalink
Merge branch 'master' of github.com:realm/realm-core into feature/rol…
Browse files Browse the repository at this point in the history
…e-change
  • Loading branch information
Michael Wilkerson-Barker committed Jul 2, 2024
2 parents 562cf09 + 7c31f5d commit 83d4e57
Show file tree
Hide file tree
Showing 19 changed files with 493 additions and 370 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

### Enhancements
* <New feature description> (PR [#????](https://github.com/realm/realm-core/pull/????))
* None.
* "Next launch" metadata file actions are now performed in a multi-process safe manner ([#7576](https://github.com/realm/realm-core/pull/7576)).

### Fixed
* <How do the end-user experience this issue? what was the impact?> ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?)
* Fixed a change of mode from Strong to All when removing links from an embedded object that links to a tombstone. This affects sync apps that use embedded objects which have a `Lst<Mixed>` that contains a link to another top level object which has been deleted by another sync client (creating a tombstone locally). In this particular case, the switch would cause any remaining link removals to recursively delete the destination object if there were no other links to it. ([#7828](https://github.com/realm/realm-core/issues/7828), since 14.0.0-beta.0)
* Fixed removing backlinks from the wrong objects if the link came from a nested list, nested dictionary, top-level dictionary, or list of mixed, and the source table had more than 256 objects. This could manifest as `array_backlink.cpp:112: Assertion failed: int64_t(value >> 1) == key.value` when removing an object. ([#7594](https://github.com/realm/realm-core/issues/7594), since v11 for dictionaries)
* Fixed the collapse/rejoin of clusters which contained nested collections with links. This could manifest as `array.cpp:319: Array::move() Assertion failed: begin <= end [2, 1]` when removing an object. ([#7839](https://github.com/realm/realm-core/issues/7839), since the introduction of nested collections in v14.0.0-beta.0)
* wait_for_upload_completion() was inconsistent in how it handled commits which did not produce any changesets to upload. Previously it would sometimes complete immediately if all commits waiting to be uploaded were empty, and at other times it would wait for a server roundtrip. It will now always complete immediately. ([PR #7796](https://github.com/realm/realm-core/pull/7796)).
* `realm_sync_session_handle_error_for_testing` parameter `is_fatal` was flipped changing the expected behavior. (#[7750](https://github.com/realm/realm-core/issues/7750)).

### Breaking changes
* None.
Expand Down
15 changes: 11 additions & 4 deletions src/realm/db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2860,20 +2860,27 @@ DBRef DB::create(BinaryData buffer, bool take_ownership) NO_THREAD_SAFETY_ANALYS
return retval;
}

void DB::claim_sync_agent()
bool DB::try_claim_sync_agent()
{
REALM_ASSERT(is_attached());
std::unique_lock<InterprocessMutex> lock(m_controlmutex);
std::lock_guard lock(m_controlmutex);
if (m_info->sync_agent_present)
throw MultipleSyncAgents{};
return false;
m_info->sync_agent_present = 1; // Set to true
m_is_sync_agent = true;
return true;
}

void DB::claim_sync_agent()
{
if (!try_claim_sync_agent())
throw MultipleSyncAgents{};
}

void DB::release_sync_agent()
{
REALM_ASSERT(is_attached());
std::unique_lock<InterprocessMutex> lock(m_controlmutex);
std::lock_guard lock(m_controlmutex);
if (!m_is_sync_agent)
return;
REALM_ASSERT(m_info->sync_agent_present);
Expand Down
1 change: 1 addition & 0 deletions src/realm/db.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ class DB : public std::enable_shared_from_this<DB> {
/// Mark this DB as the sync agent for the file.
/// \throw MultipleSyncAgents if another DB is already the sync agent.
void claim_sync_agent();
bool try_claim_sync_agent();
void release_sync_agent();

/// Returns true if there are threads waiting to acquire the write lock, false otherwise.
Expand Down
2 changes: 1 addition & 1 deletion src/realm/object-store/c_api/sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ RLM_API void realm_sync_session_handle_error_for_testing(const realm_sync_sessio
REALM_ASSERT(session);
SyncSession::OnlyForTesting::handle_error(
*session->get(),
sync::SessionErrorInfo{Status{static_cast<ErrorCodes::Error>(error_code), error_str}, !is_fatal});
sync::SessionErrorInfo{Status{static_cast<ErrorCodes::Error>(error_code), error_str}, is_fatal});
}

} // namespace realm::c_api
5 changes: 5 additions & 0 deletions src/realm/object-store/impl/realm_coordinator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ class RealmCoordinator : public std::enable_shared_from_this<RealmCoordinator>,
return m_audit_context.get();
}

bool try_claim_sync_agent()
{
return m_db->try_claim_sync_agent();
}

private:
friend Realm::Internal;
Realm::Config m_config;
Expand Down
31 changes: 14 additions & 17 deletions src/realm/object-store/sync/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,12 +715,11 @@ void App::get_profile(const std::shared_ptr<User>& user,
identities.push_back({get<std::string>(doc, "id"), get<std::string>(doc, "provider_type")});
}

if (auto data = m_metadata_store->get_user(user->user_id())) {
data->identities = std::move(identities);
data->profile = UserProfile(get<BsonDocument>(profile_json, "data"));
m_metadata_store->update_user(user->user_id(), *data);
user->update_backing_data(std::move(data));
}
m_metadata_store->update_user(user->user_id(), [&](auto& data) {
data.identities = std::move(identities);
data.profile = UserProfile(get<BsonDocument>(profile_json, "data"));
user->update_backing_data(data); // FIXME
});
}
catch (const AppError& err) {
return completion(nullptr, err);
Expand Down Expand Up @@ -812,12 +811,11 @@ void App::log_in_with_credentials(const AppCredentials& credentials, const std::
try {
auto json = parse<BsonDocument>(response.body);
if (linking_user) {
if (auto user_data = m_metadata_store->get_user(linking_user->user_id())) {
user_data->access_token = RealmJWT(get<std::string>(json, "access_token"));
// maybe a callback for this?
m_metadata_store->update_user(linking_user->user_id(), *user_data);
linking_user->update_backing_data(std::move(user_data));
}
m_metadata_store->update_user(linking_user->user_id(), [&](auto& data) {
data.access_token = RealmJWT(get<std::string>(json, "access_token"));
// FIXME: should be powered by callback
linking_user->update_backing_data(data);
});
}
else {
auto user_id = get<std::string>(json, "user_id");
Expand Down Expand Up @@ -1338,11 +1336,10 @@ void App::refresh_access_token(const std::shared_ptr<User>& user, bool update_lo
try {
auto json = parse<BsonDocument>(response.body);
RealmJWT access_token{get<std::string>(json, "access_token")};
if (auto data = self->m_metadata_store->get_user(user->user_id())) {
data->access_token = access_token;
self->m_metadata_store->update_user(user->user_id(), *data);
user->update_backing_data(std::move(data));
}
self->m_metadata_store->update_user(user->user_id(), [&](auto& data) {
data.access_token = access_token;
user->update_backing_data(data);
});
}
catch (AppError& err) {
return completion(std::move(err));
Expand Down
3 changes: 2 additions & 1 deletion src/realm/object-store/sync/async_open_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <realm/object-store/impl/realm_coordinator.hpp>
#include <realm/object-store/sync/sync_session.hpp>
#include <realm/object-store/thread_safe_reference.hpp>
#include <realm/object-store/util/scheduler.hpp>

namespace realm {

Expand Down Expand Up @@ -126,7 +127,7 @@ void AsyncOpenTask::wait_for_bootstrap_or_complete(AsyncOpenCallback&& callback,

SharedRealm shared_realm;
try {
shared_realm = coordinator->get_realm(nullptr, m_db_first_open);
shared_realm = coordinator->get_realm(util::Scheduler::make_dummy(), m_db_first_open);
}
catch (...) {
async_open_complete(std::move(callback), coordinator, exception_to_status());
Expand Down
Loading

0 comments on commit 83d4e57

Please sign in to comment.