prepare('INSERT INTO task_queue (handler, args, options, regdate) VALUES (?, ?, ?, ?)'); $result = $stmt->execute([$handler, serialize($args), serialize($options), date('Y-m-d H:i:s')]); return $result ? $oDB->getInsertID() : 0; } /** * Add a task to be executed at a specific time. * * @param int $time * @param string $handler * @param ?object $args * @param ?object $options * @return int */ public function addTaskAt(int $time, string $handler, ?object $args = null, ?object $options = null): int { $oDB = RFDB::getInstance(); $stmt = $oDB->prepare(trim(<<execute([ 'once', date('Y-m-d H:i:s', $time), $handler, serialize($args), serialize($options), date('Y-m-d H:i:s'), ]); return $result ? $oDB->getInsertID() : 0; } /** * Add a task to be executed at an interval. * * @param string $interval * @param string $handler * @param ?object $args * @param ?object $options * @return int */ public function addTaskAtInterval(string $interval, string $handler, ?object $args = null, ?object $options = null): int { $oDB = RFDB::getInstance(); $stmt = $oDB->prepare(trim(<<execute([ 'interval', $interval, $handler, serialize($args), serialize($options), date('Y-m-d H:i:s'), ]); return $result ? $oDB->getInsertID() : 0; } /** * Get the next task from the queue. * * @param int $blocking * @return ?object */ public function getNextTask(int $blocking = 0): ?object { $oDB = RFDB::getInstance(); $oDB->beginTransaction(); $stmt = $oDB->query('SELECT * FROM task_queue ORDER BY id LIMIT 1 FOR UPDATE'); $result = $stmt->fetchObject(); $stmt->closeCursor(); if ($result) { $stmt = $oDB->prepare('DELETE FROM task_queue WHERE id = ?'); $stmt->execute([$result->id]); $oDB->commit(); $result->args = unserialize($result->args); $result->options = unserialize($result->options); return $result; } else { $oDB->commit(); return null; } } /** * Get scheduled tasks. * * @param string $type * @return array */ public function getScheduledTasks(string $type): array { $oDB = RFDB::getInstance(); $tasks = []; $ids = []; // Get tasks to be executed once at the current time. if ($type === 'once') { $oDB->beginTransaction(); $stmt = $oDB->query("SELECT * FROM task_schedule WHERE `type` = 'once' AND `first_run` <= ? ORDER BY id FOR UPDATE", [$timestamp]); while ($task = $stmt->fetchObject()) { $task->args = unserialize($task->args); $task->options = unserialize($task->options); $tasks[] = $task; $ids[] = $task->id; } if (count($ids)) { $stmt = $oDB->prepare('DELETE FROM task_schedule WHERE id IN (' . implode(', ', array_fill(0, count($ids), '?')) . ')'); $stmt->execute($ids); } $oDB->commit(); } // Get tasks to be executed at an interval. if ($type === 'interval') { $stmt = $oDB->query("SELECT id, `interval` FROM task_schedule WHERE `type` = 'interval' ORDER BY id"); while ($task = $stmt->fetchObject()) { if (Queue::parseInterval($task->interval, \RX_TIME)) { $ids[] = $task->id; } } if (count($ids)) { $stmt = $oDB->prepare('SELECT * FROM task_schedule WHERE id IN (' . implode(', ', array_fill(0, count($ids), '?')) . ')'); $stmt->execute($ids); while ($task = $stmt->fetchObject()) { $task->args = unserialize($task->args); $task->options = unserialize($task->options); $tasks[] = $task; } } } return $tasks; } /** * Update the last executed timestamp of a scheduled task. * * @param int $id * @return void */ public function updateLastRunTimestamp(int $id): void { $oDB = RFDB::getInstance(); $stmt = $oDB->prepare('UPDATE task_schedule SET last_run = ?, run_count = run_count + 1 WHERE id = ?'); $stmt->execute([date('Y-m-d H:i:s'), $id]); } }