Non Blocking Channel Operations in Dart

Our first program will demonstrate non-blocking channel operations. Here’s the full source code:

import 'dart:async';

void main() async {
  final messages = StreamController<String>();
  final signals = StreamController<bool>();

  // Here's a non-blocking receive. If a value is
  // available on `messages` then it will be processed
  // immediately. If not, it will move on to the next line.
  messages.stream.first.then((msg) {
    print('received message $msg');
  }).catchError((error) {
    if (error is StateError) {
      print('no message received');
    }
  });

  // A non-blocking send works similarly. Here `msg`
  // is added to the `messages` stream without blocking.
  final msg = 'hi';
  messages.add(msg);
  print('sent message $msg');

  // We can use multiple streams to implement a multi-way
  // non-blocking select. Here we attempt non-blocking receives
  // on both `messages` and `signals`.
  await Future.any([
    messages.stream.first.then((msg) {
      print('received message $msg');
    }),
    signals.stream.first.then((sig) {
      print('received signal $sig');
    })
  ]).timeout(Duration(seconds: 1), onTimeout: () {
    print('no activity');
  });

  // Clean up
  await messages.close();
  await signals.close();
}

To run the program, save it as non_blocking_channel_operations.dart and use dart run.

$ dart run non_blocking_channel_operations.dart
sent message hi
received message hi
no activity

In this Dart example, we use StreamController and Stream to simulate channels. The StreamController allows us to add values to the stream, while the Stream allows us to listen for values.

For non-blocking operations, we use the first property of the stream along with then and catchError to handle the case when no value is available.

The multi-way non-blocking select is implemented using Future.any, which completes when any of the given futures complete. We use timeout to simulate the default case when no value is received within a certain time.

Note that Dart’s asynchronous model is different from Go’s, so the behavior might not be exactly the same, but this example demonstrates similar non-blocking concepts.