Skip to content

Allow sending synchronous generators via ports(support copying of SuspendState) #51757

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

Open
aam opened this issue Mar 16, 2023 · 2 comments
Open
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.

Comments

@aam
Copy link
Contributor

aam commented Mar 16, 2023

Currently it's impossible to send generator-created stream via ports due to vms inability to serialize SuspendState, but it seems reasonable to expect for it to work, copy sender's state over effectively forking the stream. Receiver will pick up the stream where it was forked.

import 'dart:isolate';

Stream<int> evenNumbersGenerator() async* {
  int i = 2;
  while (true) {
    yield i;
    i += 2;
  }
}

main() async {
  final rp = ReceivePort();
  rp.sendPort.send(evenNumbersGenerator());
  rp.close();
}

fails with

Unhandled exception:
Invalid argument(s): Illegal argument in isolate message: (object is a SuspendState)
 <- Context num_variables: 1
 <- Closure: (Object?) => void (from dart:core)
 <- Instance of '_ControllerStream<int>' (from dart:async)

#0      _SendPort._sendInternal (dart:isolate-patch/isolate_patch.dart:249:43)
#1      _SendPort.send (dart:isolate-patch/isolate_patch.dart:230:5)
#2      main (file:///Users/aam/p/d1/sdk/runtime/tests/vm/dart/send_async_generator.dart:14:15)
#3      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#4      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)

cc @alexmarkov @rmacnak-google

@aam aam added the area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. label Mar 16, 2023
@alexmarkov
Copy link
Contributor

Copying Stream objects when sending them between isolates would not work: listener in another isolate would not be notified when events are generated in the original isolate. It is basically the same reason why sending Future objects to another isolate by copying them doesn't make much sense (the reasoning in #51594 (comment) applies to streams as well).

It is not hard to support sending/copying SuspendState objects within isolate group as we share code between isolates in the same group. We can just clone SuspendState object - see SuspendState::Clone. We can use copying of SuspendState objects to implement sending Iterable objects returned by sync* functions, although it may not be very useful for users as sync* functions are extremely rare.

@aam
Copy link
Contributor Author

aam commented Mar 16, 2023

Sure, changed asyncronous to synchronous.

Repro of problem sending synchronous generators:

import 'dart:isolate';

Iterable<int> evenNumbersGenerator() sync* {
  int i = 2;
  while (true) {
    yield i;
    i += 2;
  }
}

main() async {
  final rp = ReceivePort();
  rp.sendPort.send(evenNumbersGenerator());
  rp.close();
}
Unhandled exception:
Invalid argument(s): Illegal argument in isolate message: (object is a SuspendState)
 <- Instance of '_SyncStarIterable<int>' (from dart:async)

#0      _SendPort._sendInternal (dart:isolate-patch/isolate_patch.dart:249:43)
#1      _SendPort.send (dart:isolate-patch/isolate_patch.dart:230:5)
#2      main (file:///Users/aam/p/d1/sdk/runtime/tests/vm/dart/send_async_generator.dart:13:15)
#3      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#4      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)

@aam aam changed the title Allow sending asynchronous generators via ports(support copying of SuspendState) Allow sending synchronous generators via ports(support copying of SuspendState) Mar 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.
Projects
None yet
Development

No branches or pull requests

2 participants