Skip to content

Commit

Permalink
Add typed error for thread creation exhaustion
Browse files Browse the repository at this point in the history
- and make sure the supervisor knows about it
- bikeshedding on the new X::Exhausted exception may start
  • Loading branch information
lizmat committed Nov 11, 2017
1 parent 5737449 commit 14fbb5e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
10 changes: 10 additions & 0 deletions src/core/Exception.pm
Expand Up @@ -897,6 +897,16 @@ my class X::Trait::Scope is Exception {
}
my class X::Comp::Trait::Scope is X::Trait::Scope does X::Comp { };

my class X::Exhausted is Exception {
has $.what;
has $.reason;
method message {
$.reason
?? "Could not create another $.what because of: $.reason"
!! "Could not create another $.what"
}
}

my class X::OutOfRange is Exception {
has $.what = 'Argument';
has $.got = '<unknown>';
Expand Down
11 changes: 11 additions & 0 deletions src/core/Thread.pm
Expand Up @@ -18,6 +18,7 @@ my class Thread {
Str() :$!name = "<anon>"
--> Nil
) {
constant THREAD_ERROR = 'Could not create a new Thread: ';
$!vm_thread := nqp::newthread(
anon sub THREAD-ENTRY() {
my $*THREAD = self;
Expand All @@ -30,6 +31,16 @@ my class Thread {
code();
},
$!app_lifetime ?? 1 !! 0);
CATCH {
when X::AdHoc {
.payload.starts-with(THREAD_ERROR)
?? X::Exhausted.new(
:what<thread>,
:reason(.payload.substr(THREAD_ERROR.chars))
).throw
!! .rethrow
}
}
}

method start(Thread:U: &code, *%adverbs) {
Expand Down
15 changes: 6 additions & 9 deletions src/core/ThreadPoolScheduler.pm
Expand Up @@ -535,7 +535,8 @@ my class ThreadPoolScheduler does Scheduler {

# exhausted the system allotment of low level threads
if $!exhausted {
$!exhausted = 0 if ++$!exhausted > EXHAUSTED_RETRY_AFTER;
$!exhausted = 0 # try again in next run of supervisor
if ++$!exhausted > EXHAUSTED_RETRY_AFTER;
}

# we can still add threads if necessary
Expand All @@ -555,14 +556,10 @@ my class ThreadPoolScheduler does Scheduler {
if $!affinity-workers.DEFINITE;

CATCH {
when X::AdHoc {
if .payload.starts-with("Could not create a new Thread") {
$!exhausted = 1;
scheduler-debug "Refraining from trying to start new threads";
}
else {
scheduler-debug .gist;
}
when X::Exhausted {
$!exhausted = 1;
scheduler-debug .message;
scheduler-debug "Refraining from trying to start new threads";
}
default {
scheduler-debug .gist;
Expand Down

0 comments on commit 14fbb5e

Please sign in to comment.