-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce a new, simpler way to open long-living isolates #53877
Comments
Check Streams are less trivial, not because they're much harder, there are just more options, more choices, when it comes to communicating back and forth. |
Makes sense there would be a But moreover, that class is equivalent to just saying
|
It still works. It creates a "Runner", which means you can send any |
I see. But it hinges on the request --> response mechanism (which, admittedly, my first proposal does as well), but I'm more interested in the two isolates acting asynchronously. For example, my use case is a main isolate spawning a bunch of worker isolates to perform heavy IO. The worker isolates do their work on their own schedule and send their results back to the main isolate when ready. However the main isolate can request a worker to change its parameters, so I need 2-way communication. The request/response scheme wouldn't work because the workers are always working and sending responses over the lifetime of the application. I ended up making my own code that does this, built on type-safe ports. EDIT I published /// Sends integer n to the child isolate, receives a string back
class NumberSender extends IsolateParent<int, String> {
@override
Future<void> run() async {
print("Opening parent...");
print("Sending: 1");
sendPort.send(1);
await Future<void>.delayed(const Duration(seconds: 1));
print("Sending: 2");
sendPort.send(2);
await Future<void>.delayed(const Duration(seconds: 1));
print("Sending: 3");
sendPort.send(3);
await Future<void>.delayed(const Duration(seconds: 1));
close();
}
@override
void onData(String str) => print("Got: $str");
}
/// Receives integer n, sends "[n]" back
class NumberConverter extends IsolateChild<String, int> {
@override
void run() => print("Opening child...");
@override
void onData(int data) => send("[$data]");
}
void main() async {
final parent = NumberSender();
final child = NumberConverter();
await parent.spawn(child);
parent.run();
} Output:
|
I've published |
Consider this example of long-living isolates. Right now the standard practice is to:
This effectively allows for 2-way communication, but it gets pretty messy and has a lot of boilerplate for something that should be simple. In particular, it also clogs up the "listen for responses" part of the code, which now has to separate real responses from the initial "here's my
SendPort
" message.Or, here's an even simpler API:
Now opening an isolate and having 2-way communications is easy!
If typed send and receive ports are implemented (#3432), then this could also be done like:
which would be implemented as:
This would have the advantage of both sides choosing when to send messages, instead of the above request-response format. An idea from @abitofevrything is to make
IsolateManager
implementSink<S>
andStream<R>
directly.The text was updated successfully, but these errors were encountered: