Advice for the use of isolates #2957
-
Hello. Our app has been working quite well, but a few of our customers are unfortunately experiencing some pretty poor performance. Without boring you with any of the details, our Drift database has around 70 tables. Many parts of the UI are built using There is a second isolate running in the background, which is responsible for synchronizing data with the server (specifically uploading, the UI does not have to change as a result of these uploads). Currently, I am creating the Drift database in the background, registering its port in the static Future<QueryExecutor> _getBackgroundExecutor(File file) async {
// Either get the existing connect port, or create a new connection
final existingPort = IsolateNameServer.lookupPortByName(databaseIsolate);
if (existingPort != null) {
// We can connect to the existing database isolate!
return DriftIsolate.fromConnectPort(existingPort).connect();
} else {
// We need to spawn a new isolate and register it
final isolate = DriftIsolate.inCurrent(() => NativeDatabase(file));
IsolateNameServer.registerPortWithName(
isolate.connectPort,
databaseIsolate,
);
return isolate.connect();
}
} Which works great in terms of stability, but seems to be lacking in performance. In practice, my background isolate gets a message sent to it whenever there is data to upload, so it's not a requirement to share the connection. Practically, when I directly use QuestionMy question (inquiry?) then, is as follows: what way would you recommend me to set up the database connections in this case? Should my background isolate just use an entirely separate connection to the database file? Or is it sensible to spawn this third isolate for common use? Could the use of a So what I have:
Sorry if it's a bit vague, but I'm curious to know what the recommended way to set up something like this is. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
When using drift isolates, there is a slowdown due to the asynchronous communication channels used to issue database requests. So operations take longer in total, but the actual time spent synchronously processing them on the isolate accessing the database is lower. That makes them a good choice for UIs which are typically asynchronous to begin with, and also more susceptible to lag caused by blocking IO. As you've seen, this model is not a good fit for work already happening on a background isolate. We're not blocking the UI here, so we can afford synchronous database IO and avoid the communication overhead. Opening a second database connection is fine, but opens you up to concurrency issues (not threatening correctness, but possibly causing "database is locked" errors). The easiest part is if the background isolate is not doing any writes at all. In that case, just enable WAL mode so that writes made in the UI don't block background reads and you can safely open a second connection.
Be aware that transactions in a |
Beta Was this translation helpful? Give feedback.
When using drift isolates, there is a slowdown due to the asynchronous communication channels used to issue database requests. So operations take longer in total, but the actual time spent synchronously processing them on the isolate accessing the database is lower. That makes them a good choice for UIs which are typically asynchronous to begin with, and also more susceptible to lag caused by blocking IO.
As you've seen, this model is not a good fit for work already happening on a background isolate. We're not blocking the UI here, so we can afford synchronous database IO and avoid the communication overhead. Opening a second database connection is fine, but opens you up to concurrency is…