What you probably want is a different kind of queue worker. See https://mglaman.dev/blog/flush-and-run-using-kernelterminate-improve-page-speed-performance
A simple example:
/src/EventSubscriber/TaskOnTerminateSubscriber.php
<?php
namespace Drupal\mymodule\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\TerminateEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* A subscriber running a task by request
*/
class TaskOnTerminateSubscriber implements EventSubscriberInterface {
/**
* TRUE if a task run is requested.
*
* @var bool
*/
protected $runTask = FALSE;
/**
* Request a task run
*/
public function runTask() {
$this->runTask = TRUE;
}
/**
* Run task if requested.
*
* @param \Symfony\Component\HttpKernel\Event\TerminateEvent $event
* The Event to process.
*/
public function onTerminate(TerminateEvent $event) {
if ($this->runTask) {
// replace this with your long-running task
sleep(10);
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [KernelEvents::TERMINATE => [['onTerminate', 150]]];
}
}
mymodule.services.yml
services:
mymodule.task_on_terminate_subscriber:
class: Drupal\mymodule\EventSubscriber\TaskOnTerminateSubscriber
tags:
- { name: event_subscriber }
Trigger the task in hook_ENTITY_TYPE_presave/insert/update:
\Drupal::service('mymodule.task_on_terminate_subscriber')->runTask();
runTask() could contain arguments, like the entity ID. You can also make the service store multiple tasks in an array class property, which would then be a queue stored in memory processed right after the response is flushed to the client.