Вот обновил код до такого, но нет:
1. Стартуем воркеры
public function start() {
exec("php-cgi -f test.php type=worker pid=1 > /dev/null 2>&1 &");
exec("php-cgi -f test.php type=worker pid=2 > /dev/null 2>&1 &");
exec("php-cgi -f test.php type=worker pid=3 > /dev/null 2>&1 &");
}
2. Код воркера
public function worker($pid) {
while ( ! $this->stop ) {
$this->db->query( "UPDATE " . PREFIX . "_tasks SET `lock` = '1', `lock_pid` = '{$pid}' WHERE `lock` = '0' AND `lock_next` <= '" . date( "Y-m-d H:i:s" ) . "' LIMIT 1" );
if ( $this->db->get_affected_rows() ) {
$row = $this->db->super_query( "SELECT `id` FROM " . PREFIX . "_tasks WHERE `lock` = '1' AND `lock_pid` = '{$pid}' LIMIT 1" );
if ( $row['id'] ) {
// Передаем задачу менеджеру
$task = new Tasks;
$task->run( $row['id'] );
}
} else {
sleep( 20 );
}
}
}
3. Ну и выполнение задачи
class Test extends Tasks {
public function start($id) {
$row = $this->db->super_query( "SELECT * FROM " . PREFIX . "_tasks WHERE `id` = '{$id}'" );
if ( $row['id'] ) {
$log_file = ROOT_DIR . '/tmp/' . $row['id'] . '.log';
$log = [];
for ( $i = 0; $i <= 10; $i++ ) {
$log[] = date( "Y-m-d H:i:s" ) . ' - ' . $row['lock_pid'] . "\n";
sleep( rand(1,5) );
}
sleep( rand(1,5) );
file_put_contents( $log_file, $log, FILE_APPEND );
// Снимаем блокировку и устанавливаем время до которого задача будет заблокирована
$this->db->query( "UPDATE " . PREFIX . "_tasks
SET `lock` = '0', `lock_pid` = '0', `lock_next` = '" . date( "Y-m-d H:i:s", strtotime( '+2 minutes' ) ) . "'
WHERE `id` = '{$row['id']}'" );
}
}
}
При выполнении задачи, он почему-то успешно делает логирование в файл, но не обновляет метку времени в БД. sleep'ы я добавил специально, чтобы затунять выполнение.