Skip to content

Commit

Permalink
Merge branch 'master' into je/user-identity
Browse files Browse the repository at this point in the history
  • Loading branch information
jedelbo committed Jan 11, 2022
2 parents 8d4a209 + 2285d15 commit ec73d3b
Show file tree
Hide file tree
Showing 19 changed files with 492 additions and 300 deletions.
27 changes: 26 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,33 @@

### Enhancements
* <New feature description> (PR [#????](https://github.com/realm/realm-core/pull/????))
* None.

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

### Breaking changes
* None.

### Compatibility
* Fileformat: Generates files with format v22. Reads and automatically upgrade from fileformat v5.

-----------

### Internals
* None.

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

# 11.8.0 Release notes

### Enhancements
* Support arithmetric operations (+, -, *, /) in query parser. Operands can be properties and/or constants of numeric types (integer, float, double or Decimal128). You can now say something like "(age + 5) * 2 > child.age".
* Support for asynchronous transactions added. (PR [#5035](https://github.com/realm/realm-core/pull/5035))
* FLX sync now properly handles write_not_allowed client reset errors ([#5147](https://github.com/realm/realm-core/pull/5147))

### Fixed
* <How do the end-user experience this issue? what was the impact?> ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?)
* The release package was missing several headers (since v11.7.0).
* The sync client will now drain the receive queue when send fails with ECONNRESET - ensuring that any error message from the server gets received and processed. ([#5078](https://github.com/realm/realm-core/pull/5078))
* Schema validation was missing for embedded objects in sets, resulting in an unhelpful error being thrown if the user attempted to define one.
Expand All @@ -17,6 +39,7 @@
* FLX sync QUERY messages are now ordered with UPLOAD messages ([#5135](https://github.com/realm/realm-core/pull/5135))
* Fixed race condition when waiting for state change notifications on FLX subscription sets that may have caused a hang ([#5146](https://github.com/realm/realm-core/pull/5146))
* UserIdentity metadata table grows indefinitely. ([#5152](https://github.com/realm/realm-core/issues/5152), since v10.0.0)
* SubscriptionSet::to_ext_json() now handles empty subscription sets correctly ([#5134](https://github.com/realm/realm-core/pull/5134))

### Breaking changes
* FLX SubscriptionSet type split into SubscriptionSet and MutableSubscriptionSet to add type safety ([#5092](https://github.com/realm/realm-core/pull/5092))
Expand All @@ -33,6 +56,8 @@
* Errors in C API no longer store or expose a std::exception_ptr. The comparison of realm_async_error_t now compares error code vs object identity. ([#5064](https://github.com/realm/realm-core/pull/5064))
* The JSON output is slightly changed in the event of link cycles. Nobody is expected to rely on that.
* Future::get_async() no longer requires its callback to be marked noexcept. ([#5130](https://github.com/realm/realm-core/pull/5130))
* SubscriptionSet no longer holds any database resources. ([#5150](https://github.com/realm/realm-core/pull/5150))
* ClientHistoryImpl::integrate_server_changesets now throws instead of returning a boolean to indicate success ([#5118](https://github.com/realm/realm-core/pull/5118))

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

Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import PackageDescription
import Foundation

let versionStr = "11.7.0"
let versionStr = "11.8.0"
let versionPieces = versionStr.split(separator: "-")
let versionCompontents = versionPieces[0].split(separator: ".")
let versionExtra = versionPieces.count > 1 ? versionPieces[1] : ""
Expand Down
2 changes: 1 addition & 1 deletion dependencies.list
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PACKAGE_NAME=realm-core
VERSION=11.7.0
VERSION=11.8.0
OPENSSL_VERSION=1.1.1g
MDBREALM_TEST_SERVER_TAG=2021-10-25
6 changes: 6 additions & 0 deletions src/realm/object-store/impl/realm_coordinator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ void RealmCoordinator::set_config(const Realm::Config& config)
if (config.sync_config->flx_sync_requested && !config.sync_config->partition_value.empty()) {
throw std::logic_error("Cannot specify a partition value when flexible sync is enabled");
}
// TODO(RCORE-912) we definitely do want to support this, but until its implemented we should prevent users
// from using something that is currently broken.
if (config.sync_config->flx_sync_requested &&
config.sync_config->client_resync_mode != ClientResyncMode::Manual) {
throw std::logic_error("Only manual client resets are supported with flexible sync");
}
}
#endif

Expand Down
24 changes: 10 additions & 14 deletions src/realm/sync/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,31 +672,27 @@ util::Optional<ClientReset>& SessionImpl::get_client_reset_config() noexcept
void SessionImpl::initiate_integrate_changesets(std::uint_fast64_t downloadable_bytes, DownloadBatchState batch_state,
const ReceivedChangesets& changesets)
{
bool simulate_integration_error = (m_wrapper.m_simulate_integration_error && !changesets.empty());
if (REALM_LIKELY(!simulate_integration_error)) {
bool success;
try {
bool simulate_integration_error = (m_wrapper.m_simulate_integration_error && !changesets.empty());
if (simulate_integration_error) {
throw IntegrationException(ClientError::bad_changeset, "simulated failure");
}
version_type client_version;
IntegrationError error = {};
if (REALM_LIKELY(!get_client().is_dry_run())) {
VersionInfo version_info;
ClientReplication& repl = access_realm(); // Throws
success = integrate_changesets(repl, m_progress, downloadable_bytes, changesets, version_info, error,
batch_state); // Throws
integrate_changesets(repl, m_progress, downloadable_bytes, changesets, version_info,
batch_state); // Throws
client_version = version_info.realm_version;
}
else {
// Fake it for "dry run" mode
success = true;
client_version = m_last_version_available + 1;
}
on_changesets_integrated(success, client_version, m_progress.download, error, batch_state); // Throws
on_changesets_integrated(client_version, m_progress.download, batch_state); // Throws
}
else {
bool success = false;
version_type client_version = 0; // Dummy
DownloadCursor download_progress = {0, 0}; // Dummy
IntegrationError error = IntegrationError::bad_changeset;
on_changesets_integrated(success, client_version, download_progress, error, batch_state); // Throws
catch (const IntegrationException& e) {
on_integration_failure(e, batch_state);
}
m_wrapper.on_sync_progress(); // Throws
}
Expand Down
1 change: 1 addition & 0 deletions src/realm/sync/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ SimplifiedProtocolError get_simplified_error(sync::ProtocolError err)
case ProtocolError::user_blacklisted:
case ProtocolError::object_already_exists:
case ProtocolError::server_permissions_changed:
case ProtocolError::write_not_allowed:
return SimplifiedProtocolError::ClientResetRequested;
}
return SimplifiedProtocolError::UnexpectedInternalIssue; // always return a value to appease MSVC.
Expand Down
52 changes: 30 additions & 22 deletions src/realm/sync/noinst/client_history_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,12 @@ void ClientHistory::find_uploadable_changesets(UploadCursor& upload_progress, ve
}


// Overriding member function in realm::sync::ClientHistoryBase
bool ClientHistory::integrate_server_changesets(const SyncProgress& progress,
void ClientHistory::integrate_server_changesets(const SyncProgress& progress,
const std::uint_fast64_t* downloadable_bytes,
const RemoteChangeset* incoming_changesets,
std::size_t num_changesets, VersionInfo& version_info,
IntegrationError& integration_error, DownloadBatchState batch_state,
util::Logger& logger, SyncTransactReporter* transact_reporter)
DownloadBatchState batch_state, util::Logger& logger,
SyncTransactReporter* transact_reporter)
{
REALM_ASSERT(num_changesets != 0);

Expand Down Expand Up @@ -369,14 +368,12 @@ bool ClientHistory::integrate_server_changesets(const SyncProgress& progress,
}
}
catch (BadChangesetError& e) {
logger.error("Failed to parse, or apply received changeset: %1", e.what()); // Throws
integration_error = IntegrationError::bad_changeset;
return false;
throw IntegrationException(ClientError::bad_changeset,
util::format("Failed to parse, or apply received changeset: %1", e.what()));
}
catch (TransformError& e) {
logger.error("Failed to transform received changeset: %1", e.what()); // Throws
integration_error = IntegrationError::bad_changeset;
return false;
throw IntegrationException(ClientError::bad_changeset,
util::format("Failed to transform received changeset: %1", e.what()));
}

// downloaded_bytes always contains the total number of downloaded bytes
Expand Down Expand Up @@ -425,7 +422,6 @@ bool ClientHistory::integrate_server_changesets(const SyncProgress& progress,

version_info.realm_version = new_version;
version_info.sync_version = {new_version, 0};
return true;
}


Expand Down Expand Up @@ -655,17 +651,29 @@ void ClientHistory::update_sync_progress(const SyncProgress& progress, const std
Array& root = m_arrays->root;

// Progress must never decrease
REALM_ASSERT(progress.latest_server_version.version >=
version_type(root.get_as_ref_or_tagged(s_progress_latest_server_version_iip).get_as_int()));
REALM_ASSERT(progress.download.server_version >=
version_type(root.get_as_ref_or_tagged(s_progress_download_server_version_iip).get_as_int()));
REALM_ASSERT(progress.download.last_integrated_client_version >=
version_type(root.get_as_ref_or_tagged(s_progress_download_client_version_iip).get_as_int()));
REALM_ASSERT(progress.upload.client_version >=
version_type(root.get_as_ref_or_tagged(s_progress_upload_client_version_iip).get_as_int()));
if (progress.upload.last_integrated_server_version > 0) {
REALM_ASSERT(progress.upload.last_integrated_server_version >=
version_type(root.get_as_ref_or_tagged(s_progress_upload_server_version_iip).get_as_int()));
if (progress.latest_server_version.version <
version_type(root.get_as_ref_or_tagged(s_progress_latest_server_version_iip).get_as_int())) {
throw IntegrationException(ClientError::bad_progress, "latest server version cannot decrease");
}
if (progress.download.server_version <
version_type(root.get_as_ref_or_tagged(s_progress_download_server_version_iip).get_as_int())) {
throw IntegrationException(ClientError::bad_progress, "server version of download cursor cannot decrease");
}
if (progress.download.last_integrated_client_version <
version_type(root.get_as_ref_or_tagged(s_progress_download_client_version_iip).get_as_int())) {
throw IntegrationException(ClientError::bad_progress,
"last integrated client version of download cursor cannot decrease");
}
if (progress.upload.client_version <
version_type(root.get_as_ref_or_tagged(s_progress_upload_client_version_iip).get_as_int())) {
throw IntegrationException(ClientError::bad_progress, "client version of upload cursor cannot decrease");
}
const auto last_integrated_server_version = progress.upload.last_integrated_server_version;
if (last_integrated_server_version > 0 &&
last_integrated_server_version <
version_type(root.get_as_ref_or_tagged(s_progress_upload_server_version_iip).get_as_int())) {
throw IntegrationException(ClientError::bad_progress,
"last integrated server version of upload cursor cannot decrease");
}

auto uploaded_bytes = std::uint_fast64_t(root.get_as_ref_or_tagged(s_progress_uploaded_bytes_iip).get_as_int());
Expand Down
30 changes: 22 additions & 8 deletions src/realm/sync/noinst/client_history_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
#define REALM_NOINST_CLIENT_HISTORY_IMPL_HPP

#include <realm/util/optional.hpp>
#include <realm/sync/client_base.hpp>
#include <realm/sync/history.hpp>
#include <realm/array_integer.hpp>

namespace realm {
namespace sync {
namespace realm::sync {

class ClientReplication;
// As new schema versions come into existence, describe them here.
Expand Down Expand Up @@ -48,6 +48,23 @@ constexpr int get_client_history_schema_version() noexcept
return 11;
}

class IntegrationException : public std::runtime_error {
public:
IntegrationException(ClientError code, const std::string& msg)
: std::runtime_error(msg)
, m_error(code)
{
}

ClientError code() const noexcept
{
return m_error;
}

private:
ClientError m_error;
};

class ClientHistory final : public _impl::History, public TransformHistory {
public:
using version_type = sync::version_type;
Expand All @@ -71,7 +88,6 @@ class ClientHistory final : public _impl::History, public TransformHistory {
~SyncTransactReporter() {}
};

enum class IntegrationError { bad_origin_file_ident, bad_changeset };

/// set_client_reset_adjustments() is used by client reset to adjust the
/// content of the history compartment. The shared group associated with
Expand Down Expand Up @@ -208,10 +224,9 @@ class ClientHistory final : public _impl::History, public TransformHistory {
/// \param transact_reporter An optional callback which will be called with the
/// version immediately processing the sync transaction and that of the sync
/// transaction.
bool integrate_server_changesets(const SyncProgress& progress, const std::uint_fast64_t* downloadable_bytes,
void integrate_server_changesets(const SyncProgress& progress, const std::uint_fast64_t* downloadable_bytes,
const RemoteChangeset* changesets, std::size_t num_changesets,
VersionInfo& new_version, IntegrationError& integration_error,
DownloadBatchState download_type, util::Logger&,
VersionInfo& new_version, DownloadBatchState download_type, util::Logger&,
SyncTransactReporter* transact_reporter = nullptr);

static void get_upload_download_bytes(DB*, std::uint_fast64_t&, std::uint_fast64_t&, std::uint_fast64_t&,
Expand Down Expand Up @@ -493,7 +508,6 @@ inline auto ClientHistory::get_transformer() -> Transformer&
/// realm::DB objects.
std::unique_ptr<ClientReplication> make_client_replication();

} // namespace sync
} // namespace realm
} // namespace realm::sync

#endif // REALM_NOINST_CLIENT_HISTORY_IMPL_HPP
Loading

0 comments on commit ec73d3b

Please sign in to comment.