Skip to content

Instantly share code, notes, and snippets.

@jnthn
Created September 21, 2017 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jnthn/25349dee44f20b932c8663dbe504c39e to your computer and use it in GitHub Desktop.
Save jnthn/25349dee44f20b932c8663dbe504c39e to your computer and use it in GitHub Desktop.
Quickly hacked up long (and so likely stuck) await reporter, to help debug v6.d non-blocking awaits
use OO::Monitors;
my monitor AwaitState {
my class Outstanding {
has int $.id;
has int $.generation;
has Backtrace $.backtrace;
}
has int $!next-id = 0;
has int $!generation = 0;
has %!outstanding;
method pre-await($backtrace) {
my $id = $!next-id++;
%!outstanding{$id} = Outstanding.new(:$id, :$backtrace, :$!generation);
$id
}
method post-await($id) {
%!outstanding{$id}:delete;
}
method next-generation(--> Nil) {
$!generation++;
}
method await-backtraces-with-age-greater-than($age) {
%!outstanding.values
.grep(*.generation + $age < $!generation)
.map(*.backtrace)
.eager
}
}
my $await-state = AwaitState.new;
for <await await-all> -> $meth {
ThreadPoolScheduler::ThreadPoolAwaiter.^lookup($meth).wrap: -> | {
my $id = $await-state.pre-await(Backtrace.new(4));
my \result = callsame();
$await-state.post-await($id);
result
}
}
start loop {
react {
whenever Supply.interval(1) {
$await-state.next-generation();
if $await-state.await-backtraces-with-age-greater-than(5) -> @bts {
note "There are `await`s with age greater than 5 seconds:";
for @bts {
note .full.indent(4);
note "";
}
}
}
}
CATCH {
note "Oops, long await reporter crashed!\n{.gist}";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment