Replies: 1 comment 2 replies
-
Managed to get it working initially, for one execution, with the following code that uses a separate isolate to sendPort(passing DriftIsolate fails with Isolate.spawn): @pragma('vm:entry-point')
Future<void> isolateEntryPoint(int objectId, RootIsolateToken? token) async {
var usesLocalConnection = false;
late final DriftIsolate driftIsolate;
DatabaseConnection? databaseConnection;
late final LocalDatabaseRepository localDataBaseRepository;
Future<void> terminateIsolate() async {
IsolateNameServer.removePortNameMapping(objectId.toString());
if (!usesLocalConnection) {
await driftIsolate.shutdownAll();
}
debugPrint('Isolate terminated');
Isolate.current.kill();
}
final receivePort = ReceivePort();
IsolateNameServer.registerPortWithName(
receivePort.sendPort,
objectId.toString(),
);
final completer = Completer<SendPort>();
debugPrint('checking token');
if (token == null) {
await terminateIsolate();
return;
}
receivePort.listen((message) {
if (message is SendPort) {
debugPrint('received drift isolate');
completer.complete(message);
return;
}
debugPrint('objectManagerService: $message');
});
final sendPortLocalDrift =
IsolateNameServer.lookupPortByName('localDriftDbIsolate');
if (sendPortLocalDrift != null) {
debugPrint('sending object id to locla drift isolate');
sendPortLocalDrift.send('object:$objectId');
await Future<void>.delayed(const Duration(milliseconds: 200));
}
if (completer.isCompleted) {
debugPrint('connection isolate received from local drift isolate');
usesLocalConnection = true;
driftIsolate = DriftIsolate.fromConnectPort(await completer.future);
} else {
debugPrint(
'no response from drift isolate, continuing with new connection',
);
driftIsolate = DriftIsolate.inCurrent(
() {
BackgroundIsolateBinaryMessenger.ensureInitialized(token);
return openConnection();
},
);
}
databaseConnection = await driftIsolate.connect(isolateDebugLog: true);
localDataBaseRepository = LocalDatabaseRepositoryDriftImpl.createWithDb(
driftLocalDatabase: DriftLocalDatabase(databaseConnection),
);
final objectManagerService =
objectManagerServiceAndroid(database: localDataBaseRepository);
await objectManagerService.changeobjectStatus(objectId: objectId, status: false);
debugPrint('stats changed');
await terminateIsolate();
}
@pragma('vm:entry-point')
void printHello(int objectId) {
final token = RootIsolateToken.instance;
Isolate.spawn((message) => isolateEntryPoint(objectId, token), null);
} However now, it hangs here on the second execution: databaseConnection = await driftIsolate.connect(isolateDebugLog: true); any ideas? Edit: Corrected the line that's hanging |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hello there,
Hope you're doing well.
So I've got a small issue where I'm trying to modify the DB from a background isolate, I can confirm the changes occur as when I switch widget(trigger a stream creation), the data is there and changed, but it doesn't happen synchronously. This is the code I'm using:
printHello can be invoked while the app is in the background or when it's in the foreground.
I need the sync when the app is in the foreground for the UI, so for that I thought I could create an isolate to which the isolate above send a message like "give me the serialized connection" to use the same connection as the DB. It would create its own connection if no response is sent. Only thing is I'm wondering if there is an easier way to achieve this with drift existing API. Thank you in advance.
Beta Was this translation helpful? Give feedback.
All reactions