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

Client reset #925

Merged
merged 130 commits into from
Nov 4, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
2d4a7c0
Set recoverOrDiscard as a default resync mode on client reset
desistefanova Sep 26, 2022
a35294b
Тypified SyncClientResetHandler
desistefanova Sep 26, 2022
c954177
Fix API doc
desistefanova Sep 26, 2022
0a50fd3
Fix spaces between classes
desistefanova Sep 26, 2022
5f655eb
Hide ClientResyncMode from FlexibleSyncConfiguration
desistefanova Sep 26, 2022
bc942ba
Fix the test
desistefanova Sep 26, 2022
1c0ddc4
Changelog
desistefanova Sep 26, 2022
aeb96a5
Fix doc API
desistefanova Sep 26, 2022
e6ff8f2
Merge branch 'master' into ds/resync_mode
desistefanova Oct 3, 2022
6e56503
Merge branch 'master' into ds/resync_mode
desistefanova Oct 4, 2022
232a188
Update lib/src/configuration.dart
desistefanova Oct 5, 2022
051a5de
Update lib/src/configuration.dart
desistefanova Oct 10, 2022
94e8076
Update lib/src/configuration.dart
desistefanova Oct 10, 2022
29bfaf4
Update lib/src/configuration.dart
desistefanova Oct 10, 2022
1c4b817
Update lib/src/configuration.dart
desistefanova Oct 10, 2022
52df055
Update lib/src/configuration.dart
desistefanova Oct 10, 2022
42d3e32
Code review changes - rename classes
desistefanova Oct 10, 2022
cbdffd0
Force _mode to require override
desistefanova Oct 10, 2022
ee95104
Merge branch 'master' into ds/resync_mode
desistefanova Oct 10, 2022
6186474
Merge branch 'master' into ds/resync_mode
desistefanova Oct 10, 2022
b99304d
Changelog
desistefanova Oct 10, 2022
4229058
Test fix after merge
desistefanova Oct 10, 2022
5f82304
Try to fix User.apiKeys
desistefanova Oct 10, 2022
d71322b
Revert "Try to fix User.apiKeys"
desistefanova Oct 10, 2022
031a2bc
Merge branch 'master' into ds/resync_mode
nirinchev Oct 17, 2022
e43cc07
Initial wiring of callbacks
nirinchev Oct 17, 2022
d3664a9
Call Atlas function
desistefanova Oct 18, 2022
5e5473d
Changelog
desistefanova Oct 18, 2022
a796889
Convert response to dynamic
desistefanova Oct 18, 2022
6230046
Add tests for multiple arguments
desistefanova Oct 18, 2022
37ad082
Add a test with expected exception
desistefanova Oct 18, 2022
3efd138
Merge branch 'master' into ds/resync_mode
desistefanova Oct 18, 2022
141bb95
Merge branch 'master' into ds/call_user_function
desistefanova Oct 18, 2022
5c9c5df
Add test for call function with object arguments
desistefanova Oct 19, 2022
25bd1a5
Expose FunctionsClient
desistefanova Oct 19, 2022
a436117
Regenerated model metrics.g.dart
desistefanova Oct 19, 2022
39b7550
Merge branch 'ds/call_user_function' into ni/client-reset
nirinchev Oct 20, 2022
b9b0a4e
Minor tweaks to the call function API
nirinchev Oct 20, 2022
0a93c70
Add basic client reset tests
nirinchev Oct 20, 2022
03f9115
Minor tweaks to the call function API
nirinchev Oct 20, 2022
263c0c9
Merge branch 'ds/resync_mode' into ni/client-reset
nirinchev Oct 20, 2022
3e4c0b6
Merge branch 'ds/call_user_function' into ds/resync_mode
desistefanova Oct 20, 2022
63a530f
Minor cleanup of baasclient
nirinchev Oct 20, 2022
a00a094
Merge branch 'ds/resync_mode' into ni/client-reset
desistefanova Oct 20, 2022
4c59263
Regenerate metrics.g.dart
desistefanova Oct 20, 2022
b2aa10d
Apply suggestions from code review
desistefanova Oct 24, 2022
b3abe6c
Code review changes
desistefanova Oct 24, 2022
d572ae9
Merge branch 'master' into ds/call_user_function
desistefanova Oct 24, 2022
7c7b873
Update test/app_test.dart
desistefanova Oct 24, 2022
794cdaf
Apply suggestions from code review
desistefanova Oct 24, 2022
0eec385
Update lib/src/user.dart
desistefanova Oct 24, 2022
adc63cc
Apply suggestions from code review
blagoev Oct 25, 2022
27c0c54
Update lib/src/configuration.dart
desistefanova Oct 25, 2022
26f47e9
Rename SyncClientResetError to ClientResetError
desistefanova Oct 25, 2022
c1487f1
Merge branch 'ds/resync_mode' of https://github.com/realm/realm-dart …
desistefanova Oct 25, 2022
0900582
Merge branch 'master' into ds/call_user_function
desistefanova Oct 25, 2022
20ba0b2
Insist not null in response
desistefanova Oct 25, 2022
be2dd4c
Reverted `response as Map<String, dynamic>`
desistefanova Oct 25, 2022
17fbe8f
Merge branch 'master' into ds/call_user_function
desistefanova Oct 25, 2022
bf2e895
Merge branch 'ds/call_user_function' into ds/resync_mode
desistefanova Oct 25, 2022
4c608e8
ManualRecoveryHandler not named argument
desistefanova Oct 25, 2022
f5b4747
Merge branch 'master' into ds/resync_mode
desistefanova Oct 25, 2022
6a4c5f8
Merge branch 'master' into ds/resync_mode
desistefanova Oct 25, 2022
b7ce710
Add client_reset_test to flutter driver
desistefanova Oct 25, 2022
9d3b0c4
Check callbacks are reported
desistefanova Oct 26, 2022
5abb190
Merge branch 'ds/resync_mode' of https://github.com/realm/realm-dart …
desistefanova Oct 26, 2022
68f5cd1
Discart on recovery disabled
desistefanova Oct 26, 2022
192aed4
manualResetFallback invoked when throw on After
desistefanova Oct 26, 2022
dd9d791
immediatelyRunFileActions + code review changes
desistefanova Oct 26, 2022
8770ea4
Merge branch 'master' into ds/resync_mode
desistefanova Oct 26, 2022
02f4fcf
Initiate realm reset after manual callback
desistefanova Oct 26, 2022
2112412
DiscardUnsyncedChangesHandler notifications
desistefanova Oct 26, 2022
6cee5c2
Fix completer error
desistefanova Oct 26, 2022
5dae2f9
Code review changes
desistefanova Oct 26, 2022
5949d3f
Fix Initiate resetRealm on ManualRecoveryHandler
desistefanova Oct 26, 2022
ad2135f
Future callbacks
desistefanova Oct 26, 2022
7f59311
Fix test with 'Realm file is in use'
desistefanova Oct 27, 2022
46dc3b1
implement callback_completed
desistefanova Oct 27, 2022
64e6b4c
Support Future in beforeResetCallback
desistefanova Oct 27, 2022
b42629e
Fix test with resetRealm
desistefanova Oct 27, 2022
8785d43
Clean up future handling for before reset callback
nirinchev Oct 27, 2022
ca68e1f
Refactor Before Callback core unlock
desistefanova Oct 27, 2022
cab4940
Merge branch 'ds/resync_mode' of https://github.com/realm/realm-dart …
desistefanova Oct 27, 2022
228e7f3
Rename unlockCoreFunc
desistefanova Oct 27, 2022
a181688
Make async After reset callback
desistefanova Oct 27, 2022
f7122fc
Fixing tests
desistefanova Oct 27, 2022
e4e5b02
Fix tests
desistefanova Oct 27, 2022
8d0d3ac
Manual reset async
desistefanova Oct 27, 2022
1fad265
unlock _syncErrorHandlerCallback if empty
desistefanova Oct 28, 2022
1b6c75f
Remove locks from sync_error_handler_callback
desistefanova Oct 28, 2022
74768c6
Fix a test expected error
desistefanova Oct 28, 2022
9d974b0
Check data before and after recovery or/and discard
desistefanova Oct 28, 2022
84fa854
Check product ids in before and after realm
desistefanova Oct 28, 2022
f087656
Fix test waiting forever
desistefanova Oct 28, 2022
56ce2b3
Recover unsynced
desistefanova Oct 28, 2022
da79760
Fix Recovery integration test
desistefanova Oct 30, 2022
66f44e6
Merge branch 'master' into ds/resync_mode
desistefanova Oct 31, 2022
91c930d
Changelog
desistefanova Oct 31, 2022
1f0260f
Update CHANGELOG.md
desistefanova Oct 31, 2022
c53982d
Update CHANGELOG.md
desistefanova Oct 31, 2022
7c2153d
Add config member to ClientResetError
desistefanova Oct 31, 2022
dd047e1
Delete class WaitingCallback
desistefanova Oct 31, 2022
af8e94b
Code review changes
desistefanova Nov 1, 2022
b7574bd
Code review changes
desistefanova Nov 1, 2022
2f677cc
Fix API doc
desistefanova Nov 1, 2022
901222d
Code review changes
desistefanova Nov 1, 2022
8f14572
Move error enums back to ream_types.dart
desistefanova Nov 1, 2022
61a27a8
Code review fixes
desistefanova Nov 1, 2022
d97476a
Merge branch 'master' into ds/resync_mode
desistefanova Nov 2, 2022
f5619fe
Move resetRealm into ClientResetError
desistefanova Nov 2, 2022
77bde66
Fix API doc
desistefanova Nov 2, 2022
2e04981
Update lib/src/configuration.dart
desistefanova Nov 2, 2022
90b3f52
Apply suggestions from code review
desistefanova Nov 3, 2022
85fff83
code review changes
desistefanova Nov 3, 2022
ac7c75c
Code review changes
desistefanova Nov 3, 2022
8220beb
Merge branch 'master' into ds/resync_mode
desistefanova Nov 3, 2022
cbebb94
Fix merge from master
desistefanova Nov 3, 2022
e0ced95
Refactor client reset (#1003)
blagoev Nov 3, 2022
db0478c
Merge branch 'master' into ds/resync_mode
desistefanova Nov 3, 2022
50a7a0e
Merge branch 'master' into ds/resync_mode
desistefanova Nov 3, 2022
b96391b
Formatting
desistefanova Nov 3, 2022
ba55fc5
Add timeouts to all client reset tests
desistefanova Nov 3, 2022
2ac9b22
Fixed test
desistefanova Nov 3, 2022
8f996d8
Code review changes
desistefanova Nov 3, 2022
574f219
Code review changes
desistefanova Nov 3, 2022
757f011
Code review changes
desistefanova Nov 4, 2022
673236b
Umprove CHANGELOG
desistefanova Nov 4, 2022
39f78bc
Exports and Imports reordered
desistefanova Nov 4, 2022
f8ce80f
Reorder 'app.dart' exports
desistefanova Nov 4, 2022
cecf772
Fix Changelog
desistefanova Nov 4, 2022
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
* Expose `User.apiKeys` client - this client can be used to create, fetch, and delete API keys.
* Expose `Credentials.apiKey` that enable authentication with API keys.
* Exposed `User.accessToken` and `User.refreshToken` - these tokens can be used to authenticate against the server when calling HTTP API outside of the Dart/Flutter SDK. For example, if you want to use the GraphQL. (PR [#919](https://github.com/realm/realm-dart/pull/919))
* Set `recoverOrDiscard` mode as default resync mode for `FlexibleSyncConfiguration`. In this mode Realm attempts to recover unsynced local changes and if that fails, then the changes are discarded.(PR [#925](https://github.com/realm/realm-dart/pull/925))

### Fixed
* Previously removeAt did not truncate length. ([#883](https://github.com/realm/realm-dart/issues/883))
Expand Down
79 changes: 74 additions & 5 deletions lib/src/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ abstract class Configuration implements Finalizable {
String? fifoFilesFallbackPath,
String? path,
SyncErrorHandler syncErrorHandler = defaultSyncErrorHandler,
SyncClientResetErrorHandler syncClientResetErrorHandler = const ManualSyncClientResetHandler(_defaultSyncClientResetHandler),
SyncClientResetErrorHandler syncClientResetErrorHandler = const RecoverOrDiscardSyncClientResetHandler(_defaultSyncClientResetHandler),
}) =>
FlexibleSyncConfiguration._(
user,
Expand Down Expand Up @@ -286,7 +286,7 @@ class FlexibleSyncConfiguration extends Configuration {
super.fifoFilesFallbackPath,
super.path,
this.syncErrorHandler = defaultSyncErrorHandler,
this.syncClientResetErrorHandler = const ManualSyncClientResetHandler(_defaultSyncClientResetHandler),
this.syncClientResetErrorHandler = const RecoverOrDiscardSyncClientResetHandler(_defaultSyncClientResetHandler),
}) : super._();

@override
Expand Down Expand Up @@ -369,8 +369,12 @@ class RealmSchema extends Iterable<SchemaObject> {

/// The signature of a callback that will be invoked if a client reset error occurs for this [Realm].
///
/// Currently, Flexible Sync supports only the [ManualSyncClientResetHandler].
class SyncClientResetErrorHandler {
/// A Client Resync is triggered if the device and server cannot agree
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
/// on a common shared history for the Realm file,
/// thus making it impossible for the device to upload or receive any changes.
/// This can happen if the server is rolled back or restored from backup.
/// {@category Sync}
abstract class SyncClientResetErrorHandler {
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
/// The callback that handles the [SyncClientResetError].
final void Function(SyncClientResetError code) callback;

Expand All @@ -379,4 +383,69 @@ class SyncClientResetErrorHandler {
}

/// A client reset strategy where the user needs to fully take care of a client reset.
typedef ManualSyncClientResetHandler = SyncClientResetErrorHandler;
///
/// If you set [ManualSyncClientResetHandler] callback as `syncClientResetErrorHandler` argument of [Configuration.flexibleSync],
/// that will enable full control of moving unsynced changes to synced realm.
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
/// {@category Sync}
class ManualSyncClientResetHandler extends SyncClientResetErrorHandler {
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
const ManualSyncClientResetHandler(super.callback);
}

/// A client reset strategy where all the not yet synchronized data is automatically
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
/// discarded and a fresh copy of the synchronized Realm is obtained.
///
/// If you set [DiscardLocalSyncClientResetHandler] callback as `syncClientResetErrorHandler` argument of [Configuration.flexibleSync],
/// the local Realm will be discarded and replaced with the server side Realm.
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
/// All local changes will be lost.
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
/// {@category Sync}
class DiscardLocalSyncClientResetHandler extends SyncClientResetErrorHandler {
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
const DiscardLocalSyncClientResetHandler(super.callback);
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
}

///A client reset strategy that attempts to automatically recover any unsynchronized changes.
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
///
/// If you set [RecoverSyncClientResetHandler] callback as `syncClientResetErrorHandler` argument of [Configuration.flexibleSync],
/// Realm will compare the local Realm with the Realm on the server and automatically transfer
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
/// any changes from the local Realm that makes sense to the Realm provided by the server.
/// {@category Sync}
class RecoverSyncClientResetHandler extends SyncClientResetErrorHandler {
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
const RecoverSyncClientResetHandler(super.callback);
}

/// A client reset strategy that attempts to automatically recover any unsynchronized changes.
/// If that fails, this handler fallsback to the discard unsynced changes strategy.
///
/// If you set [RecoverOrDiscardSyncClientResetHandler] callback as `syncClientResetErrorHandler` argument of [Configuration.flexibleSync],
/// Realm will compare the local Realm with the Realm on the server and automatically transfer
/// any changes from the local Realm that makes sense to the Realm provided by the server.
/// If that fails, the local changes will be discarded.
/// This is the default mode for fully synchronized Realms.
/// {@category Sync}
class RecoverOrDiscardSyncClientResetHandler extends SyncClientResetErrorHandler {
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
const RecoverOrDiscardSyncClientResetHandler(super.callback);

}

/// @nodoc
extension SyncClientResetErrorHandlerInternal on SyncClientResetErrorHandler {
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
ClientResyncModeInternal get clientResyncMode {
if (this is ManualSyncClientResetHandler) {
return ClientResyncModeInternal.manual;
} else if (this is DiscardLocalSyncClientResetHandler) {
return ClientResyncModeInternal.discardLocal;
} else if (this is RecoverSyncClientResetHandler) {
return ClientResyncModeInternal.recover;
} else {
return ClientResyncModeInternal.recoverOrDiscard;
}
}
}

/// Enum describing what should happen in case of a Client Resync.
/// @nodoc
enum ClientResyncModeInternal {
manual,
discardLocal,
recover,
recoverOrDiscard,
}
3 changes: 2 additions & 1 deletion lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,14 @@ class _RealmCore {
final syncConfigPtr = _realmLib.invokeGetPointer(() => _realmLib.realm_flx_sync_config_new(config.user.handle._pointer));
try {
_realmLib.realm_sync_config_set_session_stop_policy(syncConfigPtr, config.sessionStopPolicy.index);

_realmLib.realm_sync_config_set_resync_mode(syncConfigPtr, config.syncClientResetErrorHandler.clientResyncMode.index);
final errorHandlerCallback =
Pointer.fromFunction<Void Function(Handle, Pointer<realm_sync_session_t>, realm_sync_error_t)>(_syncErrorHandlerCallback);
final errorHandlerUserdata = _realmLib.realm_dart_userdata_async_new(config, errorHandlerCallback.cast(), scheduler.handle._pointer);
_realmLib.realm_sync_config_set_error_handler(syncConfigPtr, _realmLib.addresses.realm_dart_sync_error_handler_callback, errorHandlerUserdata.cast(),
_realmLib.addresses.realm_dart_userdata_async_free);


_realmLib.realm_config_set_sync_config(configPtr, syncConfigPtr);
} finally {
_realmLib.realm_release(syncConfigPtr.cast());
Expand Down
6 changes: 5 additions & 1 deletion lib/src/realm_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ export "configuration.dart"
SchemaObject,
ShouldCompactCallback,
SyncErrorHandler,
SyncClientResetErrorHandler;
SyncClientResetErrorHandler,
ManualSyncClientResetHandler,
DiscardLocalSyncClientResetHandler,
RecoverSyncClientResetHandler,
RecoverOrDiscardSyncClientResetHandler;

export 'credentials.dart' show Credentials, AuthProviderType, EmailPasswordAuthProvider;
export 'list.dart' show RealmList, RealmListOfObject, RealmListChanges;
Expand Down
39 changes: 39 additions & 0 deletions test/configuration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import 'dart:math';
import 'package:test/test.dart' hide test, throws;
import 'package:path/path.dart' as path;
import '../lib/realm.dart';
import '../lib/src/configuration.dart' show SyncClientResetErrorHandlerInternal, ClientResyncModeInternal;
import 'test.dart';

Future<void> main([List<String>? args]) async {
Expand Down Expand Up @@ -530,4 +531,42 @@ Future<void> main([List<String>? args]) async {
final disconnectedRealm = Realm(disconnectedSyncConfig);
expect(disconnectedRealm.find<Task>(oid), isNotNull);
});

baasTest("Configuration.flexibleSync set recoverOrDiscard as a default resync mode", (appConfiguration) async {
final app = App(appConfiguration);
final credentials = Credentials.anonymous();
final user = await app.logIn(credentials);
expect(
Configuration.flexibleSync(
user,
[Task.schema, Schedule.schema],
syncClientResetErrorHandler: ManualSyncClientResetHandler((syncError) {}),
).syncClientResetErrorHandler.clientResyncMode,
ClientResyncModeInternal.manual);
expect(
Configuration.flexibleSync(
user,
[Task.schema, Schedule.schema],
syncClientResetErrorHandler: DiscardLocalSyncClientResetHandler((syncError) {}),
).syncClientResetErrorHandler.clientResyncMode,
ClientResyncModeInternal.discardLocal);
expect(
Configuration.flexibleSync(
user,
[Task.schema, Schedule.schema],
syncClientResetErrorHandler: RecoverSyncClientResetHandler((syncError) {}),
).syncClientResetErrorHandler.clientResyncMode,
ClientResyncModeInternal.recover);

expect(
Configuration.flexibleSync(
user,
[Task.schema, Schedule.schema],
syncClientResetErrorHandler: RecoverOrDiscardSyncClientResetHandler((syncError) {}),
).syncClientResetErrorHandler.clientResyncMode,
ClientResyncModeInternal.recoverOrDiscard);

expect(Configuration.flexibleSync(user, [Task.schema, Schedule.schema]).syncClientResetErrorHandler.clientResyncMode,
ClientResyncModeInternal.recoverOrDiscard);
});
}