My intention is to have different threads reading simultaneously from a single channel, and processing things asynchronously. I thought this would do the trick:
my Channel $KXGA .= new;
for ^100 {
$KXGA.send( (100000..200000).pick );
}
my $sums = start react whenever $KXGA -> $number {
say "In thread ", $*THREAD.id;
say "→ ", (^$number).sum;
}
(this hangs up because I'm not closing the channel, but please don't look at that). This outputs, whatever I do:
In thread 4
→ 6995966328
In thread 4
→ 12323793510
In thread 4
→ 5473561506
So it's always using a single thread and processing things sequentially, and not in parallel. Is there some way of doing that? Even if I start
the thread within the whenever
block, the result will be exactly the same...
The react
/whenever
construct is intended for processing one message at a time and in full. The point is that state held within the react
block is safe thanks to this.
It's possible to have multiple workers reading from a Channel
; they'll just need setting up as follows:
my @sums;
for ^4 {
push @sums, start react whenever $KXGA -> $number {
say "In thread ", $*THREAD.id;
say "→ ", (^$number).sum;
}
}
This react
approach, when used with use v6.d.PREVIEW
, has the advantage that when there's less work, it won't actually occupy 4 threads at all, and they can get on with other pooled work. If instead the whole application is just processing stuff from the Channel
and that's all, you'll have less overhead and better locality with just:
my @sums;
for ^4 {
push @sums, start for $KXGA.list -> $number {
say "In thread ", $*THREAD.id;
say "→ ", (^$number).sum;
}
}
Unlike with react
there's no opportunity to react to different data sources in this approach (the reason Channel
s work with react
is primarily so you can consume them and simultaneously work with async data sources too, or perhaps deal with multiple channels at once). But if you don't need to, then the for
way is a tad simpler in the code and is almost certainly faster (and, as with react
, the loops compete over the items in the Channel
and terminate gracefully when it is closed).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With