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

Open realm async #731

Merged
merged 138 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
138 commits
Select commit Hold shift + click to select a range
3e23f73
Implement openRealmAsync in realm_core
desistefanova Jul 30, 2022
dcd479b
Convert thread_safe_reference to realm
desistefanova Jul 30, 2022
12ccd5b
Realm openSync
desistefanova Jul 30, 2022
4dad19f
Merge branch 'master' into ds/open_realm_async
desistefanova Aug 11, 2022
4c0f6c3
Rename _openRealmAsyncCallback
desistefanova Aug 11, 2022
9e73ed2
Remove Realm.openSync
desistefanova Aug 11, 2022
c801ccf
Cancel operation realm open asyn
desistefanova Aug 11, 2022
c0c1f03
Create RealmAsyncTask
desistefanova Aug 12, 2022
ae34d95
Fix test
desistefanova Aug 12, 2022
99f56e8
Delete not needed imports
desistefanova Aug 12, 2022
fc2862f
Merge branch 'master' into ds/open_realm_async
desistefanova Aug 12, 2022
8b3f340
Merge branch 'master' into ds/open_realm_async
desistefanova Aug 12, 2022
929f308
Rename class RealmAsyncOpenTask
desistefanova Aug 12, 2022
78a362e
Implement cancel and onProgress
desistefanova Aug 14, 2022
18aa548
Add API doc
desistefanova Aug 14, 2022
1f2403f
Fix API doc
desistefanova Aug 14, 2022
640eece
Update CHANGELOG.md
desistefanova Aug 14, 2022
ad31355
Merge branch 'master' into ds/open_realm_async
desistefanova Aug 14, 2022
c0c88eb
Fix removed handle from RealmAsyncOpenTask
desistefanova Aug 14, 2022
427501b
open async many times exception
desistefanova Aug 14, 2022
49ff150
Delete package dart async
desistefanova Aug 14, 2022
3e12460
Merge branch 'master' into ds/open_realm_async
desistefanova Aug 17, 2022
1a8b7d4
Regenerate bindings
desistefanova Aug 17, 2022
a0ab6cf
Implement RealmCancelationController
desistefanova Aug 19, 2022
317e228
Merge branch 'master' into ds/open_realm_async
desistefanova Aug 19, 2022
0fa912c
Merge branch 'ds/open_realm_async_variant1' into ds/open_realm_async
desistefanova Aug 19, 2022
9117488
Fix merging
desistefanova Aug 19, 2022
b8793ac
Add test for multiple realms
desistefanova Aug 19, 2022
b25a3b1
Test download progress with subscriptions
desistefanova Aug 19, 2022
69311a1
Fix test
desistefanova Aug 19, 2022
887162b
Merge branch 'master' into ds/open_realm_async
desistefanova Aug 22, 2022
503f882
Fixed Realm paths
desistefanova Aug 22, 2022
1473f78
Merge branch 'master' into ds/open_realm_async
desistefanova Sep 12, 2022
adf3113
Remove a comment
desistefanova Sep 12, 2022
4c67435
Fixing some condition
desistefanova Sep 12, 2022
6b92691
Refactor Realp open async
desistefanova Sep 13, 2022
d64fd51
Remove redundant code
desistefanova Sep 13, 2022
3f13fbf
Remove callback method
desistefanova Sep 13, 2022
69cf2fc
Create dir sync and handle CancelledException
desistefanova Sep 13, 2022
345db63
Fix wrong user realm paths
desistefanova Sep 13, 2022
6906f2c
Close realm on cancel
desistefanova Sep 14, 2022
f48bb51
Implement CancellableFuture
desistefanova Sep 16, 2022
96d2213
Update lib/src/realm_class.dart
desistefanova Sep 16, 2022
4a91725
Delete _createFileDirectory
desistefanova Sep 16, 2022
caa5cea
Merge branch 'ds/open_realm_async' of https://github.com/realm/realm-…
desistefanova Sep 16, 2022
74deaf6
Realm open async - open two different Realms
desistefanova Sep 16, 2022
13dd44a
Added tests for local realm
desistefanova Sep 16, 2022
5dbbed3
Fixing test cases
desistefanova Sep 16, 2022
6ee2435
Use throwsA in expectLater
desistefanova Sep 17, 2022
ea4c14b
CancellableFuture refactoring
desistefanova Sep 17, 2022
63277df
Fixing tests
desistefanova Sep 18, 2022
f29891d
Fix doc API and CHANGELOG
desistefanova Sep 18, 2022
cb8af6c
Rename a method
desistefanova Sep 18, 2022
7ef29e9
Token canceled in advance
desistefanova Sep 19, 2022
4e227f5
Merge branch 'master' into ds/open_realm_async
desistefanova Sep 19, 2022
5536250
Cancel with completer
desistefanova Sep 19, 2022
d41975f
Merge branch 'ds/open_realm_async' of https://github.com/realm/realm-…
desistefanova Sep 19, 2022
3064c9b
Update lib/src/realm_class.dart
desistefanova Sep 20, 2022
0560733
Update lib/src/realm_class.dart
desistefanova Sep 20, 2022
1f170c4
Update lib/src/realm_class.dart
desistefanova Sep 20, 2022
c8f2288
Update lib/src/realm_class.dart
desistefanova Sep 20, 2022
5cea4d7
Update lib/src/realm_class.dart
desistefanova Sep 20, 2022
2d10b89
Code review changes
desistefanova Sep 20, 2022
1395503
Do waitForDownload always when FLXS
desistefanova Sep 20, 2022
a179bf7
Merge branch 'master' into ds/open_realm_async
desistefanova Sep 20, 2022
44e181a
Update Changelog
desistefanova Sep 20, 2022
165791f
Realm open async if realm already exists
desistefanova Sep 20, 2022
f31c62c
Implement RealmA.open helper method for tests
desistefanova Sep 20, 2022
510faf6
Merge branch 'master' into ds/open_realm_async
desistefanova Sep 20, 2022
4d16c8c
Fix merge
desistefanova Sep 20, 2022
521b5fc
Add waiting for download
desistefanova Sep 20, 2022
432dc78
Update lib/src/realm_class.dart
desistefanova Sep 21, 2022
d80f18c
Code review changes
desistefanova Sep 23, 2022
0864aa8
Merge branch 'master' into ds/open_realm_async
desistefanova Oct 3, 2022
b11a6cc
completeError completer in sessionWaitForDownload
desistefanova Oct 4, 2022
d854550
Merge branch 'master' into ds/open_realm_async
desistefanova Oct 4, 2022
81563d0
get progress and cancel
desistefanova Oct 4, 2022
512fbf0
Completer extension makeCancellable
desistefanova Oct 4, 2022
3d824ee
Merge branch 'master' into ds/open_realm_async
desistefanova Oct 4, 2022
ed5b0ca
wait for getProgressStream
desistefanova Oct 4, 2022
53c2f6f
don't wait for getProgressStream, cancel on error
desistefanova Oct 5, 2022
1a85bbd
Cancel in future delayed
desistefanova Oct 5, 2022
a60f546
Using cancellatin_token package
desistefanova Oct 5, 2022
0e3cff1
Hide CancellableFunction
desistefanova Oct 5, 2022
013a0f1
Dart formatting
desistefanova Oct 5, 2022
3137605
Remove code for testing futures
desistefanova Oct 5, 2022
2e67ff2
wait for progress for a realm with subscriptions
desistefanova Oct 5, 2022
0609d62
Close the realm on cancel only after all the operation have completed
desistefanova Oct 5, 2022
daf8e79
await for progress notifications
desistefanova Oct 5, 2022
46825d4
Avoid "Cannot access a Session that belongs to a closed Realm"
desistefanova Oct 6, 2022
e9449a6
Avoid "Cannot access a Session that belongs to a closed Realm"
desistefanova Oct 6, 2022
918e7f3
Close realm in cancel after all others are canceled
desistefanova Oct 6, 2022
a68c6dc
skip execution in completer is completed
desistefanova Oct 6, 2022
9d44a4e
Fix tests
desistefanova Oct 6, 2022
e281a40
Implement CancellableCompleter
desistefanova Oct 6, 2022
aee17c3
Fix tests and add extension asCancellable
desistefanova Oct 6, 2022
35f11d2
Merge branch 'ds/open_realm_async_asCancellable' into ds/open_realm_a…
desistefanova Oct 6, 2022
88456ed
Self code review changes
desistefanova Oct 6, 2022
cecb37e
Merge branch 'master' into ds/open_realm_async
desistefanova Oct 6, 2022
834ca01
fix one test
desistefanova Oct 6, 2022
59b38c2
Update lib/src/realm_class.dart
desistefanova Oct 6, 2022
69dac4d
Code review change
desistefanova Oct 6, 2022
2a00c41
Merge branch 'ds/open_realm_async' of https://github.com/realm/realm-…
desistefanova Oct 6, 2022
b025e39
Remove a redundant method
desistefanova Oct 7, 2022
e601f58
Code review changes
desistefanova Oct 12, 2022
33005f6
Merge branch 'master' into ds/open_realm_async
desistefanova Oct 12, 2022
45be02b
Code review changes
desistefanova Oct 12, 2022
9d7d905
Merge branch 'ds/open_realm_async' of https://github.com/realm/realm-…
desistefanova Oct 12, 2022
0e4adc8
Update lib/src/realm_class.dart
desistefanova Oct 12, 2022
a28eb71
Add cancellation_token to realm_core
desistefanova Oct 12, 2022
1dfc0d9
Update test/realm_test.dart
desistefanova Oct 13, 2022
601e9a5
Update test/realm_test.dart
desistefanova Oct 13, 2022
8005ebc
Update test/realm_test.dart
desistefanova Oct 13, 2022
c4a7a19
Update test/realm_test.dart
desistefanova Oct 13, 2022
401e51a
Update test/realm_test.dart
desistefanova Oct 13, 2022
c14b082
Update lib/src/realm_class.dart
desistefanova Oct 13, 2022
ec2b25c
Apply suggestions from code review
desistefanova Oct 13, 2022
4d6a656
Code review changes
desistefanova Oct 13, 2022
be9d3a2
Code review changes
desistefanova Oct 13, 2022
9e66790
Code review changes
desistefanova Oct 13, 2022
01e5767
Code review changes
desistefanova Oct 13, 2022
d6138e9
realm closed after added sunscriptions
desistefanova Oct 13, 2022
92f54ac
Fix test
desistefanova Oct 13, 2022
9996836
Return back getProgressStream listen
desistefanova Oct 13, 2022
62f6f89
Update lib/src/realm_class.dart
desistefanova Oct 14, 2022
12f315e
Cancel subscription before realm close
desistefanova Oct 14, 2022
388e623
Fixed test with query subscription
desistefanova Oct 14, 2022
05ec292
Merge from master
desistefanova Oct 17, 2022
c774464
Update changelog
desistefanova Oct 17, 2022
5e31937
Merge branch 'master' into ds/open_realm_async
desistefanova Oct 17, 2022
eb85d16
Regenerate metrics.g.dart
desistefanova Oct 18, 2022
5f4afde
Set json_annotation version to ^4.7.0
desistefanova Oct 18, 2022
fdbd591
Code review changes
desistefanova Oct 18, 2022
bdcb569
Merge branch 'master' into ds/open_realm_async
desistefanova Oct 18, 2022
598a71c
Merge branch 'master' into ds/open_realm_async
desistefanova Oct 18, 2022
c587062
After merge fixes
desistefanova Oct 18, 2022
ad5dcc0
Merge branch 'master' into ds/open_realm_async
desistefanova Oct 18, 2022
e97d6e3
Regenerate main.g.dart
desistefanova Oct 18, 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 @@ -7,6 +7,7 @@
* Added `Transaction` which is a class that exposes an API for committing and rolling back an active transaction.
* Added `realm.beginWriteAsync` which returns a `Future<Transaction>` that resolves when the write lock has been obtained.
* Added `realm.writeAsync` which opens an asynchronous transaction, invokes the provided callback, then commits the transaction asynchronously.
* Support `Realm.open` API to asynchronously open a local or synced Realm. When opening a synchronized Realm it will download all the content available at the time the operation began and then return a usable Realm. ([#731](https://github.com/realm/realm-dart/pull/731))

### Fixed
* Added more validations when using `User.apiKeys` to return more meaningful errors when the user cannot perform API key actions - e.g. when the user has been logged in with API key credentials or when the user has been logged out. (Issue [#950](https://github.com/realm/realm-dart/issues/950))
Expand Down
2 changes: 1 addition & 1 deletion ffigen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ The is executed manually as needed and this package is never published.

Usage:

dart run ffigen
dart run ffigen --config config.yaml

On linux you may need to install clang 11 dev tools. If you are using apt-get you can do:
```
Expand Down
2 changes: 1 addition & 1 deletion flutter/realm_flutter/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ dependencies:
tar: ^0.5.4
build_runner: ^2.1.0
http: ^0.13.4
cancellation_token: ^1.4.0
cancellation_token: ^1.5.0

dev_dependencies:
flutter_test:
Expand Down
20 changes: 12 additions & 8 deletions lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1831,20 +1831,24 @@ class _RealmCore {
return completer.future;
}

Future<void> sessionWaitForDownload(Session session) {
final completer = Completer<void>();
final callback = Pointer.fromFunction<Void Function(Handle, Pointer<realm_sync_error_code_t>)>(_sessionWaitCompletionCallback);
final userdata = _realmLib.realm_dart_userdata_async_new(completer, callback.cast(), scheduler.handle._pointer);
_realmLib.realm_sync_session_wait_for_download_completion(session.handle._pointer, _realmLib.addresses.realm_dart_sync_wait_for_completion_callback,
userdata.cast(), _realmLib.addresses.realm_dart_userdata_async_free);
Future<void> sessionWaitForDownload(Session session, [CancellationToken? cancellationToken]) {
final completer = CancellableCompleter<void>(cancellationToken);
if (!completer.isCancelled) {
final callback = Pointer.fromFunction<Void Function(Handle, Pointer<realm_sync_error_code_t>)>(_sessionWaitCompletionCallback);
final userdata = _realmLib.realm_dart_userdata_async_new(completer, callback.cast(), scheduler.handle._pointer);
_realmLib.realm_sync_session_wait_for_download_completion(session.handle._pointer, _realmLib.addresses.realm_dart_sync_wait_for_completion_callback,
userdata.cast(), _realmLib.addresses.realm_dart_userdata_async_free);
}
return completer.future;
}

static void _sessionWaitCompletionCallback(Object userdata, Pointer<realm_sync_error_code_t> errorCode) {
final completer = userdata as Completer<void>;

if (completer.isCompleted) {
return;
}
if (errorCode != nullptr) {
// Throw RealmException instead of RealmError to be recoverable by the user.
// Throw RealmException instead of RealmError to be recoverable by the user.
completer.completeError(RealmException(errorCode.toSyncError().toString()));
} else {
completer.complete();
Expand Down
48 changes: 45 additions & 3 deletions lib/src/realm_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import 'dart:async';
import 'dart:ffi';
import 'dart:io';

import 'package:cancellation_token/cancellation_token.dart';
import 'package:logging/logging.dart';
import 'package:realm_common/realm_common.dart';
import 'package:collection/collection.dart';
import 'package:cancellation_token/cancellation_token.dart';

import 'configuration.dart';
import 'list.dart';
Expand Down Expand Up @@ -61,8 +61,6 @@ export 'package:realm_common/realm_common.dart'
ObjectId,
Uuid;

export 'package:cancellation_token/cancellation_token.dart' show CancellationToken, CancelledException;

// always expose with `show` to explicitly control the public API surface
export 'app.dart' show AppConfiguration, MetadataPersistenceMode, App, AppException;
export "configuration.dart"
Expand All @@ -89,6 +87,7 @@ export 'subscription.dart' show Subscription, SubscriptionSet, SubscriptionSetSt
export 'user.dart' show User, UserState, UserIdentity, ApiKeyClient, ApiKey;
export 'session.dart' show Session, SessionState, ConnectionState, ProgressDirection, ProgressMode, SyncProgress, ConnectionStateChange;
export 'migration.dart' show Migration;
export 'package:cancellation_token/cancellation_token.dart' show CancellationToken, CancelledException;

/// A [Realm] instance represents a `Realm` database.
///
Expand Down Expand Up @@ -120,6 +119,42 @@ class Realm implements Finalizable {
_populateMetadata();
}

/// A method for asynchronously opening a [Realm].
///
/// When the configuration is [FlexibleSyncConfiguration], the realm will be downloaded and fully
/// synchronized with the server prior to the completion of the returned [Future].
/// This method could be called also for opening a local [Realm] with [LocalConfiguration].
desistefanova marked this conversation as resolved.
Show resolved Hide resolved
///
/// * `config`- a configuration object that describes the realm.
/// * `cancellationToken` - an optional [CancellationToken] used to cancel the operation.
/// * `onProgressCallback` - a callback for receiving download progress notifications for synced [Realm]s.
///
/// Returns `Future<Realm>` that completes with the [Realm] once the remote [Realm] is fully synchronized or with a [CancelledException] if operation is canceled.
/// When the configuration is [LocalConfiguration] this completes right after the local [Realm] is opened.
/// Using [open] for opening a local Realm is equivalent to using the constructor of [Realm].
static Future<Realm> open(Configuration config, {CancellationToken? cancellationToken, ProgressCallback? onProgressCallback}) async {
if (cancellationToken != null && cancellationToken.isCancelled) {
throw cancellationToken.exception;
}
final realm = Realm(config);
StreamSubscription<SyncProgress>? subscription;
try {
if (config is FlexibleSyncConfiguration) {
final session = realm.syncSession;
if (onProgressCallback != null) {
subscription = session.getProgressStream(ProgressDirection.download, ProgressMode.forCurrentlyOutstandingWork).listen(onProgressCallback);
}
await session.waitForDownload(cancellationToken);
await subscription?.cancel();
}
} catch (_) {
await subscription?.cancel();
realm.close();
rethrow;
}
return await CancellableFuture.value(realm, cancellationToken);
}

static RealmHandle _openRealm(Configuration config) {
var dir = File(config.path).parent;
if (!dir.existsSync()) {
Expand Down Expand Up @@ -752,3 +787,10 @@ class MigrationRealm extends DynamicRealm {

MigrationRealm._(Realm realm) : super._(realm);
}

/// The signature of a callback that will be executed while the Realm is opened asynchronously with [Realm.open].
/// This is the registered onProgressCallback when calling [open] that receives progress notifications while the download is in progress.
///
/// * syncProgress - an object of [SyncProgress] that contains `transferredBytes` and `transferableBytes`.
/// {@category Realm}
typedef ProgressCallback = void Function(SyncProgress syncProgress);
5 changes: 2 additions & 3 deletions lib/src/session.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import 'dart:async';
import 'dart:ffi';

import '../realm.dart';
import 'native/realm_core.dart';
import 'user.dart';
Expand Down Expand Up @@ -61,7 +60,7 @@ class Session implements Finalizable {
Future<void> waitForUpload() => realmCore.sessionWaitForUpload(this);

/// Waits for the [Session] to finish all pending downloads.
Future<void> waitForDownload() => realmCore.sessionWaitForDownload(this);
Future<void> waitForDownload([CancellationToken? cancellationToken]) => realmCore.sessionWaitForDownload(this, cancellationToken);

/// Gets a [Stream] of [SyncProgress] that can be used to track upload or download progress.
Stream<SyncProgress> getProgressStream(ProgressDirection direction, ProgressMode mode) {
Expand Down Expand Up @@ -204,7 +203,7 @@ class SessionProgressNotificationsController {
}

void _stop() {
if (_token == null) {
if (_token == null || _session._handle.released) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ dependencies:
tar: ^0.5.4
build_runner: ^2.1.0
http: ^0.13.4
cancellation_token: ^1.4.0
cancellation_token: ^1.5.0

dev_dependencies:
build_cli: ^2.2.0
Expand Down
2 changes: 1 addition & 1 deletion test/configuration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ Future<void> main([List<String>? args]) async {

final schema = [Task.schema];
final flexibleSyncConfig = Configuration.flexibleSync(user, schema, path: realmPath);
final realm = Realm(flexibleSyncConfig);
final realm = getRealm(flexibleSyncConfig);
final oid = ObjectId();
realm.subscriptions.update((mutableSubscriptions) {
mutableSubscriptions.add(realm.query<Task>(r'_id == $0', [oid]));
Expand Down
Loading