175 lines
4.1 KiB
PHP
175 lines
4.1 KiB
PHP
<?php
|
|
|
|
/**
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; under version 2
|
|
* of the License (non-upgradable).
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Copyright (c) 2017 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
|
|
*
|
|
*/
|
|
|
|
namespace oat\taoTaskQueue\model\Worker;
|
|
|
|
use Exception;
|
|
use oat\oatbox\log\LoggerAwareTrait;
|
|
use oat\oatbox\service\ConfigurableService;
|
|
use React\ChildProcess\Process;
|
|
|
|
class WorkerProcessManager extends ConfigurableService
|
|
{
|
|
use LoggerAwareTrait;
|
|
|
|
const SERVICE_ID = 'taoTaskQueue/WorkerProcessManager';
|
|
|
|
const OPTION_TASK_COMMAND = 'task_command';
|
|
|
|
/** @var Process[] */
|
|
private $processes = [];
|
|
|
|
/** @var integer */
|
|
private $limitOfCpu;
|
|
|
|
/** @var integer */
|
|
private $limitOfMemory;
|
|
|
|
/**
|
|
* @param Process $process
|
|
*/
|
|
public function addProcess(Process $process)
|
|
{
|
|
$pid = $process->getPid();
|
|
|
|
$process->stdout->on('data', function ($status) use ($pid) {
|
|
$this->logInfo('Process: ' . $pid . ' status:' . $status);
|
|
});
|
|
|
|
$process->stdout->on('end', function () use ($pid) {
|
|
$this->logInfo('Process: ' . $pid . ' ended');
|
|
});
|
|
|
|
$process->stdout->on('error', function (Exception $e) use ($pid) {
|
|
$this->logError('Process: ' . $pid . ' error. ' . $e->getMessage());
|
|
});
|
|
|
|
$process->stdout->on('close', function () use ($pid) {
|
|
$this->logInfo('Process: ' . $pid . ' closed.');
|
|
|
|
unset($this->processes[$pid]);
|
|
});
|
|
|
|
$process->stdin->end($data = null);
|
|
|
|
$this->processes[$pid] = $process;
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function canRun()
|
|
{
|
|
$this->logInfo('No of process workers running: ' . count($this->processes));
|
|
|
|
$memoryUsage = $this->getMemoryUsage();
|
|
$cpuUsage = $this->getCpuUsage();
|
|
|
|
if (
|
|
$memoryUsage < $this->limitOfMemory
|
|
&& $cpuUsage < $this->limitOfCpu
|
|
) {
|
|
return true;
|
|
}
|
|
|
|
$this->logInfo('Limit Of memory and Cpu exceeded waiting for task to finish.
|
|
Current memory usage:' . $memoryUsage . ' Cpu usage:' . $cpuUsage);
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getCommand()
|
|
{
|
|
return $this->getOption(static::OPTION_TASK_COMMAND);
|
|
}
|
|
|
|
/**
|
|
* @return float|int
|
|
*/
|
|
public function getMemoryUsage()
|
|
{
|
|
$free = shell_exec('free');
|
|
$free = (string)trim($free);
|
|
$freeArray = explode("\n", $free);
|
|
$memory = explode(" ", $freeArray[1]);
|
|
$memory = array_filter($memory);
|
|
$memory = array_merge($memory);
|
|
$memoryUsage = $memory[1] > 0
|
|
? $memory[2] / $memory[1] * 100
|
|
: 0;
|
|
|
|
return $memoryUsage;
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
public function getCpuUsage()
|
|
{
|
|
$load = sys_getloadavg();
|
|
|
|
return $load[0];
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function getLimitOfCpu()
|
|
{
|
|
return $this->limitOfCpu;
|
|
}
|
|
|
|
/**
|
|
* @param int $limitOfCpu
|
|
*/
|
|
public function setLimitOfCpu($limitOfCpu)
|
|
{
|
|
$this->limitOfCpu = $limitOfCpu;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function getLimitOfMemory()
|
|
{
|
|
return $this->limitOfMemory;
|
|
}
|
|
|
|
/**
|
|
* @param int $limitOfMemory
|
|
*/
|
|
public function setLimitOfMemory($limitOfMemory)
|
|
{
|
|
$this->limitOfMemory = $limitOfMemory;
|
|
}
|
|
|
|
/**
|
|
* @return Process[]
|
|
*/
|
|
public function getProcesses()
|
|
{
|
|
return $this->processes;
|
|
}
|
|
}
|