in src/daemon/PhutilDaemonPool.php [257:354]
private function updateAutoscale() {
if ($this->shouldShutdown()) {
return;
}
// Don't try to autoscale more than once per second. This mostly stops the
// logs from getting flooded in verbose mode.
$now = time();
if ($this->lastAutoscaleUpdate >= $now) {
return;
}
$this->lastAutoscaleUpdate = $now;
$daemons = $this->getDaemons();
// If this pool is already at the maximum size, we can't launch any new
// daemons.
$max_size = $this->getPoolMaximumSize();
if (count($daemons) >= $max_size) {
$this->logMessage(
'POOL',
pht(
'Autoscale pool "%s" already at maximum size (%s of %s).',
$this->getPoolLabel(),
new PhutilNumber(count($daemons)),
new PhutilNumber($max_size)));
return;
}
$scaleup_duration = $this->getPoolScaleupDuration();
foreach ($daemons as $daemon) {
$busy_epoch = $daemon->getBusyEpoch();
// If any daemons haven't started work yet, don't scale the pool up.
if (!$busy_epoch) {
$this->logMessage(
'POOL',
pht(
'Autoscale pool "%s" has an idle daemon, declining to scale.',
$this->getPoolLabel()));
return;
}
// If any daemons started work very recently, wait a little while
// to scale the pool up.
$busy_for = ($now - $busy_epoch);
if ($busy_for < $scaleup_duration) {
$this->logMessage(
'POOL',
pht(
'Autoscale pool "%s" has not been busy long enough to scale up '.
'(busy for %s of %s seconds).',
$this->getPoolLabel(),
new PhutilNumber($busy_for),
new PhutilNumber($scaleup_duration)));
return;
}
}
// If we have a configured memory reserve for this pool, it tells us that
// we should not scale up unless there's at least that much memory left
// on the system (for example, a reserve of 0.25 means that 25% of system
// memory must be free to autoscale).
// Note that the first daemon is exempt: we'll always launch at least one
// daemon, regardless of any memory reservation.
if (count($daemons)) {
$reserve = $this->getPoolMemoryReserve();
if ($reserve) {
// On some systems this may be slightly more expensive than other
// checks, so we only do it once we're prepared to scale up.
$memory = PhutilSystem::getSystemMemoryInformation();
$free_ratio = ($memory['free'] / $memory['total']);
// If we don't have enough free memory, don't scale.
if ($free_ratio <= $reserve) {
$this->logMessage(
'POOL',
pht(
'Autoscale pool "%s" does not have enough free memory to '.
'scale up (%s free of %s reserved).',
$this->getPoolLabel(),
new PhutilNumber($free_ratio, 3),
new PhutilNumber($reserve, 3)));
return;
}
}
}
$this->logMessage(
'AUTO',
pht(
'Scaling pool "%s" up to %s daemon(s).',
$this->getPoolLabel(),
new PhutilNumber(count($daemons) + 1)));
$this->newDaemon();
}