Search code examples
rakurakudo

Strange behavior when changing $*SCHEDULER after execution of external program


Description

There is an example:

#!/bin/env raku
run 'raku', '-e', 'say "ok"';
exit 0;
my $*SCHEDULER = ThreadPoolScheduler.new(max_threads => 128);

On linux output is:

ok
Unhandled exception in code scheduled on thread 4
No such method 'cue' for invocant of type 'Any'

On windows output is:

Unhandled exception in code scheduled on thread 4
No such method 'cue' for invocant of type 'Any'
  in method throw at 'SETTING::'src/core.c/Exception.pm6 line 65
  in method schedule_thens at 'SETTING::'src/core.c/Promise.pm6 line 167
  in method keep at 'SETTING::'src/core.c/Promise.pm6 line 127
  in method keep at 'SETTING::'src/core.c/Promise.pm6 line 83
  in block  at 'SETTING::'src/core.c/Proc/Async.pm6 line 390
  in block  at 'SETTING::'src/core.c/ThreadPoolScheduler.pm6 line 263
  in method run-one at 'SETTING::'src/core.c/ThreadPoolScheduler.pm6 line 244
  in block  at 'SETTING::'src/core.c/ThreadPoolScheduler.pm6 line 308
  in sub THREAD-ENTRY at 'SETTING::'src/core.c/Thread.pm6 line 69

Sometimes it prints ok before an error, sometimes after one, sometimes it doesn't print it. I didn't find a pattern of this.

Questions

  1. Is this a bug?
  2. What does this error mean and why does it appear?
  3. Why does this happen even after exit 0?

Solution

  • There is a default setting for $*SCHEDULER, because all of the async functionality depends on that.

    By adding a $*SCHEDULER to that scope, you're overriding that, which I assume is your intent.

    However, at the moment the run runs, it is NOT set yet: it is Any. So the run tries to cue the action to execute the command, but there is no scheduler available to cue this on.

    The fix? Make sure the scheduler is set before executing run:

    my $*SCHEDULER = ThreadPoolScheduler.new(max_threads => 128);
    run 'raku', '-e', 'say "ok"';
    exit 0;
    

    So to answer your questions:

    1. No, it is a case of DIHWIDT

    2. See above

    3. That's a matter of timing, I guess, although it is a bit puzzling. My guess would be is that the cue is for handling the result of run, not for the run itself. So it starts executing, and after it has started, it finds out it can't actually cue the handler of the result of the run.