config.hpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. #ifndef REALM_SYNC_CONFIG_HPP
  19. #define REALM_SYNC_CONFIG_HPP
  20. #include <realm/exceptions.hpp>
  21. #include <realm/db.hpp>
  22. #include <realm/util/assert.hpp>
  23. #include <realm/util/optional.hpp>
  24. #include <realm/sync/protocol.hpp>
  25. #include <functional>
  26. #include <memory>
  27. #include <string>
  28. #include <map>
  29. #include <unordered_map>
  30. namespace realm {
  31. class SyncUser;
  32. class SyncSession;
  33. class Realm;
  34. class ThreadSafeReference;
  35. namespace bson {
  36. class Bson;
  37. }
  38. namespace sync {
  39. using port_type = std::uint_fast16_t;
  40. enum class ProtocolError;
  41. } // namespace sync
  42. struct SyncError : public SystemError {
  43. enum class ClientResetModeAllowed { DoNotClientReset, RecoveryPermitted, RecoveryNotPermitted };
  44. bool is_fatal;
  45. // Just the minimal error message, without any log URL.
  46. std::string_view simple_message;
  47. // The URL to the associated server log if any. If not supplied by the server, this will be `empty()`.
  48. std::string_view logURL;
  49. /// A dictionary of extra user information associated with this error.
  50. /// If this is a client reset error, the keys for c_original_file_path_key and c_recovery_file_path_key will be
  51. /// populated with the relevant filesystem paths.
  52. std::unordered_map<std::string, std::string> user_info;
  53. /// The sync server may send down an error that the client does not recognize,
  54. /// whether because of a version mismatch or an oversight. It is still valuable
  55. /// to expose these errors so that users can do something about them.
  56. bool is_unrecognized_by_client = false;
  57. // the server may explicitly send down an action the client should take as part of an error (i.e, client reset)
  58. // if this is set, it overrides the clients interpretation of the error
  59. sync::ProtocolErrorInfo::Action server_requests_action = sync::ProtocolErrorInfo::Action::NoAction;
  60. // If this error resulted from a compensating write, this vector will contain information about each object
  61. // that caused a compensating write and why the write was illegal.
  62. std::vector<sync::CompensatingWriteErrorInfo> compensating_writes_info;
  63. SyncError(std::error_code error_code, std::string_view msg, bool is_fatal,
  64. std::optional<std::string_view> serverLog = std::nullopt,
  65. std::vector<sync::CompensatingWriteErrorInfo> compensating_writes = {});
  66. static constexpr const char c_original_file_path_key[] = "ORIGINAL_FILE_PATH";
  67. static constexpr const char c_recovery_file_path_key[] = "RECOVERY_FILE_PATH";
  68. /// The error is a client error, which applies to the client and all its sessions.
  69. bool is_client_error() const;
  70. /// The error is a protocol error, which may either be connection-level or session-level.
  71. bool is_connection_level_protocol_error() const;
  72. /// The error is a connection-level protocol error.
  73. bool is_session_level_protocol_error() const;
  74. /// The error indicates a client reset situation.
  75. bool is_client_reset_requested() const;
  76. };
  77. using SyncSessionErrorHandler = void(std::shared_ptr<SyncSession>, SyncError);
  78. enum class ReconnectMode {
  79. /// This is the mode that should always be used by SDKs. In this
  80. /// mode the client uses a scheme for determining a reconnect delay that
  81. /// prevents it from creating too many connection requests in a short
  82. /// amount of time (i.e., a server hammering protection mechanism).
  83. normal,
  84. /// For internal sync-client testing purposes only.
  85. ///
  86. /// Never reconnect automatically after the connection is closed due to
  87. /// an error. Allow immediate reconnect if the connection was closed
  88. /// voluntarily (e.g., due to sessions being abandoned).
  89. ///
  90. /// In this mode, Client::cancel_reconnect_delay() and
  91. /// Session::cancel_reconnect_delay() can still be used to trigger
  92. /// another reconnection attempt (with no delay) after an error has
  93. /// caused the connection to be closed.
  94. testing
  95. };
  96. enum class SyncSessionStopPolicy {
  97. Immediately, // Immediately stop the session as soon as all Realms/Sessions go out of scope.
  98. LiveIndefinitely, // Never stop the session.
  99. AfterChangesUploaded, // Once all Realms/Sessions go out of scope, wait for uploads to complete and stop.
  100. };
  101. enum class ClientResyncMode : unsigned char {
  102. // Fire a client reset error
  103. Manual,
  104. // Discard local changes, without disrupting accessors or closing the Realm
  105. DiscardLocal,
  106. // Attempt to recover unsynchronized but committed changes.
  107. Recover,
  108. // Attempt recovery and if that fails, discard local.
  109. RecoverOrDiscard,
  110. };
  111. enum class SyncClientHookEvent {
  112. DownloadMessageReceived,
  113. DownloadMessageIntegrated,
  114. BootstrapMessageProcessed,
  115. BootstrapProcessed,
  116. ErrorMessageReceived,
  117. };
  118. enum class SyncClientHookAction {
  119. NoAction,
  120. EarlyReturn,
  121. SuspendWithRetryableError,
  122. };
  123. struct SyncClientHookData {
  124. SyncClientHookEvent event;
  125. sync::SyncProgress progress;
  126. int64_t query_version;
  127. sync::DownloadBatchState batch_state;
  128. size_t num_changesets;
  129. const sync::ProtocolErrorInfo* error_info = nullptr;
  130. };
  131. struct SyncConfig {
  132. struct FLXSyncEnabled {
  133. };
  134. struct ProxyConfig {
  135. using port_type = sync::port_type;
  136. enum class Type { HTTP, HTTPS } type;
  137. std::string address;
  138. port_type port;
  139. };
  140. using SSLVerifyCallback = bool(const std::string& server_address, ProxyConfig::port_type server_port,
  141. const char* pem_data, size_t pem_size, int preverify_ok, int depth);
  142. std::shared_ptr<SyncUser> user;
  143. std::string partition_value;
  144. SyncSessionStopPolicy stop_policy = SyncSessionStopPolicy::AfterChangesUploaded;
  145. std::function<SyncSessionErrorHandler> error_handler;
  146. bool flx_sync_requested = false;
  147. // When integrating a flexible sync bootstrap, process this many bytes of changeset data in a single integration
  148. // attempt. This many bytes of changesets will be uncompressed and held in memory while being applied.
  149. size_t flx_bootstrap_batch_size_bytes = 1024 * 1024;
  150. // {@
  151. /// DEPRECATED - Will be removed in a future release
  152. // The following parameters are only used by the default SyncSocket implementation. Custom SyncSocket
  153. // implementations must handle these directly, if these features are supported.
  154. util::Optional<std::string> authorization_header_name; // not used
  155. std::map<std::string, std::string> custom_http_headers;
  156. bool client_validate_ssl = true;
  157. util::Optional<std::string> ssl_trust_certificate_path;
  158. std::function<SSLVerifyCallback> ssl_verify_callback;
  159. util::Optional<ProxyConfig> proxy_config;
  160. // @}
  161. // If true, upload/download waits are canceled on any sync error and not just fatal ones
  162. bool cancel_waits_on_nonfatal_error = false;
  163. // If false, changesets incoming from the server are discarded without
  164. // applying them to the Realm file. This is required when writing objects
  165. // directly to replication, and will break horribly otherwise
  166. bool apply_server_changes = true;
  167. // The name of the directory which Realms should be backed up to following
  168. // a client reset in ClientResyncMode::Manual mode
  169. util::Optional<std::string> recovery_directory;
  170. ClientResyncMode client_resync_mode = ClientResyncMode::Manual;
  171. std::function<void(std::shared_ptr<Realm> before_frozen)> notify_before_client_reset;
  172. std::function<void(std::shared_ptr<Realm> before_frozen, ThreadSafeReference after, bool did_recover)>
  173. notify_after_client_reset;
  174. // Used by core testing to hook into the sync client when various events occur and maybe inject
  175. // errors/disconnects deterministically.
  176. std::function<SyncClientHookAction(std::weak_ptr<SyncSession>, const SyncClientHookData&)>
  177. on_sync_client_event_hook;
  178. bool simulate_integration_error = false;
  179. SyncConfig() = default;
  180. explicit SyncConfig(std::shared_ptr<SyncUser> user, bson::Bson partition);
  181. explicit SyncConfig(std::shared_ptr<SyncUser> user, std::string partition);
  182. explicit SyncConfig(std::shared_ptr<SyncUser> user, const char* partition);
  183. explicit SyncConfig(std::shared_ptr<SyncUser> user, FLXSyncEnabled);
  184. };
  185. } // namespace realm
  186. #endif // REALM_SYNC_CONFIG_HPP