fork download
  1. #!/usr/bin/perl6
  2.  
  3. class Spawn {
  4. has &.cb;
  5. has @.args;
  6. has $.name;
  7. has $.in = Channel.new;
  8.  
  9. method receive() {
  10. return $!in.receive;
  11. }
  12.  
  13. multi method send(Str $name, \msg) {
  14. for @*scheduler {
  15. if .name eq $name {
  16. .send([$!name, msg]);
  17. last;
  18. }
  19. }
  20. }
  21.  
  22. multi method send(\msg) {
  23. $!in.send(msg);
  24. }
  25.  
  26. method loop {
  27. start {
  28. &!cb(self, |@!args);
  29. }
  30. }
  31. }
  32.  
  33. my @*scheduler = [];
  34.  
  35. sub main-loop() {
  36. await Promise.allof(
  37. [ @*scheduler>>.loop ]
  38. );
  39. }
  40.  
  41. sub spawn(&cb, @args, :$name) {
  42. @*scheduler.push(
  43. Spawn.new(
  44. cb => &cb,
  45. args => @args,
  46. name => $name
  47. )
  48. );
  49. }
  50.  
  51. &spawn(&ping, ["pong", 3], name => "ping");
  52. &spawn(&pong, [], name => "pong");
  53. &main-loop();
  54.  
  55. sub ping(\s, Str $name, Int $x) {
  56. for ^$x {
  57. s.send($name, "pong");
  58. if s.receive -> ($ping, $msg) {
  59. given $msg {
  60. when /ping/ {
  61. say "{$msg} received from {$ping}";
  62. }
  63. }
  64. }
  65. }
  66. s.send($name, "finish");
  67. say "ping finished!";
  68. }
  69. sub pong(\s) {
  70. while (True) {
  71. if s.receive -> ($ping, $msg) {
  72. given $msg {
  73. when /finish/ {
  74. say "pong finished.";
  75. last;
  76. }
  77. when /pong/ {
  78. say "{$msg} received from {$ping}";
  79. s.send($ping, "ping");
  80. }
  81. }
  82. }
  83. }
  84. }
Success #stdin #stdout 0.32s 272320KB
stdin
Standard input is empty
stdout
pong received from ping
ping received from pong
pong received from ping
ping received from pong
pong received from ping
ping received from pong
ping finished!
pong finished.