Skip to content

Feature request: SendPort send done event to ReceivePort #28731

Open
@alsemenov

Description

@alsemenov

According to description of class SendPort, there is no way to close the SendPort instance and signal to bound ReceivePort to generate done event.

Lets consider the following example:

import "dart:async";
import "dart:isolate";

void entryPoint(SendPort sendPort) {
  for (int i in [0,1,2,3,4,5,6,7,8,9]){
    sendPort.send(i);
  }
}

main() async {
  ReceivePort receivePort = new ReceivePort();
  Isolate isolate = await Isolate.spawn(
                                        entryPoint,
                                        receivePort.sendPort);
  receivePort.listen(
      (data) {
        print("received: $data");
      },
      onDone:() {
        print("done");
      }
  );
}

The program is quite simple and easy to understand.
Unfortunately program successfully prints received for all digits, but it never prints done
It is necessary to call receivePort.close() explicitly to trigger the event done and finish the program.
But to prevent data loss, close() must be called only when all data is received.
However detecting the moment, when all data is sent and received might be tricky and error prone.
Here are some options:

  1. Send some special value at the end of the data.
  2. Use isolate onExitListener
  3. Use another pair of SendPort-ReceivePort to send the special value to indicate end of the data

I think that all these options have problems:

  1. It is necessary to modify the essential functionality of the program (aka business logic). In the example we send integers and either have to make some integer value special (i.e. do not use it for business) or change type integer to Object and use some special object like Capability. In all cases we have to modify the sender and receiver and call receivePort.close() explicitly. The program will became less simple and easy to understand.

  2. There is a race condition between isolate terminated event and the business data. Since they are sent via different channels (i.e. SendPort-ReceivePort pairs) the isolate terminated may arrive earlier than last digit, for example, and if we call receivePort.close() then last digit will be lost.

  3. There is a race condition between end of data value and business data. Some data may be lost similar way as in previous point.

The elegant solution would be to introduce method close() in SendPort. The method should signal to bound ReceivePort to generate done event. Therefore no other tricky solutions would be necessary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-core-librarySDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries.core-llibrary-isolatetype-enhancementA request for a change that isn't a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions