I am testing spatie's async project. I created a task as such.
use Spatie\Async\Task;
class ServiceTask extends Task
{
protected $accountService;
protected $serviceFactory;
public function __construct(ServiceFactory $serviceFactory)
{
$this->serviceFactory = $serviceFactory;
}
public function configure()
{
$this->accountService = $this->serviceFactory->getAccountService();
}
public function run()
{
//accounting tasks
}
}
And for the pool:
$pool = Pool::create();
foreach ($transactions as $transaction) {
$pool->add(new ServiceTask($serviceFactory))
// handlers
;
}
$pool->wait();
When I run the above code, I simply get
Serialization of 'Closure' is not allowed
I know that we cannot simply serialize a closure, I tried the same code above with a simple plain Data Transfer Object, it worked fine. But when passing a service, or a container class from symfony I get above error. Is there a work around for this?
Short answer: no
Longer answer: Spatie Async serializes task before adding it to the pool, so you might need an alternative solution.
See relevant code to understand what's going on: Pool::add > ParentRuntime::createProcess > ParentRuntime::encodeTask.
For more discussion, see this or this issue in spatie/async's issue list.
There are many alternatives to this problem. Since you're using Symfony, you might be interested in Symfony Messenger to send messages to a handler. Those handlers can use dependency injection:
class DefaultController extends AbstractController
{
public function index(MessageBusInterface $bus)
{
$bus->dispatch(new ServiceTask('Look! I created a message!'));
}
}
class ServiceTaskHandler implements MessageHandlerInterface
{
protected $accountService;
protected $serviceFactory;
public function __construct(ServiceFactory $serviceFactory)
{
$this->serviceFactory = $serviceFactory;
$this->accountService = $this->serviceFactory->getAccountService();
}
public function __invoke(ServiceTask $task)
{
$this->accountService->handle($task);
}
}
Be aware that a Task (ServiceTask in this example) should (like spatie/async's task) be serializable as well. So you might send an ID as a message, and look up that ID in your MessageHandler
Serialization of 'Closure' is not allowed is an error that is formed when passing a cued event as an argument. Likely the issue has to do with creating the object in a factory then passing it as part of the constructor.