dart-archive / isolate

Makes working with Dart isolates easier.
https://pub.dev/packages/isolate
BSD 3-Clause "New" or "Revised" License
90 stars 34 forks source link

Add LoadBalancer.errors stream #24

Closed lexaknyazev closed 3 years ago

lexaknyazev commented 6 years ago

A simple implementation of #23 (basically a port of IsolateRunner.errors).

LoadBalancer class lacks unit tests, so it might be reasonable to add some before merging.

lrhn commented 5 years ago

I'd prefer to not have special-casing for isolate runners inside the LoadBalancer class.

I'd rather make an error handling wrapper for isolate runners in general, then you can capture the errors of all the isolate runners before passing them to the LoadBalancer constructor.

lexaknyazev commented 5 years ago

OK, I'll update the PR this week.

lexaknyazev commented 5 years ago

an error handling wrapper for isolate runners in general

After looking at LoadBalancer and IsolateRunner public interfaces, I'm not sure how this wrapper should look like.

In a case when a LoadBalancer is created with a set of pre-existing IsolateRunners, there's no need for an additional wrapper because each IsolateRunner exposes its own .errors stream.

final isolateRunners =
    await Future.wait(Iterable.generate(16, (_) => IsolateRunner.spawn()));

for (final isolateRunner in isolateRunners) {
  // subscribe to error streams  
}

final balancer = LoadBalancer(isolateRunners);

On the other hand, when a LoadBalancer is created with a static create method, individual runners cannot be accessed from the outside, so there's no way to subscribe to their error streams.

So I can think of a few options on how to go forward from here.

lrhn commented 4 years ago

What I would do is to make a create function wrapper so that you can intercept the created runners. For example:

Future<Runner> createIsolateRunner(void whenCreated(IsolateRunner runner)) async {
  var runner = await IsolateRunner.spawn();
  whenCreated(runner);
  return runner;
}

Then you can collect errors by doing:

var poolUncaughtErrors = StreamController();
var pool = await LoadBalancer.create(createIsolateRunner((runner) {
   runner.isolate.errors.forEach(errors.add);
});
lrhn commented 3 years ago

Nor planning on using this approach.