ruth / async-service-call-bundle
Symfony bundle for asynchronous service methods calls
Installs: 33
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 5
Type:symfony-bundle
pkg:composer/ruth/async-service-call-bundle
Requires
- php: >=7.3
- symfony/console: ~5.0
- symfony/framework-bundle: ~5.0
- symfony/monolog-bundle: ^3.5
- symfony/process: ^5.0
Requires (Dev)
- symfony/phpunit-bridge: >=5.0
README
This bundle allows you to execute methods of your services asynchronously in a background process.
It is a fork on krlove/async-service-call-bundle, updated to run in Symfony 4 or 5.
Installation
Install using composer:
composer require ruth/async-service-call-bundle
It should enable the bundle at config/bundles.php
return [
...
new Krlove\AsyncServiceCallBundle\KrloveAsyncServiceCallBundle(),
]
If not, you now know what to do.
Configuration
Options:
console_path- path toconsolescript. Can be absolute or relative tokernel.project_dirparameter's value. Defaults tobin/consoleSymfony 4.* and Symfony 5.*.php_path- path to php executable. If no option provided in configuration,Symfony\Component\Process\PhpExecutableFinder::findwill be used to set it up.
Example:
# config/packages/krlove_async_service_call.yaml
krlove_async_service_call:
console_path: bin/console
php_path: /usr/local/bin/php
Usage
Define any service:
<?php
namespace App\Service;
class AwesomeService
{
public function doSomething($int, $string, $array)
{
// do something heavy
sleep(10);
}
}
Register service:
# services.yml
services:
app.service.awesome:
class: App\Service\AwesomeService
public: true
make sure your service is configured with
public: true
Execute doSomething method asynchronously:
$this->get('krlove.async')
->call('app.service.awesome', 'doSomething', [1, 'string', ['array']);
Line above will execute App\Service\AwesomeService::doSomething method by running krlove:service:call command on background.
You can follow it's execution by calling top on your console.
Original approach with symfony process Symfony\Component\Process\Process was abandoned
in favor of a more traditional exec php function. The reason is this (that you can find in upper page):
If a Response is sent before a child process had a chance to complete, the server process will be killed (depending on your OS).
It means that your task will be stopped right away.
Running an asynchronous process is not the same as running a process that survives its parent process.
Usage with Symfony Process Component
It is also possible to run your service with Symfony Process Component, and with that having an asynchronous service with a response (or exception) during request / response context.
For that you just have to call method getProcessInstance like this:
// 1. Standard way:
$process = $this->get('krlove.async')
->getProcessInstance('app.service.awesome', 'doSomething', [1, 'string', ['array']);
// and to run asynchronously
$process->start();
// ... do other things
$process->wait();
// ... do things after the process has finished
$result = $process->getOutput();
// 2. With callback function after service finishes:
$process = $this->get('krlove.async')
->getProcessInstance('app.service.awesome', 'doSomething', [1, 'string', ['array']);
// and to run asynchronously
$result = null;
$process->start(function ($res) use($process, &$result) {
$result = $process->getOutput();
});
// ... do other things
$process->wait();
// you now have result from async service call available at $result variable.
You have more information about Symfony Process Component here