mirror of https://github.com/AMT-Cheif/drift.git
Proper api to terminate a MoorIsolate
This commit is contained in:
parent
44cb7c0503
commit
e3d3bcd99e
|
@ -1,6 +1,8 @@
|
|||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
|
||||
import 'package:pedantic/pedantic.dart';
|
||||
|
||||
/// An isolate communication setup where there's a single "server" isolate that
|
||||
/// communicates with a varying amount of "client" isolates.
|
||||
///
|
||||
|
@ -46,7 +48,12 @@ class IsolateCommunication {
|
|||
|
||||
final response = (await stream.first) as _ServerConnectionResponse;
|
||||
|
||||
return IsolateCommunication._(response.sendPort, stream, debugLog);
|
||||
final communication =
|
||||
IsolateCommunication._(response.sendPort, stream, debugLog);
|
||||
|
||||
unawaited(communication.closed.then((_) => clientReceive.close()));
|
||||
|
||||
return communication;
|
||||
}
|
||||
|
||||
/// Closes the connection to the server.
|
||||
|
@ -183,6 +190,10 @@ class Server {
|
|||
void close() {
|
||||
_openConnectionPort.close();
|
||||
_opened.close();
|
||||
|
||||
for (var connected in currentChannels) {
|
||||
connected.close();
|
||||
}
|
||||
}
|
||||
|
||||
void _handleMessageOnConnectionPort(dynamic message) {
|
||||
|
@ -199,6 +210,7 @@ class Server {
|
|||
|
||||
communication.closed.whenComplete(() {
|
||||
currentChannels.remove(communication);
|
||||
receiveFromClient.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:isolate';
|
|||
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:moor/src/runtime/executor/stream_queries.dart';
|
||||
import 'package:pedantic/pedantic.dart';
|
||||
import 'communication.dart';
|
||||
|
||||
part 'client.dart';
|
||||
|
@ -33,9 +34,7 @@ class MoorIsolate {
|
|||
/// Identifier for the server isolate that we can connect to.
|
||||
final ServerKey _server;
|
||||
|
||||
final Isolate _isolate;
|
||||
|
||||
MoorIsolate._(this._server, this._isolate);
|
||||
MoorIsolate._(this._server);
|
||||
|
||||
/// Connects to this [MoorIsolate] from another isolate. All operations on the
|
||||
/// returned [DatabaseConnection] will be executed on a background isolate.
|
||||
|
@ -45,6 +44,21 @@ class MoorIsolate {
|
|||
return client._connection;
|
||||
}
|
||||
|
||||
/// Stops the background isolate and disconnects all [DatabaseConnection]s
|
||||
/// created.
|
||||
/// If you only want to disconnect a database connection created via
|
||||
/// [connect], use [GeneratedDatabase.close] instead.
|
||||
Future<void> shutdownAll() async {
|
||||
final connection = await IsolateCommunication.connectAsClient(_server);
|
||||
unawaited(connection.request(_NoArgsRequest.terminateAll).then((_) {},
|
||||
onError: (_) {
|
||||
// the background isolate is closed before it gets a chance to reply
|
||||
// to the terminateAll request. Ignore the error
|
||||
}));
|
||||
|
||||
await connection.closed;
|
||||
}
|
||||
|
||||
/// Creates a new [MoorIsolate] on a background thread.
|
||||
///
|
||||
/// The [opener] function will be used to open the [DatabaseConnection] used
|
||||
|
@ -58,10 +72,9 @@ class MoorIsolate {
|
|||
final receiveServer = ReceivePort();
|
||||
final keyFuture = receiveServer.first;
|
||||
|
||||
final isolate = await Isolate.spawn(
|
||||
_startMoorIsolate, [receiveServer.sendPort, opener]);
|
||||
await Isolate.spawn(_startMoorIsolate, [receiveServer.sendPort, opener]);
|
||||
final key = await keyFuture as ServerKey;
|
||||
return MoorIsolate._(key, isolate);
|
||||
return MoorIsolate._(key);
|
||||
}
|
||||
|
||||
/// Creates a [MoorIsolate] in the [Isolate.current] isolate. The returned
|
||||
|
@ -70,7 +83,7 @@ class MoorIsolate {
|
|||
/// connection which operations are all executed on this isolate.
|
||||
static MoorIsolate inCurrent(DatabaseOpener opener) {
|
||||
final server = _MoorServer(opener);
|
||||
return MoorIsolate._(server.key, Isolate.current);
|
||||
return MoorIsolate._(server.key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@ enum _NoArgsRequest {
|
|||
/// integer, which serves as an identifier for the transaction in
|
||||
/// [_ExecuteQuery.transactionId].
|
||||
startTransaction,
|
||||
|
||||
/// Close the background isolate, disconnect all clients, release all
|
||||
/// associated resources
|
||||
terminateAll,
|
||||
}
|
||||
|
||||
enum _StatementMethod {
|
||||
|
|
|
@ -37,6 +37,10 @@ class _MoorServer {
|
|||
return connection.executor.ensureOpen();
|
||||
case _NoArgsRequest.startTransaction:
|
||||
return _spawnTransaction();
|
||||
case _NoArgsRequest.terminateAll:
|
||||
server.close();
|
||||
Isolate.current.kill();
|
||||
break;
|
||||
// the following are requests which are handled on the client side
|
||||
case _NoArgsRequest.runOnCreate:
|
||||
throw UnsupportedError(
|
||||
|
|
|
@ -11,12 +11,12 @@ void main() {
|
|||
|
||||
setUp(() async {
|
||||
isolate = await MoorIsolate.spawn(_backgroundConnection);
|
||||
isolateConnection = await isolate.connect(isolateDebugLog: true);
|
||||
isolateConnection = await isolate.connect(isolateDebugLog: false);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
isolateConnection.executor.close();
|
||||
isolate.kill();
|
||||
return isolate.shutdownAll();
|
||||
});
|
||||
|
||||
test('can open database and send requests', () async {
|
||||
|
|
Loading…
Reference in New Issue