Skip to content

Commit

Permalink
Handle thread exhaustion more gracefully
Browse files Browse the repository at this point in the history
- leave more CPU to the threads that *are* doing stuff
- add $!exhausted attribute to ThreadPoolScheduler
- this gets set if creating a new thread failed
- which then inhibits trying to add any more workers
  • Loading branch information
lizmat committed Nov 11, 2017
1 parent ba49b34 commit fe799a9
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions src/core/ThreadPoolScheduler.pm
Expand Up @@ -315,6 +315,7 @@ my class ThreadPoolScheduler does Scheduler {
has $!general-workers;
has $!timer-workers;
has $!affinity-workers;
has int $!exhausted;

# The supervisor thread, if started.
has Thread $!supervisor;
Expand Down Expand Up @@ -457,6 +458,7 @@ my class ThreadPoolScheduler does Scheduler {
method !maybe-start-supervisor(--> Nil) {
unless $!supervisor.DEFINITE {
$!supervisor = Thread.start(:app_lifetime, :name<Supervisor>, {

sub add-general-worker(--> Nil) {
$!state-lock.protect: {
$!general-workers := push-worker(
Expand Down Expand Up @@ -531,18 +533,29 @@ my class ThreadPoolScheduler does Scheduler {
scheduler-debug-status "Per-core utilization (approx): $smooth-per-core-util%"
if $scheduler-debug-status;

if $!general-queue.DEFINITE && $!general-queue.elems {
self!tweak-workers: $!general-queue, $!general-workers,
&add-general-worker, $cpu-cores, $smooth-per-core-util;
}
if $!timer-queue.DEFINITE && $!timer-queue.elems {
self!tweak-workers: $!timer-queue, $!timer-workers,
&add-timer-worker, $cpu-cores, $smooth-per-core-util;
unless $!exhausted {
self!tweak-workers($!general-queue, $!general-workers,
&add-general-worker, $cpu-cores, $smooth-per-core-util)
if $!general-queue.DEFINITE && $!general-queue.elems;

self!tweak-workers($!timer-queue, $!timer-workers,
&add-timer-worker, $cpu-cores, $smooth-per-core-util)
if $!timer-queue.DEFINITE && $!timer-queue.elems;

self!prod-affinity-workers: $!affinity-workers
if $!affinity-workers.DEFINITE;
}
self!prod-affinity-workers: $!affinity-workers
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;
}
}
default {
scheduler-debug .gist;
}
Expand Down

0 comments on commit fe799a9

Please sign in to comment.