spawn static method
- DatabaseOpener opener, {
- bool serialize = false,
- Future<
Isolate> isolateSpawn<T>( - void (
- T
- T
- void (
Creates a new DriftIsolate on a background thread.
The opener
function will be used to open the DatabaseConnection used
by the isolate.
Because opener
will be called on another isolate with its own memory,
it must either be a top-level member or a static class method.
To close the isolate later, use shutdownAll. Or, if you know that only
a single client will connect, set singleClientMode: true
in connect.
That way, the drift isolate will shutdown when the client is closed.
The optional isolateSpawn
parameter can be used to make drift use
something else instead of Isolate.spawn to spawn the isolate. This may
be useful if you want to set additional options on the isolate or
otherwise need a reference to it.
Internally, drift uses ports from dart:isolate
to send commands to an
internal server dispatching database actions.
In most setups, those ports can send and receive almost any Dart object.
In special cases though, the platform only supports sending simple types
across send types. In particular, isolates across different Flutter
engines (such as the ones spawned by the workmanager
package) are
unable to handle most objects.
To support those setups, drift can serialize its iground isolate doing
all the work. Any other isolate can use the connect method to obtain an
instance of a GeneratedDatabase class that will delegate its work onto a
background isolate. Auto-updating queries, and transactions work across
isolates, and the user facing api is exactly the same.
Please note that, while running drift in a background isolate can reduce lags in foreground isolates (thus removing UI jank), the overall database performance will be worse. This is because result data is not available directly and instead needs to be copied from the database isolate. Thanks to recent improvements like isolate groups in the Dart VM, this overhead is fairly small and using isolates to run drift queries is recommended where possible.
The easiest way to use drift isolates is to use
NativeDatabase.createInBackground
, which is a dropternal communication
channel to only send simple types across isolates. The serialize
parameter, which is enabled by default, controls this behavior.
In most scenarios, serialize
can be disabled for a considerable
performance improvement.
Implementation
static Future<DriftIsolate> spawn(
DatabaseOpener opener, {
bool serialize = false,
Future<Isolate> Function<T>(void Function(T), T) isolateSpawn =
Isolate.spawn,
}) async {
final receiveServer = ReceivePort('drift isolate connect');
final keyFuture = receiveServer.first;
await isolateSpawn(_startDriftIsolate, [receiveServer.sendPort, opener]);
final key = await keyFuture as SendPort;
return DriftIsolate.fromConnectPort(key, serialize: serialize);
}