Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

duplicate triggers of .act when using parallel greps on an IO::Notification.watch_path supply #4489

Open
p6rt opened this issue Aug 26, 2015 · 5 comments

Comments

@p6rt
Copy link

@p6rt p6rt commented Aug 26, 2015

Migrated from rt.perl.org#125908 (status was 'open')

Searchable as RT125908$

@p6rt
Copy link
Author

@p6rt p6rt commented Aug 26, 2015

From muraiki@pair.com

When two greps are used in parallel on one supply produced by
IO​::Notification.watch_path, greps that match are triggered twice. Run
the following code, then in the same directory `touch watchfile`. Note
that I'm also using unique to filter things, as touching a file produces
a number of FileChanged events.

  my $paths = IO​::Notification.watch_path('.')\
  .grep(*.event.isa(FileChangeEvent​::FileChanged))\
  .unique(​:as(*.path), :expires(5))\
  .map(*.path);

  my $watch = $paths.grep(* ~~ /watchfile/)\
  .act(-> $x {
  say "got file change​: " ~ $x.perl;
  });

  my $never = $paths.grep(* ~~ /shouldneverexecute/)\
  .act(-> $x {
  say "should never execute​: " ~ $x.perl;
  });

  sleep;

Output​:

  got file change​: "watchfile"
  got file change​: "watchfile"

The expected output should be only a single line, not two. I also
noticed that each additional grep I add to the supply yields an
additional line of the same output.

I tried this with a plain supply and could not reproduce the problem​:

  my $s = Supply.new();

  my $watch = $s.grep(* ~~ /1/)\
  .act(-> $x {
  say "got one";
  });

  my $never = $s.grep(* ~~ /shouldneverexecute/)\
  .act(-> $x {
  say "should never execute";
  });

  $s.emit(1);
  $s.emit(2);

  sleep;

This outputs "got one" a single time, as expected.

Perl6 version info​: 2015.07.1-161-gf7cfe9d built on MoarVM version
2015.07-57-gec051f5

Loading

@p6rt
Copy link
Author

@p6rt p6rt commented Nov 3, 2015

From muraiki@pair.com

A better description for this bug, now that I have a better idea of what
is going on, is "two acts on one supply cause each act to be evaluated
twice". :)

In Reactive Extensions with cold observables, I could see this
occurring. But it isn't clear to me from the concurrency design document
that this is intended to be the case in Perl 6.

Loading

@p6rt
Copy link
Author

@p6rt p6rt commented Nov 3, 2015

From andrew@egeler.us

On Wed Aug 26 08​:19​:35 2015, muraiki@​pair.com wrote​:

When two greps are used in parallel on one supply produced by
IO​::Notification.watch_path, greps that match are triggered twice. Run
the following code, then in the same directory `touch watchfile`. Note
that I'm also using unique to filter things, as touching a file produces
a number of FileChanged events.

my $paths = IO​::Notification\.watch\_path\('\.'\)\\
     \.grep\(\*\.event\.isa\(FileChangeEvent​::FileChanged\)\)\\
     \.unique\(​:as\(\*\.path\), :expires\(5\)\)\\
     \.map\(\*\.path\);

my $watch = $paths\.grep\(\* ~~ /watchfile/\)\\
     \.act\(\-> $x \{
         say "got file change​: " ~ $x\.perl;
     \}\);

my $never = $paths\.grep\(\* ~~ /shouldneverexecute/\)\\
     \.act\(\-> $x \{
         say "should never execute​: " ~ $x\.perl;
     \}\);

sleep;

Output​:

got file change​: "watchfile"
got file change​: "watchfile"

The expected output should be only a single line, not two. I also
noticed that each additional grep I add to the supply yields an
additional line of the same output.

I tried this with a plain supply and could not reproduce the problem​:

my $s = Supply\.new\(\);

my $watch = $s\.grep\(\* ~~ /1/\)\\
     \.act\(\-> $x \{
         say "got one";
     \}\);

my $never = $s\.grep\(\* ~~ /shouldneverexecute/\)\\
     \.act\(\-> $x \{
         say "should never execute";
     \}\);

$s\.emit\(1\);
$s\.emit\(2\);

sleep;

This outputs "got one" a single time, as expected.

Perl6 version info​: 2015.07.1-161-gf7cfe9d built on MoarVM version
2015.07-57-gec051f5

I think this is a bug in Supply.unique​:

22​:38 retupmoca m​: my $s = Supply.new; my $s2 = $s.unique(​:as({$_}), :expires(5)); $s2.act({say $_}); $s.emit(1); $s2.act({ say $_ * 2}); $s.emit(2); # re​: #​125908
22​:38 camelia rakudo-moar 273e89​: OUTPUT«1␤2␤4␤2␤4␤»
22​:38 retupmoca looks like a bug in unique?

Loading

@p6rt
Copy link
Author

@p6rt p6rt commented Nov 3, 2015

The RT System itself - Status changed from 'new' to 'open'

Loading

@p6rt
Copy link
Author

@p6rt p6rt commented Jun 23, 2018

From @dogbert17

On Tue, 03 Nov 2015 08​:54​:16 -0800, root+bitcard@​retupmoca.com wrote​:

On Wed Aug 26 08​:19​:35 2015, muraiki@​pair.com wrote​:

When two greps are used in parallel on one supply produced by
IO​::Notification.watch_path, greps that match are triggered twice.
Run
the following code, then in the same directory `touch watchfile`.
Note
that I'm also using unique to filter things, as touching a file
produces
a number of FileChanged events.

my $paths = IO​::Notification.watch_path('.')\
.grep(*.event.isa(FileChangeEvent​::FileChanged))\
.unique(​:as(*.path), :expires(5))\
.map(*.path);

my $watch = $paths.grep(* ~~ /watchfile/)\
.act(-> $x {
say "got file change​: " ~ $x.perl;
});

my $never = $paths.grep(* ~~ /shouldneverexecute/)\
.act(-> $x {
say "should never execute​: " ~ $x.perl;
});

sleep;

Output​:

got file change​: "watchfile"
got file change​: "watchfile"

The expected output should be only a single line, not two. I also
noticed that each additional grep I add to the supply yields an
additional line of the same output.

I tried this with a plain supply and could not reproduce the problem​:

my $s = Supply.new();

my $watch = $s.grep(* ~~ /1/)\
.act(-> $x {
say "got one";
});

my $never = $s.grep(* ~~ /shouldneverexecute/)\
.act(-> $x {
say "should never execute";
});

$s.emit(1);
$s.emit(2);

sleep;

This outputs "got one" a single time, as expected.

Perl6 version info​: 2015.07.1-161-gf7cfe9d built on MoarVM version
2015.07-57-gec051f5

I think this is a bug in Supply.unique​:

22​:38 retupmoca m​: my $s = Supply.new; my $s2 =
$s.unique(​:as({$_}), :expires(5)); $s2.act({say $_}); $s.emit(1);
$s2.act({ say $_ * 2}); $s.emit(2); # re​: #​125908
22​:38 camelia rakudo-moar 273e89​: OUTPUT«1␤2␤4␤2␤4␤»
22​:38 retupmoca looks like a bug in unique?

$ perl6 -v
This is Rakudo version 2018.06-24-gc441d8d built on MoarVM version 2018.06
implementing Perl 6.c.

tried the original code example and it now only produces one event, i.e.

got file change​: "watchfile"

It was suspected that the real problem was a bug in Supply.unique, and the
given example seems to confirm that. However, a lot of water have flowed under
the bridges since then and it seems as if the problem in 'unique' has been fixed.

I tried the following​:

perl6 -e 'my $x = Supplier.new; my $s = $x.Supply; my $s2 = $s.unique(​:as({$_}), :expires(5)); $s2.act({say $_}); $x.emit(1); $s2.act({ say $_ * 2}); $x.emit(2);'
1
2
4

Had to rewrite the example since the api for supplies has changed since the
original bug report.

Should possibly be marked as TESTNEEDED

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant