public function testParseMeminfo()
 {
     $tests = array('meminfo.ubuntu14.txt' => array('total' => 7843336192, 'free' => 3758297088));
     $dir = dirname(__FILE__) . '/memory';
     foreach ($tests as $input => $expect) {
         $raw = Filesystem::readFile($dir . '/' . $input);
         $actual = PhutilSystem::parseMemInfo($raw);
         $this->assertEqual($expect, $actual, pht('Parse of "%s".', $input));
     }
 }
 public function updateAutoscale()
 {
     if ($this->inGracefulShutdown) {
         return;
     }
     foreach ($this->autoscale as $group => $daemons) {
         $scaleup_duration = $this->getAutoscaleProperty($group, 'up', 2);
         $max_pool_size = $this->getAutoscaleProperty($group, 'pool', 8);
         $reserve = $this->getAutoscaleProperty($group, 'reserve', 0);
         // Don't scale a group if it is already at the maximum pool size.
         if (count($daemons) >= $max_pool_size) {
             continue;
         }
         $should_scale = true;
         foreach ($daemons as $daemon_id => $ignored) {
             $busy = idx($this->daemons[$daemon_id], 'busy');
             if (!$busy) {
                 // At least one daemon in the group hasn't reported that it has
                 // started work.
                 $should_scale = false;
                 break;
             }
             if (time() - $busy < $scaleup_duration) {
                 // At least one daemon in the group was idle recently, so we have
                 // not fullly
                 $should_scale = false;
                 break;
             }
         }
         // 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).
         if ($should_scale && $reserve) {
             // On some systems this may be slightly more expensive than other
             // checks, so 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) {
                 continue;
             }
         }
         if ($should_scale) {
             $config = $this->autoscaleConfig[$group];
             $config['autoscale']['clone'] = true;
             $clone = new PhutilDaemonHandle($this, $config['class'], $this->argv, array('log' => $this->log, 'argv' => $config['argv'], 'load' => $this->libraries, 'autoscale' => $config['autoscale']));
             $this->logMessage('AUTO', pht('Scaling pool "%s" up to %s daemon(s).', $group, new PhutilNumber(count($daemons) + 1)));
             $this->addDaemon($clone, $config);
             // Don't scale more than one pool up per iteration. Otherwise, we could
             // break the memory barrier if we have a lot of pools and scale them
             // all up at once.
             return;
         }
     }
 }