Skip to content

Commit b10599b

Browse files
committed
[symfony] Async commands.
0 parents  commit b10599b

11 files changed

+394
-0
lines changed

Diff for: .gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*~
2+
/composer.lock
3+
/composer.phar
4+
/phpunit.xml
5+
/vendor/
6+
/.idea/

Diff for: .travis.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
sudo: false
2+
3+
git:
4+
depth: 10
5+
6+
language: php
7+
8+
php:
9+
- '5.6'
10+
- '7.0'
11+
12+
cache:
13+
directories:
14+
- $HOME/.composer/cache
15+
16+
install:
17+
- composer self-update
18+
- composer install --prefer-source
19+
20+
script:
21+
- vendor/bin/phpunit --exclude-group=functional

Diff for: Commands.php

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Enqueue\AsyncCommand;
4+
5+
final class Commands
6+
{
7+
const RUN_COMMAND = 'run_command';
8+
}

Diff for: DependencyInjection/AsyncCommandExtension.php

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Enqueue\AsyncCommand\DependencyInjection;
4+
5+
use Symfony\Component\Config\FileLocator;
6+
use Symfony\Component\DependencyInjection\ContainerBuilder;
7+
use Symfony\Component\DependencyInjection\Extension\Extension;
8+
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
9+
10+
class AsyncCommandExtension extends Extension
11+
{
12+
/**
13+
* {@inheritdoc}
14+
*/
15+
public function load(array $configs, ContainerBuilder $container)
16+
{
17+
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
18+
$loader->load('services.yml');
19+
}
20+
}

Diff for: LICENSE

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2018 Max Kotliar
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

Diff for: README.md

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Symfony Async Command.
2+
3+
[![Gitter](https://badges.gitter.im/php-enqueue/Lobby.svg)](https://gitter.im/php-enqueue/Lobby)
4+
[![Build Status](https://travis-ci.org/php-enqueue/async-command.png?branch=master)](https://travis-ci.org/php-enqueue/async-command)
5+
[![Total Downloads](https://poser.pugx.org/enqueue/async-command/d/total.png)](https://packagist.org/packages/enqueue/async-command)
6+
[![Latest Stable Version](https://poser.pugx.org/enqueue/async-command/version.png)](https://packagist.org/packages/enqueue/async-command)
7+
8+
It contains an extension to Symfony's [Console](https://symfony.com/doc/current/components/console.html) component.
9+
It allows to execute Symfony's command async by sending the request to message queue.
10+
11+
## Resources
12+
13+
* [Site](https://enqueue.forma-pro.com/)
14+
* [Documentation](https://github.com/php-enqueue/enqueue-dev/blob/master/docs/index.md)
15+
* [Questions](https://gitter.im/php-enqueue/Lobby)
16+
* [Issue Tracker](https://github.com/php-enqueue/enqueue-dev/issues)
17+
18+
## Developed by Forma-Pro
19+
20+
Forma-Pro is a full stack development company which interests also spread to open source development.
21+
Being a team of strong professionals we have an aim an ability to help community by developing cutting edge solutions in the areas of e-commerce, docker & microservice oriented architecture where we have accumulated a huge many-years experience.
22+
Our main specialization is Symfony framework based solution, but we are always looking to the technologies that allow us to do our job the best way. We are committed to creating solutions that revolutionize the way how things are developed in aspects of architecture & scalability.
23+
24+
If you have any questions and inquires about our open source development, this product particularly or any other matter feel free to contact at [email protected]
25+
26+
## License
27+
28+
It is released under the [MIT License](LICENSE).

Diff for: Resources/config/services.yml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
services:
2+
enqueue.async_command.run_command_processor:
3+
class: 'Enqueue\AsyncCommand\RunCommandProcessor'
4+
public: public
5+
arguments:
6+
- '%kernel.root_dir%/..'
7+
tags:
8+
- { name: 'enqueue.client.processor' }

Diff for: RunCommand.php

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
namespace Enqueue\AsyncCommand;
4+
5+
final class RunCommand implements \JsonSerializable
6+
{
7+
/**
8+
* @var string
9+
*/
10+
private $command;
11+
12+
/**
13+
* @var string[]
14+
*/
15+
private $arguments;
16+
17+
/**
18+
* @var string[]
19+
*/
20+
private $options;
21+
22+
/**
23+
* @param string $command
24+
* @param string[] $arguments
25+
* @param string[] $options
26+
*/
27+
public function __construct($command, array $arguments = [], array $options = [])
28+
{
29+
$this->command = $command;
30+
$this->arguments = $arguments;
31+
$this->options = $options;
32+
}
33+
34+
/**
35+
* @return string
36+
*/
37+
public function getCommandLine()
38+
{
39+
$optionsString = '';
40+
foreach ($this->options as $name => $value) {
41+
$optionsString .= " $name=$value";
42+
}
43+
$optionsString = trim($optionsString);
44+
45+
$argumentsString = '';
46+
foreach ($this->arguments as $value) {
47+
$argumentsString .= " $value";
48+
}
49+
$argumentsString = trim($argumentsString);
50+
51+
return trim($this->command.' '.$argumentsString.' '.$optionsString);
52+
}
53+
54+
/**
55+
* @return string
56+
*/
57+
public function getCommand(): string
58+
{
59+
return $this->command;
60+
}
61+
62+
/**
63+
* @return string[]
64+
*/
65+
public function getArguments(): array
66+
{
67+
return $this->arguments;
68+
}
69+
70+
/**
71+
* @return string[]
72+
*/
73+
public function getOptions(): array
74+
{
75+
return $this->options;
76+
}
77+
78+
public function jsonSerialize()
79+
{
80+
return [
81+
'command' => $this->command,
82+
'arguments' => $this->arguments,
83+
'options' => $this->options,
84+
];
85+
}
86+
87+
/**
88+
* @param string $json
89+
*
90+
* @return self
91+
*/
92+
public static function jsonUnserialize($json)
93+
{
94+
$data = json_decode($json, true);
95+
if (JSON_ERROR_NONE !== json_last_error()) {
96+
throw new \InvalidArgumentException(sprintf(
97+
'The malformed json given. Error %s and message %s',
98+
json_last_error(),
99+
json_last_error_msg()
100+
));
101+
}
102+
103+
return new self($data['command'], $data['arguments'], $data['options']);
104+
}
105+
}

Diff for: RunCommandProcessor.php

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Enqueue\AsyncCommand;
4+
5+
use Enqueue\Client\CommandSubscriberInterface;
6+
use Enqueue\Consumption\Result;
7+
use Interop\Queue\PsrContext;
8+
use Interop\Queue\PsrMessage;
9+
use Interop\Queue\PsrProcessor;
10+
use Symfony\Component\Process\PhpExecutableFinder;
11+
use Symfony\Component\Process\Process;
12+
13+
final class RunCommandProcessor implements PsrProcessor, CommandSubscriberInterface
14+
{
15+
/**
16+
* @var string
17+
*/
18+
private $projectDir;
19+
20+
public function __construct($projectDir)
21+
{
22+
$this->projectDir = $projectDir;
23+
}
24+
25+
public function process(PsrMessage $message, PsrContext $context)
26+
{
27+
$command = RunCommand::jsonUnserialize($message->getBody());
28+
29+
$phpBin = (new PhpExecutableFinder())->find();
30+
$consoleBin = file_exists($this->projectDir.'/bin/console') ? './bin/console' : './app/console';
31+
32+
$process = new Process($phpBin.' '.$consoleBin.' '.$command->getCommandLine(), $this->projectDir);
33+
34+
$process->run();
35+
36+
$result = new RunCommandResult($process->getExitCode(), $process->getOutput(), $process->getErrorOutput());
37+
38+
return Result::reply($context->createMessage(json_encode($result)));
39+
}
40+
41+
public static function getSubscribedCommand()
42+
{
43+
return [
44+
'processorName' => Commands::RUN_COMMAND,
45+
'queueName' => Commands::RUN_COMMAND,
46+
'queueNameHardcoded' => true,
47+
'exclusive' => true,
48+
];
49+
}
50+
}

Diff for: RunCommandResult.php

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
namespace Enqueue\AsyncCommand;
4+
5+
final class RunCommandResult implements \JsonSerializable
6+
{
7+
/**
8+
* @var int
9+
*/
10+
private $exitCode;
11+
12+
/**
13+
* @var string
14+
*/
15+
private $output;
16+
17+
/**
18+
* @var string
19+
*/
20+
private $errorOutput;
21+
22+
/**
23+
* @param int $exitCode
24+
* @param string $output
25+
* @param string $errorOutput
26+
*/
27+
public function __construct($exitCode, $output, $errorOutput)
28+
{
29+
$this->exitCode = $exitCode;
30+
$this->output = $output;
31+
$this->errorOutput = $errorOutput;
32+
}
33+
34+
/**
35+
* @return int
36+
*/
37+
public function getExitCode(): int
38+
{
39+
return $this->exitCode;
40+
}
41+
42+
/**
43+
* @return string
44+
*/
45+
public function getOutput(): string
46+
{
47+
return $this->output;
48+
}
49+
50+
/**
51+
* @return string
52+
*/
53+
public function getErrorOutput(): string
54+
{
55+
return $this->errorOutput;
56+
}
57+
58+
public function jsonSerialize()
59+
{
60+
return [
61+
'exitCode' => $this->exitCode,
62+
'output' => $this->output,
63+
'errorOutput' => $this->errorOutput,
64+
];
65+
}
66+
67+
/**
68+
* @param string $json
69+
*
70+
* @return self
71+
*/
72+
public static function jsonUnserialize($json)
73+
{
74+
$data = json_decode($json, true);
75+
if (JSON_ERROR_NONE !== json_last_error()) {
76+
throw new \InvalidArgumentException(sprintf(
77+
'The malformed json given. Error %s and message %s',
78+
json_last_error(),
79+
json_last_error_msg()
80+
));
81+
}
82+
83+
return new self($data['exitCode'], $data['output'], $data['errorOutput']);
84+
}
85+
}

0 commit comments

Comments
 (0)