On Sat Dec 05 11:13:54 2015, b...@abrij.org wrote: > > 16:18 skids I think the Supply work may have made > $fh.watch.Promise not fire anymore. > 16:20 watch.tap still works. > 16:21 jnthn The semantics of Supply.Promise changed > 16:21 You'll need $fh.watch.head(1).Promise to get the > original ones > 16:21 skids Ah that would explain it. jnthn++ > 16:22 Hrm that doesn't seem to do it though. > 2 more elements. Show/hide. > 16:34 jnthn Hm, head doesn't seem to be filing the "done" > > These work: > > $ perl6 -e 'my $f = Supplier.new; my $s = $f.head(1).Supply; my $t = > $s.tap(-> $ { 42.say }, done => {43.say} ); start { for 0..3 { > $f.emit(42) }; $f.done(); }; await $s.Promise; 44.say; ' > 42 > 43 > 44 > > $ perl6 -e 'my $f = Supplier.new; my $s = $f.head(1).Supply; my $t = > $s.tap(-> $ { 42.say }, done => {43.say} ); start { for 0..3 { > $f.emit(42) }; }; await $s.Promise; 44.say; ' > 42 > 43 > 44 > > > This neither sends a done nor fulfills a .Promise (input echoed into > file from another terminal): > > $ perl6 -e 'my $fh = open("/tmp/foo.txt", :create); my $s = > $fh.watch.head(1); my $t = $s.tap(-> $ { 42.say }, done => {43.say} ); > await $s.Promise; 44.say' > 42 > ^C > This works reliably now, and so could do with a test. Probably thanks to one of the many Supply fixes over the last months.
> ...and when the .head is off a Supply instead of a Supplier, a done > from the original Supply propagates but the Promise never unhooks: > > $ perl6 -e 'my $f = Supplier.new; my $s = $f.Supply.head(1); my $t = > $s.tap(-> $ { 42.say }, done => {43.say} ); start { for 0..3 { > $f.emit(42) }; $f.done(); }; await $s.Promise; 44.say; ' > 42 > 43 > ^C > > $ perl6 -e 'my $f = Supplier.new; my $s = $f.Supply.head(1); my $t = > $s.tap(-> $ { 42.say }, done => {43.say} ); start { for 0..3 { > $f.emit(42) }; }; await $s.Promise; 44.say; ' > 42 > ^C This code is vulnerable to a race condition, thus it sometimes works, sometimes not. If you add a `sleep 1` before the `await` then it reliably hangs. The reason is that a Supplier is a live supply; if you miss the events (emit/done) then they're gone for good. (Note that `.Promise` taps the supply separately from the `.tap` that is already taking place.) For this to reliably work, the `Promise` should be obtained prior to setting off the `start` block. This works reliably, every time: my $f = Supplier.new; my $s = $f.Supply.head(1); my $t = $s.tap(-> $ { 42.say }, done => {43.say} ); my $p = $s.Promise; start { for 0..3 { $f.emit(42) }; $f.done(); } await $p; 44.say; Tagging testneeded for the part that deserves a test. /jnthn