Comments inline.

On Mon, May 28, 2018 at 2:02 AM, Norman Gaywood <ngayw...@gmail.com> wrote:
> T""his simple program creates a thread to read a directory with dir() and
> place the files on a channel. $N worker threads read that channel and
> "process" (prints) the files. But I'm getting this "An operation first
> awaited:" error.
>
> I've read the traps page about this error several times, but still can't
> make sense of it. Can some explain what's going on here?
>
> The directory contents:
> $ ls
> a  b  c  traverse-dir0.p6
>
> Running the program:
> $ ./traverse-dir0.p6
> traverse-dir0.p6
> a
> b
> c
> An operation first awaited:
>   in sub MAIN at ./traverse-dir0.p6 line 24
>   in block <unit> at ./traverse-dir0.p6 line 5
>
> Died with the exception:
>     Cannot find method 'path': no method cache and no .^find_method
>       in block  at ./traverse-dir0.p6 line 16
>
> The program:
> $ cat traverse-dir0.p6
> #!/usr/bin/env perl6
> # There is a thread to populate $dir-channel by reading filenames in a
> directory with dir()
> # and $N worker threads to read the filenames from the $dir-channel.
>
> sub MAIN( Str $dir = ".", Int :$N = 4 ) {
>
>     my $dir-channel = Channel.new();
>     my $dir-read = start {
>         $dir-channel.send( $_ ) for dir $dir;
>         $dir-channel.close;
>     }
>
>     my @workers = (^$N).map: {
>         start {
>             while my $file = $dir-channel.receive() {
>                 say $file.path;
>             }
>             CATCH {
>                 when X::Channel::ReceiveOnClosed { .resume }

------------------------------

What did you expect to happen if you resumed?

Because I expect it to try to run `say $file.path;` with invalid data.
You can just remove the `.resume` and it works.

------------------------------

>             }
>         }
>     }
>
>     await $dir-read, @workers;
> }

There is no need to await for $dir-read, as the workers won't finish
until it's done anyway.

---

Anyway I would use a `react` block.

    my @workers = (^$N).map: {
        start react whenever $dir-channel -> $file {
            say $file.path;
        }
    }

Note that `start` and `react` don't need {}, but you can use them if neccesary.


    my @workers = (^$N).map: {
        start {
            say 'started';

            react {
                say 'reacting';

                whenever Promise.in(½) { say '½ second has elapsed' }

                whenever $dir-channel -> $file {
                    say $file.path;
                }
            }
        }
    }

Reply via email to