2024-06-17 12:44:12 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Appwrite\Platform\Tasks;
|
|
|
|
|
|
|
|
|
|
use Appwrite\Event\Func;
|
2025-05-14 09:42:39 +00:00
|
|
|
use Swoole\Coroutine as Co;
|
2024-10-08 07:54:40 +00:00
|
|
|
use Utopia\Database\Database;
|
2025-09-01 14:03:49 +00:00
|
|
|
use Utopia\Telemetry\Adapter as Telemetry;
|
2024-06-17 12:44:12 +00:00
|
|
|
|
|
|
|
|
class ScheduleExecutions extends ScheduleBase
|
|
|
|
|
{
|
|
|
|
|
public const UPDATE_TIMER = 3; // seconds
|
|
|
|
|
public const ENQUEUE_TIMER = 4; // seconds
|
|
|
|
|
|
2025-09-01 14:03:49 +00:00
|
|
|
protected Func $queueForFunctions;
|
|
|
|
|
|
2024-06-17 12:44:12 +00:00
|
|
|
public static function getName(): string
|
|
|
|
|
{
|
|
|
|
|
return 'schedule-executions';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function getSupportedResource(): string
|
|
|
|
|
{
|
|
|
|
|
return 'execution';
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-03 03:07:53 +00:00
|
|
|
public static function getCollectionId(): string
|
|
|
|
|
{
|
|
|
|
|
return 'executions';
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:03:49 +00:00
|
|
|
public function __construct()
|
|
|
|
|
{
|
|
|
|
|
$this
|
2025-09-03 09:29:49 +00:00
|
|
|
->desc('Execute executions scheduled in Appwrite')
|
2025-09-01 14:03:49 +00:00
|
|
|
->inject('queueForFunctions')
|
|
|
|
|
->inject('dbForPlatform')
|
|
|
|
|
->inject('getProjectDB')
|
|
|
|
|
->inject('telemetry')
|
|
|
|
|
->callback($this->action(...));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function action(Func $queueForFunctions, Database $dbForPlatform, callable $getProjectDB, Telemetry $telemetry): void
|
|
|
|
|
{
|
|
|
|
|
$this->queueForFunctions = $queueForFunctions;
|
|
|
|
|
$this->schedule($dbForPlatform, $getProjectDB, $telemetry);
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-16 17:11:04 +00:00
|
|
|
protected function enqueueResources(Database $dbForPlatform, callable $getProjectDB): void
|
2024-06-17 12:44:12 +00:00
|
|
|
{
|
2024-07-18 12:03:24 +00:00
|
|
|
$intervalEnd = (new \DateTime())->modify('+' . self::ENQUEUE_TIMER . ' seconds');
|
2024-06-17 13:12:02 +00:00
|
|
|
|
2024-06-17 12:44:12 +00:00
|
|
|
foreach ($this->schedules as $schedule) {
|
2024-06-17 13:12:02 +00:00
|
|
|
if (!$schedule['active']) {
|
2024-12-12 10:30:26 +00:00
|
|
|
$dbForPlatform->deleteDocument(
|
2024-07-01 13:35:37 +00:00
|
|
|
'schedules',
|
|
|
|
|
$schedule['$id'],
|
|
|
|
|
);
|
|
|
|
|
|
2025-05-26 05:42:11 +00:00
|
|
|
unset($this->schedules[$schedule['$sequence']]);
|
2024-06-17 12:44:12 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$scheduledAt = new \DateTime($schedule['schedule']);
|
2024-07-18 12:03:24 +00:00
|
|
|
if ($scheduledAt <= $intervalEnd) {
|
2024-06-17 12:44:12 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-12 10:30:26 +00:00
|
|
|
$data = $dbForPlatform->getDocument(
|
2024-09-07 10:20:23 +00:00
|
|
|
'schedules',
|
|
|
|
|
$schedule['$id'],
|
|
|
|
|
)->getAttribute('data', []);
|
2024-07-18 12:03:24 +00:00
|
|
|
|
2024-09-07 10:20:23 +00:00
|
|
|
$delay = $scheduledAt->getTimestamp() - (new \DateTime())->getTimestamp();
|
2024-07-19 09:22:50 +00:00
|
|
|
|
2024-12-17 14:19:26 +00:00
|
|
|
$this->updateProjectAccess($schedule['project'], $dbForPlatform);
|
2024-12-17 14:05:49 +00:00
|
|
|
|
2025-09-01 14:03:49 +00:00
|
|
|
\go(function () use ($schedule, $scheduledAt, $delay, $data) {
|
|
|
|
|
$queueForFunctions = clone $this->queueForFunctions;
|
2025-05-14 09:42:39 +00:00
|
|
|
Co::sleep($delay);
|
2025-04-29 09:28:53 +00:00
|
|
|
|
|
|
|
|
$queueForFunctions->setType('schedule')
|
|
|
|
|
// Set functionId instead of function as we don't have $dbForProject
|
|
|
|
|
// TODO: Refactor to use function instead of functionId
|
2025-02-03 12:43:35 +00:00
|
|
|
->setFunctionId($schedule['resource']['resourceId'])
|
2025-04-29 09:28:53 +00:00
|
|
|
->setExecution($schedule['resource'])
|
|
|
|
|
->setMethod($data['method'] ?? 'POST')
|
|
|
|
|
->setPath($data['path'] ?? '/')
|
|
|
|
|
->setHeaders($data['headers'] ?? [])
|
|
|
|
|
->setBody($data['body'] ?? '')
|
|
|
|
|
->setProject($schedule['project'])
|
2025-04-30 01:06:51 +00:00
|
|
|
->setUserId($data['userId'] ?? '')
|
|
|
|
|
->trigger();
|
2025-05-12 16:05:32 +00:00
|
|
|
|
2025-05-13 11:03:09 +00:00
|
|
|
$this->recordEnqueueDelay($scheduledAt);
|
2024-10-01 14:30:47 +00:00
|
|
|
});
|
2024-09-20 16:30:05 +00:00
|
|
|
|
2024-12-12 10:30:26 +00:00
|
|
|
$dbForPlatform->deleteDocument(
|
2024-10-08 07:54:40 +00:00
|
|
|
'schedules',
|
|
|
|
|
$schedule['$id'],
|
|
|
|
|
);
|
|
|
|
|
|
2025-05-26 05:42:11 +00:00
|
|
|
unset($this->schedules[$schedule['$sequence']]);
|
2025-04-17 05:09:08 +00:00
|
|
|
}
|
2024-06-17 12:44:12 +00:00
|
|
|
}
|
|
|
|
|
}
|