@@ -532,29 +532,7 @@ public function cancelTask(int $taskId): DataResponse {
532532 #[ApiRoute(verb: 'GET ' , url: '/tasks_provider/next ' , root: '/taskprocessing ' )]
533533 public function getNextScheduledTask (array $ providerIds , array $ taskTypeIds ): DataResponse {
534534 try {
535- $ providerIdsBasedOnTaskTypesWithNull = array_unique (array_map (function ($ taskTypeId ) {
536- try {
537- return $ this ->taskProcessingManager ->getPreferredProvider ($ taskTypeId )->getId ();
538- } catch (Exception ) {
539- return null ;
540- }
541- }, $ taskTypeIds ));
542-
543- $ providerIdsBasedOnTaskTypes = array_filter ($ providerIdsBasedOnTaskTypesWithNull , fn ($ providerId ) => $ providerId !== null );
544-
545- // restrict $providerIds to providers that are configured as preferred for the passed task types
546- $ possibleProviderIds = array_values (array_intersect ($ providerIdsBasedOnTaskTypes , $ providerIds ));
547-
548- // restrict $taskTypeIds to task types that can actually be run by one of the now restricted providers
549- $ possibleTaskTypeIds = array_values (array_filter ($ taskTypeIds , function ($ taskTypeId ) use ($ possibleProviderIds ) {
550- try {
551- $ providerForTaskType = $ this ->taskProcessingManager ->getPreferredProvider ($ taskTypeId )->getId ();
552- } catch (Exception ) {
553- // no provider found for task type
554- return false ;
555- }
556- return in_array ($ providerForTaskType , $ possibleProviderIds , true );
557- }));
535+ [$ possibleProviderIds , $ possibleTaskTypeIds ] = $ this ->intersectTaskTypesAndProviders ($ taskTypeIds , $ providerIds );
558536
559537 if (count ($ possibleProviderIds ) === 0 || count ($ possibleTaskTypeIds ) === 0 ) {
560538 throw new NotFoundException ();
@@ -596,6 +574,61 @@ public function getNextScheduledTask(array $providerIds, array $taskTypeIds): Da
596574 }
597575 }
598576
577+ /**
578+ * Returns the next n scheduled tasks for the specified set of taskTypes and providers
579+ * The returned tasks are capped at ~50MiB
580+ *
581+ * @param list<string> $providerIds The ids of the providers
582+ * @param list<string> $taskTypeIds The ids of the task types
583+ * @param int $numberOfTasks The number of tasks to return
584+ * @return DataResponse<Http::STATUS_OK, array{tasks: list<array{task: CoreTaskProcessingTask, provider: string}>, has_more: bool}, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
585+ *
586+ * 200: Tasks returned
587+ */
588+ #[ExAppRequired]
589+ #[ApiRoute(verb: 'GET ' , url: '/tasks_provider/next_batch ' , root: '/taskprocessing ' )]
590+ public function getNextScheduledTaskBatch (array $ providerIds , array $ taskTypeIds , int $ numberOfTasks = 1 ): DataResponse {
591+ try {
592+ [$ possibleProviderIds , $ possibleTaskTypeIds ] = $ this ->intersectTaskTypesAndProviders ($ taskTypeIds , $ providerIds );
593+
594+ if (count ($ possibleProviderIds ) === 0 || count ($ possibleTaskTypeIds ) === 0 ) {
595+ return new DataResponse ([
596+ 'tasks ' => [],
597+ 'has_more ' => false ,
598+ ]);
599+ }
600+
601+ $ tasks = $ this ->taskProcessingManager ->getNextScheduledTasks ($ possibleTaskTypeIds , numberOfTasks: $ numberOfTasks + 1 );
602+ $ tasksJson = [];
603+ // Stop when $numberOfTasks is reached or the json payload is larger than 50MiB
604+ while (count ($ tasks ) > 0 && count ($ tasksJson ) < $ numberOfTasks && strlen (json_encode ($ tasks )) < 50 * 1024 * 1024 ) {
605+ // Until we find a task whose task type is set to be provided by the providers requested with this request
606+ // Or no scheduled task is found anymore (given the taskIds to ignore)
607+ $ task = array_shift ($ tasks );
608+ try {
609+ $ provider = $ this ->taskProcessingManager ->getPreferredProvider ($ task ->getTaskTypeId ());
610+ if (in_array ($ provider ->getId (), $ possibleProviderIds , true )) {
611+ if ($ this ->taskProcessingManager ->lockTask ($ task )) {
612+ $ tasksJson [] = ['task ' => $ task ->jsonSerialize (), 'provider ' => $ provider ->getId ()];
613+ continue ;
614+ }
615+ }
616+ } catch (Exception ) {
617+ // There is no provider set for the task type of this task
618+ // proceed to ignore this task
619+ }
620+ }
621+ $ hasMore = count ($ tasks ) > 0 ;
622+
623+ return new DataResponse ([
624+ 'tasks ' => $ tasksJson ,
625+ 'has_more ' => $ hasMore ,
626+ ]);
627+ } catch (Exception ) {
628+ return new DataResponse (['message ' => $ this ->l ->t ('Internal error ' )], Http::STATUS_INTERNAL_SERVER_ERROR );
629+ }
630+ }
631+
599632 /**
600633 * @param resource $data
601634 * @return int
@@ -611,4 +644,36 @@ private function setFileContentsInternal($data): int {
611644 $ file = $ folder ->newFile (time () . '- ' . rand (1 , 100000 ), $ data );
612645 return $ file ->getId ();
613646 }
647+
648+ /**
649+ * @param array $taskTypeIds
650+ * @param array $providerIds
651+ * @return array
652+ */
653+ private function intersectTaskTypesAndProviders (array $ taskTypeIds , array $ providerIds ): array {
654+ $ providerIdsBasedOnTaskTypesWithNull = array_unique (array_map (function ($ taskTypeId ) {
655+ try {
656+ return $ this ->taskProcessingManager ->getPreferredProvider ($ taskTypeId )->getId ();
657+ } catch (Exception ) {
658+ return null ;
659+ }
660+ }, $ taskTypeIds ));
661+
662+ $ providerIdsBasedOnTaskTypes = array_filter ($ providerIdsBasedOnTaskTypesWithNull , fn ($ providerId ) => $ providerId !== null );
663+
664+ // restrict $providerIds to providers that are configured as preferred for the passed task types
665+ $ possibleProviderIds = array_values (array_intersect ($ providerIdsBasedOnTaskTypes , $ providerIds ));
666+
667+ // restrict $taskTypeIds to task types that can actually be run by one of the now restricted providers
668+ $ possibleTaskTypeIds = array_values (array_filter ($ taskTypeIds , function ($ taskTypeId ) use ($ possibleProviderIds ) {
669+ try {
670+ $ providerForTaskType = $ this ->taskProcessingManager ->getPreferredProvider ($ taskTypeId )->getId ();
671+ } catch (Exception ) {
672+ // no provider found for task type
673+ return false ;
674+ }
675+ return in_array ($ providerForTaskType , $ possibleProviderIds , true );
676+ }));
677+ return [$ possibleProviderIds , $ possibleTaskTypeIds ];
678+ }
614679}
0 commit comments