I have a piece of code that spawns x number of Isolates that are all running http servers. After starting the isolates my main application exits however. When testing I added the while(true) block as seen below, with an async await so the CPU doesn't run berserk. I totally forgot about it until months later when reviewing the code. It seems kind of unnecessary, although I could potentially add a kill-switch for all isolates, but it begs the question; how would I go about waiting for isolates to die off before exiting? As it is now, that while loop is keeping the entire application alive.
main() async {
Server http_server = Server(80, 3);
http_server.start();
while(true) {
await Future.delayed(Duration(seconds: 1));
}
}
CodePudding user response:
You should create a ReceivePort
and then send a SendPort
instance from this as argument to your Isolate
instances (either create one ReceivePort
for each Isolate
or reuse the same depending on the amount of detail you want). By doing so, you can send data back to your main-isolate and your main-isolate will not stop because it has an open ReceivePort
which prevents the isolate from stopping.
You can then e.g. make it so your HTTP servers can ask for the whole server to turn off. Or, you can just keep a ReceivePort
instance open which will prevent the main isolate from stopping and without busy waiting (in that case, you don't need to send the SendPort
instance into your isolates. Dart does not keep track of when ReceivePort
should be closed, so you must manually close it when you think it is done).
Example:
import 'dart:async';
import 'dart:isolate';
void main() {
ReceivePort receivePort = ReceivePort();
receivePort.listen((message) {
print('Got: $message');
if (message == 'Goodbye') {
print('Close ReceivePort and therefore also the program since '
'nothing else are running that could trigger an event.');
receivePort.close();
}
});
Isolate.spawn(myIsolate, receivePort.sendPort);
}
void myIsolate(SendPort msg) {
print('Running inside isolate. Wait 5 seconds before sending message back');
Timer(const Duration(seconds: 5), () => msg.send('Goodbye'));
}