为什么我无法迁移 unix 套接字的每当块中的供应?

ama*_*ano 10 raku

服务器

#!/usr/bin/env raku

unlink "/run/user/1000/sock";
my $socket = IO::Socket::Async.listen-path("/run/user/1000/sock");

react {
  my $timerSupplier = Supplier.new;

  whenever $timerSupplier.Supply.migrate {
    say "3 second interval: ", $_;
  }
  $timerSupplier.emit(Supply.interval(3));

  whenever $socket -> $conn {
    $timerSupplier.emit(Supply.interval(3));
    say "\"", $_.Supply.lines.Channel.receive, "\"";
    $conn.close;
  }
}

Run Code Online (Sandbox Code Playgroud)

客户

#!/usr/bin/env raku

my $sock = IO::Socket::Async.connect-path("/run/user/1000/sock").result;
await $sock.print("ok\n");
Run Code Online (Sandbox Code Playgroud)

如果我先执行服务器,然后执行客户端,则会出现以下异常。

Unhandled exception in code scheduled on thread 8
Can only cancel an AsyncTask handle
  in block  at ./server line 16
Run Code Online (Sandbox Code Playgroud)

谁能告诉我有什么问题吗?

Xli*_*iff 9

事实上,这是你的代码中的一个错误。为了找到它,我必须稍微重写一下:

unlink "/run/user/1000/sock";
my $socket = IO::Socket::Async.listen-path("/run/user/1000/sock");

react {
  my $timerSupplier = Supplier.new;

  whenever $timerSupplier.Supply.migrate {
    CATCH { default { .message.say } }
    say "3 second interval:", $_;
  }

  $timerSupplier.emit( Supply.interval(3) );

  whenever $socket -> $conn {
    CATCH { default { .message.say } }

    $timerSupplier.emit(Supply.interval(3));
    say "\"{ $conn.Supply.lines.Channel.receive }\"";
    $conn.close;
  }
}
Run Code Online (Sandbox Code Playgroud)

这使我能够克服错误消息,这充其量也没有什么帮助。此更改导致以下错误消息:

Cannot unbox a type object (Any) to a str.
Run Code Online (Sandbox Code Playgroud)

所以我必须将第一个whenever块更改为以下内容:

  whenever $timerSupplier.Supply.migrate {
    CATCH { default { .message.say } }
    say "3 second interval: { $_ }";
  }
Run Code Online (Sandbox Code Playgroud)

这产生了一个工作示例:

3 second interval: 0
3 second interval: 1
"ok"
3 second interval: 0
3 second interval: 1
3 second interval: 2
Run Code Online (Sandbox Code Playgroud)

我唯一的建议是尽可能多地使用字符串插值,因为这具有在相关对象上运行隐式 .Str() 的好处。say $_vs的语义say "{ $_ }"很微妙,但意义深远。


ama*_*ano 4

更换

  whenever $socket -> $conn {
    $timerSupplier.emit(Supply.interval(3));
    say "\"", $_.Supply.lines.Channel.receive, "\"";
    $conn.close;
  }
Run Code Online (Sandbox Code Playgroud)

  whenever $socket -> $conn {
    $timerSupplier.emit(Supply.interval(3));
    say "\"", $conn.Supply.lines.Channel.receive, "\"";
    $conn.close;
  }
Run Code Online (Sandbox Code Playgroud)

修复了错误。似乎如果一个块有一个命名参数,主题变量就会停止工作。