Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/vendor
/tests/__cache
/.phpunit.result.cache
.idea
vendor
tests/__cache
.phpunit.result.cache
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"spiral/roadrunner-worker": ">=2.0.3",
"spiral/goridge": "^3.0",
"symfony/psr-http-message-bridge": "^1.1 || ^2.0",
"psr/log": "^1.1"
"psr/log": "^1.1",
"temporal/sdk": "^1.0"
},
"suggest": {
"nyholm/psr7": "For a super lightweight PSR-7/17 implementation",
Expand Down
65 changes: 57 additions & 8 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Baldinof\RoadRunnerBundle\Command\WorkerCommand;
use Baldinof\RoadRunnerBundle\Contract\ActivityInterface;
use Baldinof\RoadRunnerBundle\Contract\WorkflowInterface;
use Baldinof\RoadRunnerBundle\DependencyInjection\BaldinofRoadRunnerExtension;
use Baldinof\RoadRunnerBundle\Helpers\RPCFactory;
use Baldinof\RoadRunnerBundle\Http\KernelHandler;
Expand All @@ -16,22 +18,31 @@
use Baldinof\RoadRunnerBundle\RoadRunnerBridge\HttpFoundationWorker;
use Baldinof\RoadRunnerBundle\RoadRunnerBridge\HttpFoundationWorkerInterface;
use Baldinof\RoadRunnerBundle\Worker\Dependencies;
use Baldinof\RoadRunnerBundle\Worker\Worker;
use Baldinof\RoadRunnerBundle\Worker\HttpWorker;
use Baldinof\RoadRunnerBundle\Worker\TemporalWorker;
use Baldinof\RoadRunnerBundle\Worker\WorkerInterface;
use Baldinof\RoadRunnerBundle\Worker\WorkerResolver;
use Baldinof\RoadRunnerBundle\Worker\WorkerResolverInterface;
use Psr\Log\LoggerInterface;
use Spiral\Goridge\RPC\RPCInterface;
use Spiral\RoadRunner\Environment;
use Spiral\RoadRunner\EnvironmentInterface;
use Spiral\RoadRunner\Http\HttpWorker;
use Spiral\RoadRunner\Http\HttpWorkerInterface;
use Spiral\RoadRunner\Http\HttpWorker as RoadRunnerHttpWorker;
use Spiral\RoadRunner\Http\HttpWorkerInterface as RoadRunnerHttpWorkerInterface;
use Spiral\RoadRunner\Metrics\Metrics;
use Spiral\RoadRunner\Metrics\MetricsInterface;
use Spiral\RoadRunner\Worker as RoadRunnerWorker;
use Spiral\RoadRunner\WorkerInterface as RoadRunnerWorkerInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Temporal\Client\GRPC\ServiceClient;
use Temporal\Client\WorkflowClient;
use Temporal\Client\WorkflowClientInterface;
use Temporal\Worker\WorkerFactoryInterface;
use Temporal\WorkerFactory;
use function function_exists;

// Polyfill of the `service()` function introduced in Symfony 5.1 when using older version
if (!\function_exists('Symfony\Component\DependencyInjection\Loader\Configurator\service')) {
if (!function_exists('Symfony\Component\DependencyInjection\Loader\Configurator\service')) {
function service(string $id): ReferenceConfigurator
{
return ref($id);
Expand All @@ -52,7 +63,7 @@ function service(string $id): ReferenceConfigurator
->factory([RoadRunnerWorker::class, 'createFromEnvironment'])
->args([service(EnvironmentInterface::class), '%baldinof_road_runner.intercept_side_effect%']);

$services->set(HttpWorkerInterface::class, HttpWorker::class)
$services->set(RoadRunnerHttpWorkerInterface::class, RoadRunnerHttpWorker::class)
->args([service(RoadRunnerWorkerInterface::class)]);

$services->set(RPCInterface::class)
Expand All @@ -64,9 +75,9 @@ function service(string $id): ReferenceConfigurator

// Bundle services
$services->set(HttpFoundationWorkerInterface::class, HttpFoundationWorker::class)
->args([service(HttpWorkerInterface::class)]);
->args([service(RoadRunnerHttpWorkerInterface::class)]);

$services->set(WorkerInterface::class, Worker::class)
$services->set(HttpWorker::class)
->public() // Manually retrieved on the DIC in the Worker if the kernel has been rebooted
->tag('monolog.logger', ['channel' => BaldinofRoadRunnerExtension::MONOLOG_CHANNEL])
->args([
Expand All @@ -75,6 +86,19 @@ function service(string $id): ReferenceConfigurator
service(HttpFoundationWorkerInterface::class),
]);

$services->set(WorkerFactoryInterface::class)
->factory([WorkerFactory::class, 'create']);

$services->set(TemporalWorker::class)
->public() // Manually retrieved on the DIC in the Worker if the kernel has been rebooted
->tag('monolog.logger', ['channel' => BaldinofRoadRunnerExtension::MONOLOG_CHANNEL])
->args([
service('kernel'),
service(WorkerFactoryInterface::class),
tagged_iterator('baldinof_road_runner.temporal_workflows'),
tagged_iterator('baldinof_road_runner.temporal_activities'),
]);

$services->set(Dependencies::class)
->public() // Manually retrieved on the DIC in the Worker if the kernel has been rebooted
->args([
Expand All @@ -83,8 +107,18 @@ function service(string $id): ReferenceConfigurator
service(EventDispatcherInterface::class),
]);

$services->set(WorkerResolverInterface::class, WorkerResolver::class)
->args([
service(EnvironmentInterface::class),
service(HttpWorker::class),
service(TemporalWorker::class),
]);

$services->set(WorkerCommand::class)
->args([service(WorkerInterface::class)])
->args([
service(WorkerResolverInterface::class),
service(EnvironmentInterface::class)
])
->autoconfigure();

$services->set(KernelHandler::class)
Expand All @@ -105,4 +139,19 @@ function service(string $id): ReferenceConfigurator
service(StreamedResponseListener::class.'.inner'),
'%env(default::RR_MODE)%',
]);

$services
->set(WorkflowClientInterface::class, WorkflowClient::class)
->args([
service(ServiceClient::class)
])
;

$services
->set(ServiceClient::class)
->factory([ServiceClient::class, 'create'])
->args([
'localhost:7233'
])
;
};
52 changes: 14 additions & 38 deletions src/Command/WorkerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,68 +4,44 @@

namespace Baldinof\RoadRunnerBundle\Command;

use Baldinof\RoadRunnerBundle\Worker\WorkerInterface;
use Spiral\RoadRunner\Environment\Mode;
use Baldinof\RoadRunnerBundle\Worker\WorkerResolverInterface;
use Spiral\RoadRunner\EnvironmentInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

final class WorkerCommand extends Command
{
protected static $defaultName = 'baldinof:roadrunner:worker';

private WorkerInterface $worker;
private WorkerResolverInterface $workerResolver;
private EnvironmentInterface $environment;

public function __construct(WorkerInterface $worker)
public function __construct(
WorkerResolverInterface $workerResolver,
EnvironmentInterface $environment
)
{
parent::__construct();

$this->worker = $worker;
$this->workerResolver = $workerResolver;
$this->environment = $environment;
}

public function configure(): void
{
$this
->setDescription('Run the roadrunner worker')
->setDescription('Run the roadrunner')
->setHelp(<<<EOF
This command should not be run manually but specified in a <info>.rr.yaml</info>
configuration file.
EOF);
}

protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
if (getenv('RR_MODE') !== Mode::MODE_HTTP) {
$io = new SymfonyStyle($input, $output);

$io->title('RoadRunner Bundle');
$io->error('Command baldinof:roadrunner:worker should not be run manually');
$io->writeln('You should reference this command in a <info>.rr.yaml</> configuration file, then run <info>bin/rr serve</>. Example:');
$io->writeln(<<<YAML
<comment>
http:
address: "0.0.0.0:8080"

uploads:
forbid: [".php", ".exe", ".bat"]

workers:
command: "php bin/console baldinof:roadrunner:worker"
relay: "unix://var/roadrunner.sock"

static:
dir: "public"
forbid: [".php", ".htaccess"]
</comment>
YAML);

$io->writeln('See <href=https://roadrunner.dev/>RoadRunner</> and <href=https://github.com/Baldinof/roadrunner-bundle/blob/master/README.md>baldinof/roadrunner-bundle</> documentations.');

return 1;
}

$this->worker->start();
$worker = $this->workerResolver->resolve($this->environment->getMode());
$worker->start();

return 0;
}
Expand Down
13 changes: 12 additions & 1 deletion src/DependencyInjection/BaldinofRoadRunnerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,23 @@
use Baldinof\RoadRunnerBundle\Integration\Symfony\ConfigureVarDumperListener;
use Baldinof\RoadRunnerBundle\Reboot\KernelRebootStrategyInterface;
use Baldinof\RoadRunnerBundle\Reboot\OnExceptionRebootStrategy;
use BlackfireProbe;
use Doctrine\Persistence\ManagerRegistry;
use Psr\Log\LoggerInterface;
use Sentry\State\HubInterface;
use Spiral\RoadRunner\Metrics\Collector;
use Spiral\RoadRunner\Metrics\MetricsInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Temporal\Activity\ActivityInterface;
use Temporal\Workflow\WorkflowInterface;

class BaldinofRoadRunnerExtension extends Extension
{
Expand Down Expand Up @@ -56,6 +60,13 @@ public function load(array $configs, ContainerBuilder $container): void

$container->setParameter('baldinof_road_runner.middlewares', $config['middlewares']);

$container->registerAttributeForAutoconfiguration(WorkflowInterface::class, function (ChildDefinition $definition){
$definition->addTag('baldinof_road_runner.temporal_workflows');
});
$container->registerAttributeForAutoconfiguration(ActivityInterface::class, function (ChildDefinition $definition){
$definition->addTag('baldinof_road_runner.temporal_activities');
});

$this->loadIntegrations($container, $config);

if ($config['metrics']['enabled']) {
Expand Down Expand Up @@ -86,7 +97,7 @@ private function loadIntegrations(ContainerBuilder $container, array $config): v
/** @var array */
$bundles = $container->getParameter('kernel.bundles');

if (class_exists(\BlackfireProbe::class)) {
if (class_exists(BlackfireProbe::class)) {
$container->register(BlackfireMiddleware::class);
$beforeMiddlewares[] = BlackfireMiddleware::class;
}
Expand Down
26 changes: 26 additions & 0 deletions src/Temporal/TemporalWorkerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);

namespace Baldinof\RoadRunnerBundle\Temporal;

use Temporal\Worker\WorkerFactoryInterface;
use Temporal\Worker\WorkerInterface;
use Temporal\Worker\WorkerOptions;

final class TemporalWorkerFactory
{
private WorkerFactoryInterface $workerFactory;

public function __construct(WorkerFactoryInterface $workerFactory)
{
$this->workerFactory = $workerFactory;
}

public function create(string $queue = WorkerFactoryInterface::DEFAULT_TASK_QUEUE, WorkerOptions $workerOptions = null): WorkerInterface
{
return $this->workerFactory->newWorker(
$queue,
$workerOptions
);
}
}
12 changes: 6 additions & 6 deletions src/Worker/Worker.php → src/Worker/HttpWorker.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Baldinof\RoadRunnerBundle\Worker;

use function Baldinof\RoadRunnerBundle\consumes;
use Baldinof\RoadRunnerBundle\Event\WorkerExceptionEvent;
use Baldinof\RoadRunnerBundle\Event\WorkerKernelRebootedEvent;
use Baldinof\RoadRunnerBundle\Event\WorkerStartEvent;
Expand All @@ -15,11 +14,12 @@
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\RebootableInterface;
use function Baldinof\RoadRunnerBundle\consumes;

/**
* @internal
*/
final class Worker implements WorkerInterface
final class HttpWorker implements WorkerInterface
{
private KernelInterface $kernel;
private LoggerInterface $logger;
Expand All @@ -35,7 +35,7 @@ public function __construct(
$this->logger = $logger;
$this->httpFoundationWorker = $httpFoundationWorker;

/** @var Dependencies */
/** @var Dependencies $dependencies */
$dependencies = $kernel->getContainer()->get(Dependencies::class);
$this->dependencies = $dependencies;
}
Expand Down Expand Up @@ -78,10 +78,10 @@ public function start(): void
} finally {
if ($this->kernel instanceof RebootableInterface && $this->dependencies->getKernelRebootStrategy()->shouldReboot()) {
$this->kernel->reboot(null);
/** @var Dependencies */
$deps = $this->kernel->getContainer()->get(Dependencies::class);
/** @var Dependencies $dependencies */
$dependencies = $this->kernel->getContainer()->get(Dependencies::class);

$this->dependencies = $deps;
$this->dependencies = $dependencies;
$this->dependencies->getEventDispatcher()->dispatch(new WorkerKernelRebootedEvent());
}

Expand Down
Loading