-
Notifications
You must be signed in to change notification settings - Fork 87
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
Cannot Open Realm in Background Isolate #1451
Comments
This documentation explains how to open the file from multiple processes. In your case, you are opening it from the same process from different isolates. In this case, you should open it with the same config as the one you used to open it on the main isolate. Note that due to #1433, that won't work with 1.6.0, so you either need to downgrade or wait until 1.7.0 is released. |
Okay... any idea what the timeframe for 1.7 is? |
I don't imagine it'll land before the holidays, so realistically - the first half of January. |
Any update on this? |
@richard457 Waiting for #1470. I expect us to release this week. |
when this goes to pub.dev? |
@richard457 1.7 is out |
I have tested this out with the following code: static Future handleRealm(List<dynamic> args) async {
final rootIsolateToken = args[0] as RootIsolateToken;
final sendPort = args[1] as SendPort;
final branchId = args[2] as int;
final encryptionKey = args[3] as String;
BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken);
// get isar instances
isar = await isarK();
final app = App.getById(AppSecrets.appId);
final user = app?.currentUser!;
List<int> key = encryptionKey.toIntList();
final config = Configuration.flexibleSync(
user!,
[
RealmITransaction.schema,
RealmITransactionItem.schema,
RealmProduct.schema,
RealmVariant.schema,
RealmStock.schema,
RealmIUnit.schema
],
);
final realm = Realm(config);
// final realm = await Realm.open(config);
// Subscribe to changes for transactions
final iTransactionsCollection =
realm.query<RealmITransaction>(r'branchId == $0', [branchId]);
iTransactionsCollection.changes.listen((changes) async {
for (final result in changes.results) {
final model = createmodel(result);
if (model.action == AppActions.deleted && model.deletedAt == null) {
model.deletedAt = DateTime.now();
}
sendPort.send('data ${model.id}');
}
});
} and Trigered the function like @override
Future<void> pull() async {
RootIsolateToken? rootIsolateToken = RootIsolateToken.instance;
int branchId = ProxyService.box.getBranchId()!;
String key = ProxyService.box.encryptionKey();
ReceivePort receivePort = ReceivePort();
await Isolate.spawn(IsolateHandler.handleRealm, [
rootIsolateToken,
receivePort.sendPort,
branchId,
key,
]);
receivePort.listen((message) {
log('Isolate: $message');
});
} I can confirm that on Windows the above code works but not on Android device, when there is a data change the sendPort.send('data ${model.id}'); is not triggered on android @nielsenko |
@richard457 Remember to hold onto the stream subscription so that you can call final subscription = iTransactionsCollection.changes.listen(...
// and later
await subscription.cancel(); This holds for all streams, not just realm change streams. Otherwise you risk leaking native resources, such as file handles, etc. You can also end up in situations where the subscription is the only thing that prevents the entire stream from being garbage collected. In general I recommend using await for (final t in iTransactionsCollection.changes.listen(...)) {
// dart will ensure subscription is cancelled no matter how you exit from here
} but that is not always possible. Realm actually tries to help mitigate this issue by using weak handles, and while debugging this, I found a bug that I'm fixing as I write this, so stay tuned.. However - after the fix - it becomes even more important to always remember to cancel the stream subscription, as you are otherwise certain to both leak native- and pin dart- resources. |
Thanks, @nielsenko but I find on Android that data changes are not reflected when the connection to the server (flexible sync) is established while on Windows changes are detected automatically, I mean I have two device
|
@richard457 Could you setup logging and tell us what you see? Realm.logger.level = RealmLogLevel.trace; on both windows and android? Also,
|
My model @RealmModel()
class _RealmITransaction {
late String id;
@PrimaryKey()
@MapTo('_id')
late ObjectId realmId;
late String reference;
String? categoryId;
late String transactionNumber;
late int branchId;
late String status;
late String transactionType;
late double subTotal;
late String paymentType;
late double cashReceived;
late double customerChangeDue;
late String createdAt;
} final app = App(AppConfiguration(AppSecrets.appId,
baseUrl: Uri.parse("https://services.cloud.mongodb.com")));
final user = app.currentUser ?? await app.logIn(Credentials.anonymous());
List<int> key = ProxyService.box.encryptionKey().toIntList();
final config = Configuration.flexibleSync(
user,
[
RealmITransaction.schema,
],
// encryptionKey:key,
path: await absolutePath("db_"));
realm = Realm(config); Yes I am able to see data in atlas when data are saved from desktop app. |
And how does your flexible sync subscriptions look? realm.subscriptions.update((ms) {
// what are you subscribing on?
}); .. and what does the logging tell you? |
final transaction =
realm.query<RealmITransaction>(r'branchId == $0', [branchId]);
//https://www.mongodb.com/docs/realm/sdk/flutter/sync/manage-sync-subscriptions/
realm.subscriptions.update((sub) {
sub.clear();
sub.add(transaction, name: "transactions-${branchId}", update: true);
); FYI: I am only doing subscription from main tread not in isolate. I/flutter ( 5150): 2024-01-26T11:23:11.276052: [INFO] Realm: Connection[1]: Session[1]: Binding '/data/user/0/rw.app/app_flutter/app-sync/db_' to ''
I/flutter ( 5150): 2024-01-26T11:23:11.278213: [INFO] Realm: Connection[1]: Session[1]: client_reset_config = false, Realm exists = true
I/flutter ( 5150): 2024-01-26T11:23:11.279519: [INFO] Realm: Connection[1]: Connecting to 'wss://ws.ap-south-1.aws.realm.mongodb.com:443/api/client/v2.0/app/devicesync-ifwtd/realm-sync'
I/flutter ( 5150): 2024-01-26T11:23:11.626326: [INFO] Realm: Connected to endpoint '15.207.151.40:443' (from '10.110.0.187:48752')
I/flutter ( 5150): 2024-01-26T11:23:13.377412: [INFO] Realm: Connection[1]: Connected to app services with request id: "65b37a0123d017c54b8e3f4c"
I/flutter ( 5150): 2024-01-26T11:23:21.771668: [INFO] Realm: Connection[1]: Session[1]: Begin processing pending FLX bootstrap for query version 12. (changesets: 1, original total changeset size: 0)
I/flutter ( 5150): 2024-01-26T11:23:21.783177: [INFO] Realm: Connection[1]: Session[1]: Integrated 1 changesets from pending bootstrap for query version 12, producing client version 159 in 10 ms. 0 changesets remaining in bootstrap |
The code bits I have seen makes me question if you are using the same realm in both the foreground and the background isolate. I see a |
It is okay to setup the subscription(s) in one isolate, and query/observe the realm in another, but it must be backed by the same physical realm file. Try to print the |
Sorry for late reply, I realized that not setting path in isolate was the root cause of the issue. |
What happened?
See #1055 for a similar issue...
I'm trying to follow the doc from here : https://www.mongodb.com/docs/realm/sdk/flutter/sync/sync-multiple-processes/...
The basic instructions from that are to have a single realm using the flexible sync config and then any other workers using a disconnected sync configuration.
I'm trying to do that and am getting the following exception.
RealmException (RealmException: Error opening realm at path /Users/ebenezer/.hh2mobile.realm. Error code: 2013 . Message: Realm at path '/Users/ebenezer/.hh2mobile.realm' already opened with different sync configurations.)
Repro steps
Look at the code in the code snippet below. It does the following
Note that the way the writeRealm is initialized is the same as the issue that I mention in the "What happened?" section except that reporter used a memory config where I'm using a disconnected sync config.
What am I doing wrong?
Version
Dart SDK version: 3.2.3 (stable) (Tue Dec 5 17:58:33 2023 +0000) on "macos_arm64"
What Atlas Services are you using?
Atlas Device Sync
What type of application is this?
Dart standalone application
Client OS and version
macOS Sonoma 14.2
Code snippets
Stacktrace of the exception/crash you're getting
No response
Relevant log output
No response
The text was updated successfully, but these errors were encountered: