Ограничить количество экземпляров Symfony Command

У меня есть команда в моем приложении Symfony, запущенном Cron. Я хочу иметь возможность ограничить количество экземпляров, выполняемых одновременно на моем сервере, скажем, 4 экземпляра. Я понятия не имею, как это сделать. Я нашел, как заблокировать команду, чтобы запустить команду только один раз и дождаться ее завершения, но я не знаю, как запустить более одного и все равно ограничить количество экземпляров. У вас есть идея?


person Kristen Joseph-Delaffon    schedule 11.10.2017    source источник


Ответы (4)


То, что вы ищете, это semaphore.

В настоящее время запланировано LockComponent для версии 3.4 (было взято из версии 3.3). Это значительное улучшение по сравнению с LockHandler в FilesystemComponent.

В крайнем случае вы, вероятно, можете объединить фиксированное количество блокировок из LockHandler. Я не рекомендую его, потому что он использует flock в файловой системе. Это ограничивает блокировку одним сервером. Кроме того, в некоторых системах flock может быть ограничен областью процесса.

<?php

use Symfony\Component\Filesystem\LockHandler;

define('LOCK_ID', 'some-identifier');
define('LOCK_MAX', 5);

$lockPool = [];

for ($i = 0; $i <= LOCK_MAX;) {
    $lockHandle = sprintf('%s-%s.lock', LOCK_ID, ++$i);
    $lockPool[$i] = new LockHandler($lockHandle);
}

$activeLock = null;
$lockTimeout = 60 * 1000;

$lockWaitStart = microtime(true);
while(!$activeLock) {
    foreach ($lockPool as $lockHandler) {
        if ($lockHandler->lock()) {
            $activeLock = $lockHandler;
            break 2;
        }
    }

    if ($lockTimeout && ($lockTimeout > microtime(true) - $lockWaitStart)) {
        break;
    }

    // Randomly wait between 0.1ms and 10ms
    usleep(mt_rand(100, 10000));
}

Гораздо лучшим и эффективным решением было бы использовать расширение семафора и немного поколдовать с ftok, shm_* и sem_*.

person Steve Buzonas    schedule 12.10.2017

я предлагаю вам использовать систему управления технологическим процессом в качестве руководителя. он довольно прост в использовании, и вы можете выбрать, сколько экземпляров вашего скрипта вы запускаете.

http://supervisord.org/

person Mocrates    schedule 11.10.2017

Вы можете использовать общий файл счетчика, который содержит счетчик, который увеличивается, когда команда начинает выполняться, и уменьшается до ее завершения.

Другим решением будет проверка списка процессов примерно так:

$processCount = exec('ps aux | grep "some part of the console command you run" | grep -v "grep" | wc -l' );
if(!empty($processCount) && $processCount >= X) {
    return false;
}
person Joe    schedule 12.10.2017

Вы можете создать «команду запуска», выполняемую вашим cron или руководителем.

Эта команда Symfony может запускать ваши экземпляры с компонентом процесса на вашем сервере. Вы также можете проверить все, что хотите, и сделать все, что хотите, как функция exec php.

person Fabien Salles    schedule 12.10.2017