print sth every second, and also sleep 10 seconds very 5 seconds using react … whenever in Perl 6?










12















I want to print the current time every second, and also want to sleep 10 seconds very 5 seconds:



react 
whenever Supply.interval(1)
say DateTime.now.posix;


whenever Supply.interval(5)
sleep 10;
say 'Sleep Done';


whenever signal(SIGINT)
say "Done.";
done;




the output is not what i wanted:



1542371045
Sleep Done
1542371055
Sleep Done
1542371065
Sleep Done
1542371075
Done.
...


what i want is this:



1542371045
1542371046
1542371047
1542371048
1542371049
Sleep Done
1542371059
1542371060
1542371061
1542371062
1542371063
Sleep Done
Done.


Don't know much about Promise, Supply... about Perl 6, is this possible?










share|improve this question



















  • 1





    Should the time reports each second continue to be made during that 10 seconds break? Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds?

    – Jonathan Worthington
    Nov 16 '18 at 10:35











  • I think the basic misunderstanding is that only one whenever block will be executing at a time. This is actually underdocumented, so I will have a stab at that.

    – Elizabeth Mattijsen
    Nov 16 '18 at 11:33











  • @JonathanWorthington thanks for your attention. 1,Should the time reports each second continue to be made during that 10 seconds break? No, duration the 10 seconds break, I don't want it to continue report the time. 2,Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds? yes.

    – chenyf
    Nov 16 '18 at 12:23











  • if you don't want it to report while it's sleeping, it sleeps for 10 seconds each time, and you want it to report that it finished sleeping every 5 seconds, that means that at any time two 10-second sleeps are active, and the time should never be reported at all; am i misunderstanding?

    – timotimo
    Nov 16 '18 at 12:57











  • @timotimo yes, you are right. when sleep, it doesn't report time.

    – chenyf
    Nov 16 '18 at 14:27















12















I want to print the current time every second, and also want to sleep 10 seconds very 5 seconds:



react 
whenever Supply.interval(1)
say DateTime.now.posix;


whenever Supply.interval(5)
sleep 10;
say 'Sleep Done';


whenever signal(SIGINT)
say "Done.";
done;




the output is not what i wanted:



1542371045
Sleep Done
1542371055
Sleep Done
1542371065
Sleep Done
1542371075
Done.
...


what i want is this:



1542371045
1542371046
1542371047
1542371048
1542371049
Sleep Done
1542371059
1542371060
1542371061
1542371062
1542371063
Sleep Done
Done.


Don't know much about Promise, Supply... about Perl 6, is this possible?










share|improve this question



















  • 1





    Should the time reports each second continue to be made during that 10 seconds break? Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds?

    – Jonathan Worthington
    Nov 16 '18 at 10:35











  • I think the basic misunderstanding is that only one whenever block will be executing at a time. This is actually underdocumented, so I will have a stab at that.

    – Elizabeth Mattijsen
    Nov 16 '18 at 11:33











  • @JonathanWorthington thanks for your attention. 1,Should the time reports each second continue to be made during that 10 seconds break? No, duration the 10 seconds break, I don't want it to continue report the time. 2,Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds? yes.

    – chenyf
    Nov 16 '18 at 12:23











  • if you don't want it to report while it's sleeping, it sleeps for 10 seconds each time, and you want it to report that it finished sleeping every 5 seconds, that means that at any time two 10-second sleeps are active, and the time should never be reported at all; am i misunderstanding?

    – timotimo
    Nov 16 '18 at 12:57











  • @timotimo yes, you are right. when sleep, it doesn't report time.

    – chenyf
    Nov 16 '18 at 14:27













12












12








12








I want to print the current time every second, and also want to sleep 10 seconds very 5 seconds:



react 
whenever Supply.interval(1)
say DateTime.now.posix;


whenever Supply.interval(5)
sleep 10;
say 'Sleep Done';


whenever signal(SIGINT)
say "Done.";
done;




the output is not what i wanted:



1542371045
Sleep Done
1542371055
Sleep Done
1542371065
Sleep Done
1542371075
Done.
...


what i want is this:



1542371045
1542371046
1542371047
1542371048
1542371049
Sleep Done
1542371059
1542371060
1542371061
1542371062
1542371063
Sleep Done
Done.


Don't know much about Promise, Supply... about Perl 6, is this possible?










share|improve this question
















I want to print the current time every second, and also want to sleep 10 seconds very 5 seconds:



react 
whenever Supply.interval(1)
say DateTime.now.posix;


whenever Supply.interval(5)
sleep 10;
say 'Sleep Done';


whenever signal(SIGINT)
say "Done.";
done;




the output is not what i wanted:



1542371045
Sleep Done
1542371055
Sleep Done
1542371065
Sleep Done
1542371075
Done.
...


what i want is this:



1542371045
1542371046
1542371047
1542371048
1542371049
Sleep Done
1542371059
1542371060
1542371061
1542371062
1542371063
Sleep Done
Done.


Don't know much about Promise, Supply... about Perl 6, is this possible?







perl6






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 16 '18 at 12:29







chenyf

















asked Nov 16 '18 at 5:06









chenyfchenyf

1,818621




1,818621







  • 1





    Should the time reports each second continue to be made during that 10 seconds break? Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds?

    – Jonathan Worthington
    Nov 16 '18 at 10:35











  • I think the basic misunderstanding is that only one whenever block will be executing at a time. This is actually underdocumented, so I will have a stab at that.

    – Elizabeth Mattijsen
    Nov 16 '18 at 11:33











  • @JonathanWorthington thanks for your attention. 1,Should the time reports each second continue to be made during that 10 seconds break? No, duration the 10 seconds break, I don't want it to continue report the time. 2,Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds? yes.

    – chenyf
    Nov 16 '18 at 12:23











  • if you don't want it to report while it's sleeping, it sleeps for 10 seconds each time, and you want it to report that it finished sleeping every 5 seconds, that means that at any time two 10-second sleeps are active, and the time should never be reported at all; am i misunderstanding?

    – timotimo
    Nov 16 '18 at 12:57











  • @timotimo yes, you are right. when sleep, it doesn't report time.

    – chenyf
    Nov 16 '18 at 14:27












  • 1





    Should the time reports each second continue to be made during that 10 seconds break? Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds?

    – Jonathan Worthington
    Nov 16 '18 at 10:35











  • I think the basic misunderstanding is that only one whenever block will be executing at a time. This is actually underdocumented, so I will have a stab at that.

    – Elizabeth Mattijsen
    Nov 16 '18 at 11:33











  • @JonathanWorthington thanks for your attention. 1,Should the time reports each second continue to be made during that 10 seconds break? No, duration the 10 seconds break, I don't want it to continue report the time. 2,Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds? yes.

    – chenyf
    Nov 16 '18 at 12:23











  • if you don't want it to report while it's sleeping, it sleeps for 10 seconds each time, and you want it to report that it finished sleeping every 5 seconds, that means that at any time two 10-second sleeps are active, and the time should never be reported at all; am i misunderstanding?

    – timotimo
    Nov 16 '18 at 12:57











  • @timotimo yes, you are right. when sleep, it doesn't report time.

    – chenyf
    Nov 16 '18 at 14:27







1




1





Should the time reports each second continue to be made during that 10 seconds break? Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds?

– Jonathan Worthington
Nov 16 '18 at 10:35





Should the time reports each second continue to be made during that 10 seconds break? Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds?

– Jonathan Worthington
Nov 16 '18 at 10:35













I think the basic misunderstanding is that only one whenever block will be executing at a time. This is actually underdocumented, so I will have a stab at that.

– Elizabeth Mattijsen
Nov 16 '18 at 11:33





I think the basic misunderstanding is that only one whenever block will be executing at a time. This is actually underdocumented, so I will have a stab at that.

– Elizabeth Mattijsen
Nov 16 '18 at 11:33













@JonathanWorthington thanks for your attention. 1,Should the time reports each second continue to be made during that 10 seconds break? No, duration the 10 seconds break, I don't want it to continue report the time. 2,Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds? yes.

– chenyf
Nov 16 '18 at 12:23





@JonathanWorthington thanks for your attention. 1,Should the time reports each second continue to be made during that 10 seconds break? No, duration the 10 seconds break, I don't want it to continue report the time. 2,Should the 10 seconds of sleep be triggered every 5 seconds, so it reports it's slept once per 5 seconds? yes.

– chenyf
Nov 16 '18 at 12:23













if you don't want it to report while it's sleeping, it sleeps for 10 seconds each time, and you want it to report that it finished sleeping every 5 seconds, that means that at any time two 10-second sleeps are active, and the time should never be reported at all; am i misunderstanding?

– timotimo
Nov 16 '18 at 12:57





if you don't want it to report while it's sleeping, it sleeps for 10 seconds each time, and you want it to report that it finished sleeping every 5 seconds, that means that at any time two 10-second sleeps are active, and the time should never be reported at all; am i misunderstanding?

– timotimo
Nov 16 '18 at 12:57













@timotimo yes, you are right. when sleep, it doesn't report time.

– chenyf
Nov 16 '18 at 14:27





@timotimo yes, you are right. when sleep, it doesn't report time.

– chenyf
Nov 16 '18 at 14:27












5 Answers
5






active

oldest

votes


















11














Depending on exactly what else was needed, I'd probably write it something like this:



react 
sub sequence()
whenever Supply.interval(1).head(5)
say DateTime.now.posix;
LAST whenever Promise.in(10)
say "Sleep done";
sequence();



sequence();



Which gives output like this:



1542395158
1542395159
1542395160
1542395161
1542395162
Sleep done
1542395172
1542395173
1542395174
1542395175
1542395176
Sleep done
1542395186
1542395187
1542395188
...


This will make absolutely sure you get 5 ticks out between the 10s pauses; doing it with two separate interval supplies - as in many solutions here - will not give any strict guarantees of that, and could miss a tick now and then. (One that doesn't is the cute one with rotor, which is a good bet if you don't need to actually print the "sleep done" thing). It's also free of state (variables) and conditions, which is rather nice.



While this looks like it might be recursive, since whenever is an asynchronous looping construct, it will not actually build up a call stack at all.



It's also fully built of asynchronous constructs, and so in Perl 6.d will not - if the react is triggered on the thread pool - ever block a real OS thread. So you could have thousands of these active. By contrast, sleep will block a real thread, which is what sleep traditionally would be expected to do, but isn't such a good fit if otherwise dealing with asynchronous constructs.






share|improve this answer























  • I might have tried a recursive implementation, except that I wanted to keep using the original .interval(1) Supply.

    – Brad Gilbert
    Nov 16 '18 at 19:40











  • thanks very much for your answer! Although concurrence is hard to understand, but Perl 6 make hard things possible.

    – chenyf
    Nov 17 '18 at 14:21


















8
















One mistake you are making is that you are assuming that supplies will lose values, or you are assuming they will stop generating values while the react is blocked.
They won't.

They keep generating values.



You should also try to have the code in a whenever run for as short of a time as possible.

(Pretend it is a CPU interrupt handler.)

There may be some exceptions to this rule, particularly for supply blocks.



Using the structure that you provided, this is one way to achieve what you want:



 react 
# Are we ignoring the interval(1) values?
my Bool:D $ignore = False;

# The sleeping status of interval(5).
my Promise:D $sleep .= kept;

whenever Supply.interval(1)
# Skip if it is supposed to be blocked.
next if $ignore;

say DateTime.now.posix;


# First one runs immediately, so skip it.
whenever Supply.interval(5).skip
# Don't run while the “sleep” is pending.
next unless $sleep.status; # Planned

if $ignore
$ignore = False;
say 'Sleep Done';
else
$ignore = True;
# Must be less than the multiple of 5 we want
# otherwise there may be a race condition.
$sleep = Promise.in(9);



whenever signal(SIGINT)
say "Done.";
done;





That isn't very clear.

How about we just use .rotor instead, to skip every third interval of 5?



react 
my Bool:D $ignore = True;

# Note that first one runs immediately. (no .skip)
# We also want it to always be a few milliseconds before
# the other Supply, so we put it first.
# (Should have done that with the previous example as well.)
whenever Supply.interval(5).rotor(1, 1 => 1)
$ignore = !$ignore;


whenever Supply.interval(1)
next if $ignore;

say DateTime.now.posix;


whenever signal(SIGINT)
say "Done.";
done;





While we are at it, why not just use .rotor on the .interval(1) Supply?



react 
whenever Supply.interval(1).rotor(1 xx 4, 1 => 10)
say DateTime.now.posix;


whenever signal(SIGINT)
say "Done.";
done;




Note that we can't just use 5 => 10 because that batches them up, and we want them to be run singly.




Note that .grep also works on Supplys, so we could have used that instead to check the $ignored value.



react 
my Bool:D $ignore = True;

whenever Supply.interval(5).rotor(1, 1 => 1)
$ignore = !$ignore;


whenever Supply.interval(1).grep( !$ignore )
say DateTime.now.posix;


whenever signal(SIGINT)
say "Done.";
done;







share|improve this answer






























    4














    May this can work:



    loop 
    react
    whenever Supply.interval(1)
    say DateTime.now.posix;


    whenever Promise.in(5)
    done;


    whenever signal(SIGINT)
    say "Done.";
    done;


    sleep 10;



    The output is:



    1542347961
    1542347962
    1542347963
    1542347964
    1542347965
    1542347976 # <- 10s
    1542347977
    1542347978
    1542347979
    1542347980
    1542347991 # <- 10s





    share|improve this answer






























      3














      The thing is the two Supplies are effectively running in different threads so don't interact with each other. Your sleep only puts the thread it's in to sleep (and then the fact it's a 5 second interval creates another sleep anyway).



      To achieve the result you're looking for I went with this which uses the single 1 second interval and a couple of flags.



      react 
      whenever Supply.interval(1)
      state $slept = False;
      state $count = 0;
      if $count >= 0
      if $slept
      say "Sleep Done";
      $slept = False

      say DateTime.now.posix;

      $count++;
      if ( $count == 5 )
      $count = -9;
      $slept = True


      whenever signal(SIGINT)
      say "Done.";
      done;




      Note that we have to use state variables because the whenever block is effectively executed in it's own thread each second. The state variables allow us to keep track of the current situation.



      If it was running on a smaller interval I would maybe think about using atomic ints instead of normal ones (in case the code was executed while it was still running) but that block should never take more than a second to execute so I don't think it's a problem.






      share|improve this answer

























      • thanks for your answer. It works!

        – chenyf
        Nov 16 '18 at 12:48


















      2














      Because only one whenever will be executing at any time, the sleep in there will be halting all handling of things to react to. The easiest way to achieve what you want, is to do the sleep as an asynchronous job by wrapping the code of that whenever into a start block.



      react 
      whenever Supply.interval(1)
      say DateTime.now.posix;


      whenever Supply.interval(5)
      start
      sleep 10;
      say 'Sleep Done';



      whenever signal(SIGINT)
      say "Done.";
      done;




      This gives the desired output, as far as I can see.






      share|improve this answer























      • thanks for your attention. but the time reports are continuous. maybe it's hard to describe this question in my english.so i write a answer that report discontinuous times.

        – chenyf
        Nov 16 '18 at 12:46











      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53331761%2fprint-sth-every-second-and-also-sleep-10-seconds-very-5-seconds-using-react%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      11














      Depending on exactly what else was needed, I'd probably write it something like this:



      react 
      sub sequence()
      whenever Supply.interval(1).head(5)
      say DateTime.now.posix;
      LAST whenever Promise.in(10)
      say "Sleep done";
      sequence();



      sequence();



      Which gives output like this:



      1542395158
      1542395159
      1542395160
      1542395161
      1542395162
      Sleep done
      1542395172
      1542395173
      1542395174
      1542395175
      1542395176
      Sleep done
      1542395186
      1542395187
      1542395188
      ...


      This will make absolutely sure you get 5 ticks out between the 10s pauses; doing it with two separate interval supplies - as in many solutions here - will not give any strict guarantees of that, and could miss a tick now and then. (One that doesn't is the cute one with rotor, which is a good bet if you don't need to actually print the "sleep done" thing). It's also free of state (variables) and conditions, which is rather nice.



      While this looks like it might be recursive, since whenever is an asynchronous looping construct, it will not actually build up a call stack at all.



      It's also fully built of asynchronous constructs, and so in Perl 6.d will not - if the react is triggered on the thread pool - ever block a real OS thread. So you could have thousands of these active. By contrast, sleep will block a real thread, which is what sleep traditionally would be expected to do, but isn't such a good fit if otherwise dealing with asynchronous constructs.






      share|improve this answer























      • I might have tried a recursive implementation, except that I wanted to keep using the original .interval(1) Supply.

        – Brad Gilbert
        Nov 16 '18 at 19:40











      • thanks very much for your answer! Although concurrence is hard to understand, but Perl 6 make hard things possible.

        – chenyf
        Nov 17 '18 at 14:21















      11














      Depending on exactly what else was needed, I'd probably write it something like this:



      react 
      sub sequence()
      whenever Supply.interval(1).head(5)
      say DateTime.now.posix;
      LAST whenever Promise.in(10)
      say "Sleep done";
      sequence();



      sequence();



      Which gives output like this:



      1542395158
      1542395159
      1542395160
      1542395161
      1542395162
      Sleep done
      1542395172
      1542395173
      1542395174
      1542395175
      1542395176
      Sleep done
      1542395186
      1542395187
      1542395188
      ...


      This will make absolutely sure you get 5 ticks out between the 10s pauses; doing it with two separate interval supplies - as in many solutions here - will not give any strict guarantees of that, and could miss a tick now and then. (One that doesn't is the cute one with rotor, which is a good bet if you don't need to actually print the "sleep done" thing). It's also free of state (variables) and conditions, which is rather nice.



      While this looks like it might be recursive, since whenever is an asynchronous looping construct, it will not actually build up a call stack at all.



      It's also fully built of asynchronous constructs, and so in Perl 6.d will not - if the react is triggered on the thread pool - ever block a real OS thread. So you could have thousands of these active. By contrast, sleep will block a real thread, which is what sleep traditionally would be expected to do, but isn't such a good fit if otherwise dealing with asynchronous constructs.






      share|improve this answer























      • I might have tried a recursive implementation, except that I wanted to keep using the original .interval(1) Supply.

        – Brad Gilbert
        Nov 16 '18 at 19:40











      • thanks very much for your answer! Although concurrence is hard to understand, but Perl 6 make hard things possible.

        – chenyf
        Nov 17 '18 at 14:21













      11












      11








      11







      Depending on exactly what else was needed, I'd probably write it something like this:



      react 
      sub sequence()
      whenever Supply.interval(1).head(5)
      say DateTime.now.posix;
      LAST whenever Promise.in(10)
      say "Sleep done";
      sequence();



      sequence();



      Which gives output like this:



      1542395158
      1542395159
      1542395160
      1542395161
      1542395162
      Sleep done
      1542395172
      1542395173
      1542395174
      1542395175
      1542395176
      Sleep done
      1542395186
      1542395187
      1542395188
      ...


      This will make absolutely sure you get 5 ticks out between the 10s pauses; doing it with two separate interval supplies - as in many solutions here - will not give any strict guarantees of that, and could miss a tick now and then. (One that doesn't is the cute one with rotor, which is a good bet if you don't need to actually print the "sleep done" thing). It's also free of state (variables) and conditions, which is rather nice.



      While this looks like it might be recursive, since whenever is an asynchronous looping construct, it will not actually build up a call stack at all.



      It's also fully built of asynchronous constructs, and so in Perl 6.d will not - if the react is triggered on the thread pool - ever block a real OS thread. So you could have thousands of these active. By contrast, sleep will block a real thread, which is what sleep traditionally would be expected to do, but isn't such a good fit if otherwise dealing with asynchronous constructs.






      share|improve this answer













      Depending on exactly what else was needed, I'd probably write it something like this:



      react 
      sub sequence()
      whenever Supply.interval(1).head(5)
      say DateTime.now.posix;
      LAST whenever Promise.in(10)
      say "Sleep done";
      sequence();



      sequence();



      Which gives output like this:



      1542395158
      1542395159
      1542395160
      1542395161
      1542395162
      Sleep done
      1542395172
      1542395173
      1542395174
      1542395175
      1542395176
      Sleep done
      1542395186
      1542395187
      1542395188
      ...


      This will make absolutely sure you get 5 ticks out between the 10s pauses; doing it with two separate interval supplies - as in many solutions here - will not give any strict guarantees of that, and could miss a tick now and then. (One that doesn't is the cute one with rotor, which is a good bet if you don't need to actually print the "sleep done" thing). It's also free of state (variables) and conditions, which is rather nice.



      While this looks like it might be recursive, since whenever is an asynchronous looping construct, it will not actually build up a call stack at all.



      It's also fully built of asynchronous constructs, and so in Perl 6.d will not - if the react is triggered on the thread pool - ever block a real OS thread. So you could have thousands of these active. By contrast, sleep will block a real thread, which is what sleep traditionally would be expected to do, but isn't such a good fit if otherwise dealing with asynchronous constructs.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Nov 16 '18 at 19:22









      Jonathan WorthingtonJonathan Worthington

      8,84912548




      8,84912548












      • I might have tried a recursive implementation, except that I wanted to keep using the original .interval(1) Supply.

        – Brad Gilbert
        Nov 16 '18 at 19:40











      • thanks very much for your answer! Although concurrence is hard to understand, but Perl 6 make hard things possible.

        – chenyf
        Nov 17 '18 at 14:21

















      • I might have tried a recursive implementation, except that I wanted to keep using the original .interval(1) Supply.

        – Brad Gilbert
        Nov 16 '18 at 19:40











      • thanks very much for your answer! Although concurrence is hard to understand, but Perl 6 make hard things possible.

        – chenyf
        Nov 17 '18 at 14:21
















      I might have tried a recursive implementation, except that I wanted to keep using the original .interval(1) Supply.

      – Brad Gilbert
      Nov 16 '18 at 19:40





      I might have tried a recursive implementation, except that I wanted to keep using the original .interval(1) Supply.

      – Brad Gilbert
      Nov 16 '18 at 19:40













      thanks very much for your answer! Although concurrence is hard to understand, but Perl 6 make hard things possible.

      – chenyf
      Nov 17 '18 at 14:21





      thanks very much for your answer! Although concurrence is hard to understand, but Perl 6 make hard things possible.

      – chenyf
      Nov 17 '18 at 14:21













      8
















      One mistake you are making is that you are assuming that supplies will lose values, or you are assuming they will stop generating values while the react is blocked.
      They won't.

      They keep generating values.



      You should also try to have the code in a whenever run for as short of a time as possible.

      (Pretend it is a CPU interrupt handler.)

      There may be some exceptions to this rule, particularly for supply blocks.



      Using the structure that you provided, this is one way to achieve what you want:



       react 
      # Are we ignoring the interval(1) values?
      my Bool:D $ignore = False;

      # The sleeping status of interval(5).
      my Promise:D $sleep .= kept;

      whenever Supply.interval(1)
      # Skip if it is supposed to be blocked.
      next if $ignore;

      say DateTime.now.posix;


      # First one runs immediately, so skip it.
      whenever Supply.interval(5).skip
      # Don't run while the “sleep” is pending.
      next unless $sleep.status; # Planned

      if $ignore
      $ignore = False;
      say 'Sleep Done';
      else
      $ignore = True;
      # Must be less than the multiple of 5 we want
      # otherwise there may be a race condition.
      $sleep = Promise.in(9);



      whenever signal(SIGINT)
      say "Done.";
      done;





      That isn't very clear.

      How about we just use .rotor instead, to skip every third interval of 5?



      react 
      my Bool:D $ignore = True;

      # Note that first one runs immediately. (no .skip)
      # We also want it to always be a few milliseconds before
      # the other Supply, so we put it first.
      # (Should have done that with the previous example as well.)
      whenever Supply.interval(5).rotor(1, 1 => 1)
      $ignore = !$ignore;


      whenever Supply.interval(1)
      next if $ignore;

      say DateTime.now.posix;


      whenever signal(SIGINT)
      say "Done.";
      done;





      While we are at it, why not just use .rotor on the .interval(1) Supply?



      react 
      whenever Supply.interval(1).rotor(1 xx 4, 1 => 10)
      say DateTime.now.posix;


      whenever signal(SIGINT)
      say "Done.";
      done;




      Note that we can't just use 5 => 10 because that batches them up, and we want them to be run singly.




      Note that .grep also works on Supplys, so we could have used that instead to check the $ignored value.



      react 
      my Bool:D $ignore = True;

      whenever Supply.interval(5).rotor(1, 1 => 1)
      $ignore = !$ignore;


      whenever Supply.interval(1).grep( !$ignore )
      say DateTime.now.posix;


      whenever signal(SIGINT)
      say "Done.";
      done;







      share|improve this answer



























        8
















        One mistake you are making is that you are assuming that supplies will lose values, or you are assuming they will stop generating values while the react is blocked.
        They won't.

        They keep generating values.



        You should also try to have the code in a whenever run for as short of a time as possible.

        (Pretend it is a CPU interrupt handler.)

        There may be some exceptions to this rule, particularly for supply blocks.



        Using the structure that you provided, this is one way to achieve what you want:



         react 
        # Are we ignoring the interval(1) values?
        my Bool:D $ignore = False;

        # The sleeping status of interval(5).
        my Promise:D $sleep .= kept;

        whenever Supply.interval(1)
        # Skip if it is supposed to be blocked.
        next if $ignore;

        say DateTime.now.posix;


        # First one runs immediately, so skip it.
        whenever Supply.interval(5).skip
        # Don't run while the “sleep” is pending.
        next unless $sleep.status; # Planned

        if $ignore
        $ignore = False;
        say 'Sleep Done';
        else
        $ignore = True;
        # Must be less than the multiple of 5 we want
        # otherwise there may be a race condition.
        $sleep = Promise.in(9);



        whenever signal(SIGINT)
        say "Done.";
        done;





        That isn't very clear.

        How about we just use .rotor instead, to skip every third interval of 5?



        react 
        my Bool:D $ignore = True;

        # Note that first one runs immediately. (no .skip)
        # We also want it to always be a few milliseconds before
        # the other Supply, so we put it first.
        # (Should have done that with the previous example as well.)
        whenever Supply.interval(5).rotor(1, 1 => 1)
        $ignore = !$ignore;


        whenever Supply.interval(1)
        next if $ignore;

        say DateTime.now.posix;


        whenever signal(SIGINT)
        say "Done.";
        done;





        While we are at it, why not just use .rotor on the .interval(1) Supply?



        react 
        whenever Supply.interval(1).rotor(1 xx 4, 1 => 10)
        say DateTime.now.posix;


        whenever signal(SIGINT)
        say "Done.";
        done;




        Note that we can't just use 5 => 10 because that batches them up, and we want them to be run singly.




        Note that .grep also works on Supplys, so we could have used that instead to check the $ignored value.



        react 
        my Bool:D $ignore = True;

        whenever Supply.interval(5).rotor(1, 1 => 1)
        $ignore = !$ignore;


        whenever Supply.interval(1).grep( !$ignore )
        say DateTime.now.posix;


        whenever signal(SIGINT)
        say "Done.";
        done;







        share|improve this answer

























          8












          8








          8









          One mistake you are making is that you are assuming that supplies will lose values, or you are assuming they will stop generating values while the react is blocked.
          They won't.

          They keep generating values.



          You should also try to have the code in a whenever run for as short of a time as possible.

          (Pretend it is a CPU interrupt handler.)

          There may be some exceptions to this rule, particularly for supply blocks.



          Using the structure that you provided, this is one way to achieve what you want:



           react 
          # Are we ignoring the interval(1) values?
          my Bool:D $ignore = False;

          # The sleeping status of interval(5).
          my Promise:D $sleep .= kept;

          whenever Supply.interval(1)
          # Skip if it is supposed to be blocked.
          next if $ignore;

          say DateTime.now.posix;


          # First one runs immediately, so skip it.
          whenever Supply.interval(5).skip
          # Don't run while the “sleep” is pending.
          next unless $sleep.status; # Planned

          if $ignore
          $ignore = False;
          say 'Sleep Done';
          else
          $ignore = True;
          # Must be less than the multiple of 5 we want
          # otherwise there may be a race condition.
          $sleep = Promise.in(9);



          whenever signal(SIGINT)
          say "Done.";
          done;





          That isn't very clear.

          How about we just use .rotor instead, to skip every third interval of 5?



          react 
          my Bool:D $ignore = True;

          # Note that first one runs immediately. (no .skip)
          # We also want it to always be a few milliseconds before
          # the other Supply, so we put it first.
          # (Should have done that with the previous example as well.)
          whenever Supply.interval(5).rotor(1, 1 => 1)
          $ignore = !$ignore;


          whenever Supply.interval(1)
          next if $ignore;

          say DateTime.now.posix;


          whenever signal(SIGINT)
          say "Done.";
          done;





          While we are at it, why not just use .rotor on the .interval(1) Supply?



          react 
          whenever Supply.interval(1).rotor(1 xx 4, 1 => 10)
          say DateTime.now.posix;


          whenever signal(SIGINT)
          say "Done.";
          done;




          Note that we can't just use 5 => 10 because that batches them up, and we want them to be run singly.




          Note that .grep also works on Supplys, so we could have used that instead to check the $ignored value.



          react 
          my Bool:D $ignore = True;

          whenever Supply.interval(5).rotor(1, 1 => 1)
          $ignore = !$ignore;


          whenever Supply.interval(1).grep( !$ignore )
          say DateTime.now.posix;


          whenever signal(SIGINT)
          say "Done.";
          done;







          share|improve this answer















          One mistake you are making is that you are assuming that supplies will lose values, or you are assuming they will stop generating values while the react is blocked.
          They won't.

          They keep generating values.



          You should also try to have the code in a whenever run for as short of a time as possible.

          (Pretend it is a CPU interrupt handler.)

          There may be some exceptions to this rule, particularly for supply blocks.



          Using the structure that you provided, this is one way to achieve what you want:



           react 
          # Are we ignoring the interval(1) values?
          my Bool:D $ignore = False;

          # The sleeping status of interval(5).
          my Promise:D $sleep .= kept;

          whenever Supply.interval(1)
          # Skip if it is supposed to be blocked.
          next if $ignore;

          say DateTime.now.posix;


          # First one runs immediately, so skip it.
          whenever Supply.interval(5).skip
          # Don't run while the “sleep” is pending.
          next unless $sleep.status; # Planned

          if $ignore
          $ignore = False;
          say 'Sleep Done';
          else
          $ignore = True;
          # Must be less than the multiple of 5 we want
          # otherwise there may be a race condition.
          $sleep = Promise.in(9);



          whenever signal(SIGINT)
          say "Done.";
          done;





          That isn't very clear.

          How about we just use .rotor instead, to skip every third interval of 5?



          react 
          my Bool:D $ignore = True;

          # Note that first one runs immediately. (no .skip)
          # We also want it to always be a few milliseconds before
          # the other Supply, so we put it first.
          # (Should have done that with the previous example as well.)
          whenever Supply.interval(5).rotor(1, 1 => 1)
          $ignore = !$ignore;


          whenever Supply.interval(1)
          next if $ignore;

          say DateTime.now.posix;


          whenever signal(SIGINT)
          say "Done.";
          done;





          While we are at it, why not just use .rotor on the .interval(1) Supply?



          react 
          whenever Supply.interval(1).rotor(1 xx 4, 1 => 10)
          say DateTime.now.posix;


          whenever signal(SIGINT)
          say "Done.";
          done;




          Note that we can't just use 5 => 10 because that batches them up, and we want them to be run singly.




          Note that .grep also works on Supplys, so we could have used that instead to check the $ignored value.



          react 
          my Bool:D $ignore = True;

          whenever Supply.interval(5).rotor(1, 1 => 1)
          $ignore = !$ignore;


          whenever Supply.interval(1).grep( !$ignore )
          say DateTime.now.posix;


          whenever signal(SIGINT)
          say "Done.";
          done;








          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 16 '18 at 17:25









          Brad GilbertBrad Gilbert

          25.7k864110




          25.7k864110





















              4














              May this can work:



              loop 
              react
              whenever Supply.interval(1)
              say DateTime.now.posix;


              whenever Promise.in(5)
              done;


              whenever signal(SIGINT)
              say "Done.";
              done;


              sleep 10;



              The output is:



              1542347961
              1542347962
              1542347963
              1542347964
              1542347965
              1542347976 # <- 10s
              1542347977
              1542347978
              1542347979
              1542347980
              1542347991 # <- 10s





              share|improve this answer



























                4














                May this can work:



                loop 
                react
                whenever Supply.interval(1)
                say DateTime.now.posix;


                whenever Promise.in(5)
                done;


                whenever signal(SIGINT)
                say "Done.";
                done;


                sleep 10;



                The output is:



                1542347961
                1542347962
                1542347963
                1542347964
                1542347965
                1542347976 # <- 10s
                1542347977
                1542347978
                1542347979
                1542347980
                1542347991 # <- 10s





                share|improve this answer

























                  4












                  4








                  4







                  May this can work:



                  loop 
                  react
                  whenever Supply.interval(1)
                  say DateTime.now.posix;


                  whenever Promise.in(5)
                  done;


                  whenever signal(SIGINT)
                  say "Done.";
                  done;


                  sleep 10;



                  The output is:



                  1542347961
                  1542347962
                  1542347963
                  1542347964
                  1542347965
                  1542347976 # <- 10s
                  1542347977
                  1542347978
                  1542347979
                  1542347980
                  1542347991 # <- 10s





                  share|improve this answer













                  May this can work:



                  loop 
                  react
                  whenever Supply.interval(1)
                  say DateTime.now.posix;


                  whenever Promise.in(5)
                  done;


                  whenever signal(SIGINT)
                  say "Done.";
                  done;


                  sleep 10;



                  The output is:



                  1542347961
                  1542347962
                  1542347963
                  1542347964
                  1542347965
                  1542347976 # <- 10s
                  1542347977
                  1542347978
                  1542347979
                  1542347980
                  1542347991 # <- 10s






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 16 '18 at 6:05









                  chenyfchenyf

                  1,818621




                  1,818621





















                      3














                      The thing is the two Supplies are effectively running in different threads so don't interact with each other. Your sleep only puts the thread it's in to sleep (and then the fact it's a 5 second interval creates another sleep anyway).



                      To achieve the result you're looking for I went with this which uses the single 1 second interval and a couple of flags.



                      react 
                      whenever Supply.interval(1)
                      state $slept = False;
                      state $count = 0;
                      if $count >= 0
                      if $slept
                      say "Sleep Done";
                      $slept = False

                      say DateTime.now.posix;

                      $count++;
                      if ( $count == 5 )
                      $count = -9;
                      $slept = True


                      whenever signal(SIGINT)
                      say "Done.";
                      done;




                      Note that we have to use state variables because the whenever block is effectively executed in it's own thread each second. The state variables allow us to keep track of the current situation.



                      If it was running on a smaller interval I would maybe think about using atomic ints instead of normal ones (in case the code was executed while it was still running) but that block should never take more than a second to execute so I don't think it's a problem.






                      share|improve this answer

























                      • thanks for your answer. It works!

                        – chenyf
                        Nov 16 '18 at 12:48















                      3














                      The thing is the two Supplies are effectively running in different threads so don't interact with each other. Your sleep only puts the thread it's in to sleep (and then the fact it's a 5 second interval creates another sleep anyway).



                      To achieve the result you're looking for I went with this which uses the single 1 second interval and a couple of flags.



                      react 
                      whenever Supply.interval(1)
                      state $slept = False;
                      state $count = 0;
                      if $count >= 0
                      if $slept
                      say "Sleep Done";
                      $slept = False

                      say DateTime.now.posix;

                      $count++;
                      if ( $count == 5 )
                      $count = -9;
                      $slept = True


                      whenever signal(SIGINT)
                      say "Done.";
                      done;




                      Note that we have to use state variables because the whenever block is effectively executed in it's own thread each second. The state variables allow us to keep track of the current situation.



                      If it was running on a smaller interval I would maybe think about using atomic ints instead of normal ones (in case the code was executed while it was still running) but that block should never take more than a second to execute so I don't think it's a problem.






                      share|improve this answer

























                      • thanks for your answer. It works!

                        – chenyf
                        Nov 16 '18 at 12:48













                      3












                      3








                      3







                      The thing is the two Supplies are effectively running in different threads so don't interact with each other. Your sleep only puts the thread it's in to sleep (and then the fact it's a 5 second interval creates another sleep anyway).



                      To achieve the result you're looking for I went with this which uses the single 1 second interval and a couple of flags.



                      react 
                      whenever Supply.interval(1)
                      state $slept = False;
                      state $count = 0;
                      if $count >= 0
                      if $slept
                      say "Sleep Done";
                      $slept = False

                      say DateTime.now.posix;

                      $count++;
                      if ( $count == 5 )
                      $count = -9;
                      $slept = True


                      whenever signal(SIGINT)
                      say "Done.";
                      done;




                      Note that we have to use state variables because the whenever block is effectively executed in it's own thread each second. The state variables allow us to keep track of the current situation.



                      If it was running on a smaller interval I would maybe think about using atomic ints instead of normal ones (in case the code was executed while it was still running) but that block should never take more than a second to execute so I don't think it's a problem.






                      share|improve this answer















                      The thing is the two Supplies are effectively running in different threads so don't interact with each other. Your sleep only puts the thread it's in to sleep (and then the fact it's a 5 second interval creates another sleep anyway).



                      To achieve the result you're looking for I went with this which uses the single 1 second interval and a couple of flags.



                      react 
                      whenever Supply.interval(1)
                      state $slept = False;
                      state $count = 0;
                      if $count >= 0
                      if $slept
                      say "Sleep Done";
                      $slept = False

                      say DateTime.now.posix;

                      $count++;
                      if ( $count == 5 )
                      $count = -9;
                      $slept = True


                      whenever signal(SIGINT)
                      say "Done.";
                      done;




                      Note that we have to use state variables because the whenever block is effectively executed in it's own thread each second. The state variables allow us to keep track of the current situation.



                      If it was running on a smaller interval I would maybe think about using atomic ints instead of normal ones (in case the code was executed while it was still running) but that block should never take more than a second to execute so I don't think it's a problem.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 16 '18 at 10:15

























                      answered Nov 16 '18 at 10:03









                      ScimonScimon

                      2,0121312




                      2,0121312












                      • thanks for your answer. It works!

                        – chenyf
                        Nov 16 '18 at 12:48

















                      • thanks for your answer. It works!

                        – chenyf
                        Nov 16 '18 at 12:48
















                      thanks for your answer. It works!

                      – chenyf
                      Nov 16 '18 at 12:48





                      thanks for your answer. It works!

                      – chenyf
                      Nov 16 '18 at 12:48











                      2














                      Because only one whenever will be executing at any time, the sleep in there will be halting all handling of things to react to. The easiest way to achieve what you want, is to do the sleep as an asynchronous job by wrapping the code of that whenever into a start block.



                      react 
                      whenever Supply.interval(1)
                      say DateTime.now.posix;


                      whenever Supply.interval(5)
                      start
                      sleep 10;
                      say 'Sleep Done';



                      whenever signal(SIGINT)
                      say "Done.";
                      done;




                      This gives the desired output, as far as I can see.






                      share|improve this answer























                      • thanks for your attention. but the time reports are continuous. maybe it's hard to describe this question in my english.so i write a answer that report discontinuous times.

                        – chenyf
                        Nov 16 '18 at 12:46
















                      2














                      Because only one whenever will be executing at any time, the sleep in there will be halting all handling of things to react to. The easiest way to achieve what you want, is to do the sleep as an asynchronous job by wrapping the code of that whenever into a start block.



                      react 
                      whenever Supply.interval(1)
                      say DateTime.now.posix;


                      whenever Supply.interval(5)
                      start
                      sleep 10;
                      say 'Sleep Done';



                      whenever signal(SIGINT)
                      say "Done.";
                      done;




                      This gives the desired output, as far as I can see.






                      share|improve this answer























                      • thanks for your attention. but the time reports are continuous. maybe it's hard to describe this question in my english.so i write a answer that report discontinuous times.

                        – chenyf
                        Nov 16 '18 at 12:46














                      2












                      2








                      2







                      Because only one whenever will be executing at any time, the sleep in there will be halting all handling of things to react to. The easiest way to achieve what you want, is to do the sleep as an asynchronous job by wrapping the code of that whenever into a start block.



                      react 
                      whenever Supply.interval(1)
                      say DateTime.now.posix;


                      whenever Supply.interval(5)
                      start
                      sleep 10;
                      say 'Sleep Done';



                      whenever signal(SIGINT)
                      say "Done.";
                      done;




                      This gives the desired output, as far as I can see.






                      share|improve this answer













                      Because only one whenever will be executing at any time, the sleep in there will be halting all handling of things to react to. The easiest way to achieve what you want, is to do the sleep as an asynchronous job by wrapping the code of that whenever into a start block.



                      react 
                      whenever Supply.interval(1)
                      say DateTime.now.posix;


                      whenever Supply.interval(5)
                      start
                      sleep 10;
                      say 'Sleep Done';



                      whenever signal(SIGINT)
                      say "Done.";
                      done;




                      This gives the desired output, as far as I can see.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 16 '18 at 12:15









                      Elizabeth MattijsenElizabeth Mattijsen

                      9,30412239




                      9,30412239












                      • thanks for your attention. but the time reports are continuous. maybe it's hard to describe this question in my english.so i write a answer that report discontinuous times.

                        – chenyf
                        Nov 16 '18 at 12:46


















                      • thanks for your attention. but the time reports are continuous. maybe it's hard to describe this question in my english.so i write a answer that report discontinuous times.

                        – chenyf
                        Nov 16 '18 at 12:46

















                      thanks for your attention. but the time reports are continuous. maybe it's hard to describe this question in my english.so i write a answer that report discontinuous times.

                      – chenyf
                      Nov 16 '18 at 12:46






                      thanks for your attention. but the time reports are continuous. maybe it's hard to describe this question in my english.so i write a answer that report discontinuous times.

                      – chenyf
                      Nov 16 '18 at 12:46


















                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53331761%2fprint-sth-every-second-and-also-sleep-10-seconds-very-5-seconds-using-react%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Top Tejano songwriter Luis Silva dead of heart attack at 64

                      政党

                      天津地下鉄3号線