Re: An operation first awaited

2018-05-28 Thread Norman Gaywood
I've moved this question to stackoverflow

https://stackoverflow.com/questions/50573586/perl6-an-operation-first-awaited

More comments inline below.

On Tue, 29 May 2018 at 01:40, Brad Gilbert  wrote:

> .
> > An operation first awaited:
> >   in sub MAIN at ./traverse-dir0.p6 line 24
> >   in block  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
>
>

> > 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.
>

Hmm, I was expecting the resume to make  $dir-channel.receive() fail and
hence the loop

 while my $file = $dir-channel.receive()

to finish. That is control would not move to inside the while() loop.

It seems not :-( I'll need to get my head around what is happening.

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

Yep :-)


>
> ---
>
> Anyway I would use a `react` block.
>

Nice, I'll work on this. Thanks.

My original intention was to rewrite my code with "back-pressure" on the dir()
read thread.

And then I got stuck on this error I'm posting about :-(



> 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;
> }
> }
> }
> }
>


Re: An operation first awaited

2018-05-28 Thread Norman Gaywood
On Mon, 28 May 2018 at 17:24, JJ Merelo  wrote:

> Hi
>
> El lun., 28 may. 2018 a las 9:04, Norman Gaywood ()
> escribió:
>
>> 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  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;
>>
> You are repeatedly closing the channel here. That accounts for the error.
> If you comment that out, it will just get stuck, but that's a different
> problem
>

If I comment out the channel.close then the worker threads will get wait
forever on the channel.
I don't see how I am repeatedly closing the channel. The "for dir
$dir"  should run until the dir is exhausted and then close the
channel
(once).


> JJ
> PS: It would be great if you would post this question to StackOverflow
> too, you will get lots of knowlegeable answers and it will easy for
> everyone to find the answer there afterwards.
>

Good idea. I should use StackOverflow more:
https://stackoverflow.com/questions/50573586/perl6-an-operation-first-awaited


Re: An operation first awaited

2018-05-28 Thread Brad Gilbert
Comments inline.

On Mon, May 28, 2018 at 2:02 AM, Norman Gaywood  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  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;
}
}
}
}


Re: An operation first awaited

2018-05-28 Thread JJ Merelo
Hi

El lun., 28 may. 2018 a las 9:04, Norman Gaywood ()
escribió:

> 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  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;
>
You are repeatedly closing the channel here. That accounts for the error.
If you comment that out, it will just get stuck, but that's a different
problem

JJ
PS: It would be great if you would post this question to StackOverflow too,
you will get lots of knowlegeable answers and it will easy for everyone to
find the answer there afterwards.


An operation first awaited

2018-05-28 Thread Norman Gaywood
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  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 }
}
}
}

await $dir-read, @workers;
}