1
0
Fork 0
mirror of synced 2024-06-27 02:31:04 +12:00

Merge pull request #3809 from appwrite/fix-function-scheduling

Fix functon scheduling loop logic, and double-loop prevention
This commit is contained in:
Torsten Dittmann 2022-09-14 10:20:27 +02:00 committed by GitHub
commit 1043cc4fc1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 4 deletions

View file

@ -2148,6 +2148,17 @@ $collections = [
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('scheduleUpdatedAt'), // Used to fix duplicate executions bug. Can be removed once new queue library is used
'type' => Database::VAR_DATETIME,
'format' => '',
'size' => 0,
'signed' => false,
'required' => false,
'default' => null,
'array' => false,
'filters' => ['datetime'],
],
[
'$id' => ID::custom('schedulePrevious'),
'type' => Database::VAR_DATETIME,

View file

@ -84,6 +84,7 @@ App::post('/v1/functions')
'deployment' => '',
'events' => $events,
'schedule' => $schedule,
'scheduleUpdatedAt' => DateTime::now(),
'schedulePrevious' => null,
'scheduleNext' => null,
'timeout' => $timeout,
@ -445,6 +446,7 @@ App::put('/v1/functions/:functionId')
$cron = (!empty($function->getAttribute('deployment')) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (!empty($function->getAttribute('deployment')) && !empty($schedule)) ? DateTime::format($cron->getNextRunDate()) : null;
$scheduleUpdatedAt = $schedule !== $original ? DateTime::now() : $function->getAttribute('scheduleUpdatedAt');
$enabled ??= $function->getAttribute('enabled', true);
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
@ -452,6 +454,7 @@ App::put('/v1/functions/:functionId')
'name' => $name,
'events' => $events,
'schedule' => $schedule,
'scheduleUpdatedAt' => $scheduleUpdatedAt,
'scheduleNext' => $next,
'timeout' => $timeout,
'enabled' => $enabled,

View file

@ -129,7 +129,7 @@ class FunctionsV1 extends Worker
break;
case 'schedule':
$scheduleOriginal = $execution->getAttribute('scheduleOriginal', '');
$functionOriginal = $function;
/*
* 1. Get Original Task
* 2. Check for updates
@ -150,21 +150,25 @@ class FunctionsV1 extends Worker
throw new Exception('Function not found (' . $function->getId() . ')');
}
if ($scheduleOriginal && $scheduleOriginal !== $function->getAttribute('schedule')) { // Schedule has changed from previous run, ignore this run.
if ($functionOriginal->getAttribute('schedule') !== $function->getAttribute('schedule')) { // Schedule has changed from previous run, ignore this run.
return;
}
if ($functionOriginal->getAttribute('scheduleUpdatedAt') !== $function->getAttribute('scheduleUpdatedAt')) { // Double execution due to rapid cron changes, ignore this run.
return;
}
$cron = new CronExpression($function->getAttribute('schedule'));
$next = DateTime::format($cron->getNextRunDate());
$function
$function = $function
->setAttribute('scheduleNext', $next)
->setAttribute('schedulePrevious', DateTime::now());
$function = $database->updateDocument(
'functions',
$function->getId(),
$function->setAttribute('scheduleNext', $next)
$function
);
$reschedule = new Func();