Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • attr-events
  • ci-82
  • custom-routes
  • expr-lang
  • locale-wip
  • main
  • register-logging-channel
  • 0.1.37
  • v0.1.0
  • v0.1.1
  • v0.1.10
  • v0.1.11
  • v0.1.12
  • v0.1.13
  • v0.1.14
  • v0.1.15
  • v0.1.16
  • v0.1.17
  • v0.1.18
  • v0.1.19
  • v0.1.2
  • v0.1.20
  • v0.1.21
  • v0.1.22
  • v0.1.23
  • v0.1.24
  • v0.1.25
  • v0.1.26
  • v0.1.27
  • v0.1.28
  • v0.1.29
  • v0.1.3
  • v0.1.30
  • v0.1.31
  • v0.1.32
  • v0.1.33
  • v0.1.34
  • v0.1.35
  • v0.1.36
  • v0.1.38
  • v0.1.39
  • v0.1.4
  • v0.1.40
  • v0.1.41
  • v0.1.42
  • v0.1.43
  • v0.1.44
  • v0.1.45
  • v0.1.46
  • v0.1.47
  • v0.1.48
  • v0.1.49
  • v0.1.5
  • v0.1.50
  • v0.1.51
  • v0.1.52
  • v0.1.53
  • v0.1.54
  • v0.1.55
  • v0.1.56
  • v0.1.57
  • v0.1.58
  • v0.1.59
  • v0.1.6
  • v0.1.60
  • v0.1.61
  • v0.1.62
  • v0.1.63
  • v0.1.64
  • v0.1.65
  • v0.1.66
  • v0.1.67
  • v0.1.68
  • v0.1.69
  • v0.1.7
  • v0.1.70
  • v0.1.71
  • v0.1.72
  • v0.1.73
  • v0.1.74
  • v0.1.75
  • v0.1.76
  • v0.1.77
  • v0.1.78
  • v0.1.79
  • v0.1.8
  • v0.1.80
  • v0.1.81
  • v0.1.82
  • v0.1.83
  • v0.1.84
  • v0.1.85
  • v0.1.9
93 results

Target

Select target project
No results found
Select Git revision
  • attr-events
  • ci-82
  • custom-routes
  • expr-lang
  • locale-wip
  • main
  • register-logging-channel
  • 0.1.37
  • v0.1.0
  • v0.1.1
  • v0.1.10
  • v0.1.11
  • v0.1.12
  • v0.1.13
  • v0.1.14
  • v0.1.15
  • v0.1.16
  • v0.1.17
  • v0.1.18
  • v0.1.19
  • v0.1.2
  • v0.1.20
  • v0.1.21
  • v0.1.22
  • v0.1.23
  • v0.1.24
  • v0.1.25
  • v0.1.26
  • v0.1.27
  • v0.1.28
  • v0.1.29
  • v0.1.3
  • v0.1.30
  • v0.1.31
  • v0.1.32
  • v0.1.33
  • v0.1.34
  • v0.1.35
  • v0.1.36
  • v0.1.38
  • v0.1.39
  • v0.1.4
  • v0.1.40
  • v0.1.41
  • v0.1.42
  • v0.1.43
  • v0.1.44
  • v0.1.45
  • v0.1.46
  • v0.1.47
  • v0.1.48
  • v0.1.49
  • v0.1.5
  • v0.1.50
  • v0.1.51
  • v0.1.52
  • v0.1.53
  • v0.1.54
  • v0.1.55
  • v0.1.56
  • v0.1.57
  • v0.1.58
  • v0.1.59
  • v0.1.6
  • v0.1.60
  • v0.1.61
  • v0.1.62
  • v0.1.63
  • v0.1.64
  • v0.1.65
  • v0.1.66
  • v0.1.67
  • v0.1.68
  • v0.1.69
  • v0.1.7
  • v0.1.70
  • v0.1.71
  • v0.1.72
  • v0.1.73
  • v0.1.74
  • v0.1.75
  • v0.1.76
  • v0.1.77
  • v0.1.78
  • v0.1.79
  • v0.1.8
  • v0.1.80
  • v0.1.81
  • v0.1.82
  • v0.1.83
  • v0.1.84
  • v0.1.85
  • v0.1.9
93 results
Show changes
Commits on Source (8)
#!/usr/bin/env php
<?php
###############################################################################################
# Moves the DbpRelayCoreBundle to bottom of the array in `config/bundles.php`.
###############################################################################################
//##############################################################################################
// Moves the DbpRelayCoreBundle to bottom of the array in `config/bundles.php`.
//##############################################################################################
// read the entire string
$str = file_get_contents('config/bundles.php');
$coreBundleString = " Dbp\Relay\CoreBundle\DbpRelayCoreBundle::class => ['all' => true],";
$str = str_replace($coreBundleString . "\n", '', $str);
$str = str_replace('];', $coreBundleString . "\n];", $str);
$str = str_replace($coreBundleString."\n", '', $str);
$str = str_replace('];', $coreBundleString."\n];", $str);
// write the entire string
file_put_contents('config/bundles.php', $str);
......@@ -3,7 +3,7 @@
"type": "symfony-bundle",
"license": "AGPL-3.0-or-later",
"require": {
"php": "^7.3",
"php": "^7.3 || ^8.0",
"ext-fileinfo": "*",
"ext-json": "*",
"api-platform/core": "^2.6.3",
......@@ -29,8 +29,8 @@
"require-dev": {
"brainmaestro/composer-git-hooks": "^2.8",
"friendsofphp/php-cs-fixer": "^3.0",
"phpstan/phpstan": "^0.12.33",
"phpstan/phpstan-phpunit": "^0.12.13",
"phpstan/phpstan": "^1.0.0",
"phpstan/phpstan-phpunit": "^1.0.0",
"symfony/browser-kit": "^5.3",
"symfony/http-client": "^5.3",
"symfony/phpunit-bridge": "^5.3",
......
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "83accfd991b38ee637acc3a0cade2f17",
"content-hash": "34f15df2aa0f926b4054d2e5b18d4a63",
"packages": [
{
"name": "api-platform/core",
......@@ -6623,16 +6623,16 @@
},
{
"name": "nikic/php-parser",
"version": "v4.13.0",
"version": "v4.13.1",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "50953a2691a922aa1769461637869a0a2faa3f53"
"reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53",
"reference": "50953a2691a922aa1769461637869a0a2faa3f53",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd",
"reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd",
"shasum": ""
},
"require": {
......@@ -6673,9 +6673,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0"
"source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1"
},
"time": "2021-09-20T12:20:58+00:00"
"time": "2021-11-03T20:52:16+00:00"
},
{
"name": "openlss/lib-array2xml",
......@@ -6784,16 +6784,16 @@
},
{
"name": "phpstan/phpstan",
"version": "0.12.99",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "b4d40f1d759942f523be267a1bab6884f46ca3f7"
"reference": "cb317029197236c571c1b9305b8dd12850d8d85c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/b4d40f1d759942f523be267a1bab6884f46ca3f7",
"reference": "b4d40f1d759942f523be267a1bab6884f46ca3f7",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/cb317029197236c571c1b9305b8dd12850d8d85c",
"reference": "cb317029197236c571c1b9305b8dd12850d8d85c",
"shasum": ""
},
"require": {
......@@ -6809,7 +6809,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.12-dev"
"dev-master": "1.0-dev"
}
},
"autoload": {
......@@ -6824,7 +6824,7 @@
"description": "PHPStan - PHP Static Analysis Tool",
"support": {
"issues": "https://github.com/phpstan/phpstan/issues",
"source": "https://github.com/phpstan/phpstan/tree/0.12.99"
"source": "https://github.com/phpstan/phpstan/tree/1.1.1"
},
"funding": [
{
......@@ -6844,38 +6844,39 @@
"type": "tidelift"
}
],
"time": "2021-09-12T20:09:55+00:00"
"time": "2021-11-06T22:46:47+00:00"
},
{
"name": "phpstan/phpstan-phpunit",
"version": "0.12.22",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-phpunit.git",
"reference": "7c01ef93bf128b4ac8bdad38c54b2a4fd6b0b3cc"
"reference": "9eb88c9f689003a8a2a5ae9e010338ee94dc39b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/7c01ef93bf128b4ac8bdad38c54b2a4fd6b0b3cc",
"reference": "7c01ef93bf128b4ac8bdad38c54b2a4fd6b0b3cc",
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/9eb88c9f689003a8a2a5ae9e010338ee94dc39b3",
"reference": "9eb88c9f689003a8a2a5ae9e010338ee94dc39b3",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0",
"phpstan/phpstan": "^0.12.92"
"phpstan/phpstan": "^1.0"
},
"conflict": {
"phpunit/phpunit": "<7.0"
},
"require-dev": {
"nikic/php-parser": "^4.13.0",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/phpstan-strict-rules": "^0.12.6",
"phpstan/phpstan-strict-rules": "^1.0",
"phpunit/phpunit": "^9.5"
},
"type": "phpstan-extension",
"extra": {
"branch-alias": {
"dev-master": "0.12-dev"
"dev-master": "1.0-dev"
},
"phpstan": {
"includes": [
......@@ -6896,9 +6897,9 @@
"description": "PHPUnit extensions and rules for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
"source": "https://github.com/phpstan/phpstan-phpunit/tree/0.12.22"
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.0.0"
},
"time": "2021-08-12T10:53:43+00:00"
"time": "2021-10-14T08:03:54+00:00"
},
{
"name": "sebastian/diff",
......@@ -7577,16 +7578,16 @@
},
{
"name": "vimeo/psalm",
"version": "4.11.2",
"version": "4.12.0",
"source": {
"type": "git",
"url": "https://github.com/vimeo/psalm.git",
"reference": "6fba5eb554f9507b72932f9c75533d8af593688d"
"reference": "e42bc4a23f67acba28a23bb09c348e2ff38a1d87"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vimeo/psalm/zipball/6fba5eb554f9507b72932f9c75533d8af593688d",
"reference": "6fba5eb554f9507b72932f9c75533d8af593688d",
"url": "https://api.github.com/repos/vimeo/psalm/zipball/e42bc4a23f67acba28a23bb09c348e2ff38a1d87",
"reference": "e42bc4a23f67acba28a23bb09c348e2ff38a1d87",
"shasum": ""
},
"require": {
......@@ -7610,7 +7611,7 @@
"openlss/lib-array2xml": "^1.0",
"php": "^7.1|^8",
"sebastian/diff": "^3.0 || ^4.0",
"symfony/console": "^3.4.17 || ^4.1.6 || ^5.0",
"symfony/console": "^3.4.17 || ^4.1.6 || ^5.0 || ^6.0",
"webmozart/path-util": "^2.3"
},
"provide": {
......@@ -7628,7 +7629,7 @@
"psalm/plugin-phpunit": "^0.16",
"slevomat/coding-standard": "^7.0",
"squizlabs/php_codesniffer": "^3.5",
"symfony/process": "^4.3 || ^5.0",
"symfony/process": "^4.3 || ^5.0 || ^6.0",
"weirdan/prophecy-shim": "^1.0 || ^2.0"
},
"suggest": {
......@@ -7676,9 +7677,9 @@
],
"support": {
"issues": "https://github.com/vimeo/psalm/issues",
"source": "https://github.com/vimeo/psalm/tree/4.11.2"
"source": "https://github.com/vimeo/psalm/tree/4.12.0"
},
"time": "2021-10-26T17:28:17+00:00"
"time": "2021-11-06T10:31:17+00:00"
},
{
"name": "webmozart/path-util",
......@@ -7728,6 +7729,7 @@
"issues": "https://github.com/webmozart/path-util/issues",
"source": "https://github.com/webmozart/path-util/tree/2.3.0"
},
"abandoned": "symfony/filesystem",
"time": "2015-12-17T08:42:14+00:00"
}
],
......@@ -7737,7 +7739,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "^7.3",
"php": "^7.3 || ^8.0",
"ext-fileinfo": "*",
"ext-json": "*"
},
......
# Locks
Locks are used to provide exclusive access to a shared resource.
The Relay API gateway optionally requires a locking backend. By default it uses
a local backend which is only suitable if all processes run on the same server.
Once your API runs on multiple servers you need to configure a remote/shared
locking backend.
## Configuration
In the bundle configuration set the `lock_dsn` key to a DSN supported by the
[Symfony Lock component](https://symfony.com/doc/current/components/lock.html)
At the moment we only support RedisStore and PdoStore:
### Redis
```yaml
# config/packages/dbp_relay_core.yaml
dbp_relay_core:
# redis[s]://[pass@][ip|host|socket[:port]]
lock_dsn: 'redis://localhost:6379'
```
### PDO
```yaml
# config/packages/dbp_relay_core.yaml
dbp_relay_core:
lock_dsn: 'mysql://user:secret@mariadb:3306/dbname'
```
This will create a `lock_keys` table in your database where the lock information
will be stored.
## Usage in Code
```php
// Retrieve a LockFactory instance via dependency injection
public function __construct(LockFactory $lockFactory) {
// Make sure to prefix the resource string to avoid conflicts with other bundles
$lock = $lockFactory->createLock(/* ... */);
// ...
}
```
For more information see
https://symfony.com/doc/current/components/lock.html#usage
\ No newline at end of file
......@@ -16,14 +16,48 @@ This requires two extra deployment related tasks:
In the bundle configuration set the `queue_dsn` key to a DSN supported by the
[Symfony messenger component](https://symfony.com/doc/current/messenger.html)
At the moment we only support the redis transport.
At the moment we only support the redis and doctrine transports:
Example:
### Redis
This transport requires the Redis PHP extension (>=4.3) and a running Redis server (^5.0).
```yaml
# config/packages/dbp_relay_core.yaml
dbp_relay_core:
# redis[s]://[pass@][ip|host|socket[:port]]
queue_dsn: 'redis://localhost:6379'
```
This creates a redis stream automatically when active.
### Doctrine
In case of doctrine you have to install `symfony/doctrine-messenger`
```bash
composer require symfony/doctrine-messenger
```
then create a doctrine connection and point the `queue_dsn` to that connection:
```yaml
queue_dsn: 'redis://localhost:6379'
# config/packages/doctrine.yaml
doctrine:
dbal:
connections:
my-queue-connection-name:
url: 'mysql://db:secret@mariadb:3306/db'
```
```yaml
# config/packages/dbp_relay_core.yaml
dbp_relay_core:
queue_dsn: 'doctrine://my-queue-connection-name'
```
I will automatically create a new database table when active.
## Run the workers
Start a worker using
......@@ -76,4 +110,13 @@ autorestart=true
process_name=%(program_name)s_%(process_num)02d
```
Change `user` to the Unix user on your server.
\ No newline at end of file
Change `user` to the Unix user on your server.
## Testing your Setup
After everything is set up you can create a few dummy tasks and see if they get
handled by the workers:
```bash
./bin/console dbp:relay:core:queue:test --count 10 --delay 3
```
......@@ -9,7 +9,7 @@ parameters:
- tests
bootstrapFiles:
- vendor/bin/.phpunit/phpunit-9-0/vendor/autoload.php
excludes_analyse:
excludePaths:
- tests/bootstrap.php
- src/Swagger/DocumentationNormalizer.php
ignoreErrors:
......
......@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Dbp\Relay\CoreBundle\DependencyInjection;
use Dbp\Relay\CoreBundle\Queue\TestMessage;
use Dbp\Relay\CoreBundle\Queue\Utils as QueueUtils;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
......@@ -163,6 +165,10 @@ class DbpRelayCoreExtension extends ConfigurableExtension implements PrependExte
]),
]);
$routing = [
TestMessage::class => QueueUtils::QUEUE_TRANSPORT_NAME,
];
// https://symfony.com/doc/4.4/messenger.html#transports-async-queued-messages
$messengerTransportDsn = $config['queue_dsn'];
if ($messengerTransportDsn === '') {
......@@ -170,36 +176,28 @@ class DbpRelayCoreExtension extends ConfigurableExtension implements PrependExte
$messengerTransportDsn = $config['messenger_transport_dsn'];
}
if ($container->hasParameter('dbp_api.messenger_routing')) {
$routing = [];
$routing = array_merge($routing, $container->getParameter('dbp_api.messenger_routing'));
if ($messengerTransportDsn === '') {
throw new \RuntimeException('A bundle requires a worker queue: set "queue_dsn" in the core bundle config');
}
$container->loadFromExtension('framework', [
'messenger' => [
'transports' => [
'async' => $messengerTransportDsn,
],
'routing' => $routing,
],
]);
} else {
// By always setting a transport, we ensure that the messenger commands work in all cases, even if they
// are not stricly needed
if ($messengerTransportDsn === '') {
$messengerTransportDsn = 'in-memory://dummy-queue-not-configured';
}
$container->loadFromExtension('framework', [
'messenger' => [
'transports' => [
'async' => $messengerTransportDsn,
],
],
]);
}
$container->loadFromExtension('framework', [
'messenger' => [
'transports' => [
QueueUtils::QUEUE_TRANSPORT_NAME => $messengerTransportDsn,
],
'routing' => $routing,
],
]);
// https://symfony.com/doc/5.3/components/lock.html
$lockDsn = $config['lock_dsn'];
if ($lockDsn !== '') {
......
<?php
declare(strict_types=1);
namespace Dbp\Relay\CoreBundle\Queue;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Stamp\DelayStamp;
class TestCommand extends Command implements LoggerAwareInterface
{
use LoggerAwareTrait;
protected static $defaultName = 'dbp:relay:core:queue:test';
/**
* @var MessageBusInterface
*/
private $bus;
public function __construct(MessageBusInterface $bus)
{
parent::__construct();
$this->bus = $bus;
}
protected function configure()
{
$this->setDescription('Start some dummy tasks for testing');
$this->addOption('count', null, InputArgument::OPTIONAL, 'The number of messages to send', 1);
$this->addOption('delay', null, InputArgument::OPTIONAL, 'Delay in seconds', 0);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$count = (int) $input->getOption('count');
$delay = (int) $input->getOption('delay');
for ($i = 0; $i < $count; ++$i) {
if ($delay !== 0) {
$envelope = new Envelope(new TestMessage(), [new DelayStamp($delay * 1000)]);
} else {
$envelope = new Envelope(new TestMessage());
}
$this->bus->dispatch($envelope);
}
return Command::SUCCESS;
}
}
<?php
declare(strict_types=1);
namespace Dbp\Relay\CoreBundle\Queue;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
class TestHandler implements MessageHandlerInterface, LoggerAwareInterface
{
use LoggerAwareTrait;
public function __invoke(TestMessage $message)
{
$this->logger->info('Handled test message');
}
}
<?php
declare(strict_types=1);
namespace Dbp\Relay\CoreBundle\Queue;
class TestMessage
{
}
......@@ -56,10 +56,13 @@ class TransportFactoryDecorator implements TransportFactoryInterface, LoggerAwar
// Use the new recommended default:
// https://github.com/symfony/symfony/pull/42163
$options['delete_after_ack'] = true;
} elseif (strpos($dsn, 'doctrine://') === 0) {
$options['table_name'] = 'core_queue_messages';
$options['queue_name'] = 'main';
} elseif ($dsn === 'in-memory://dummy-queue-not-configured') {
// This is used when no queue is configured, so allow it.
} else {
throw new \Exception('Only redis currently supported as a messenger transport (current DSN: '.$dsn.')');
throw new \Exception('Only redis and doctrine currently supported as a queue transport (current DSN: '.$dsn.')');
}
}
......
......@@ -29,5 +29,13 @@ services:
autoconfigure: true
Dbp\Relay\CoreBundle\Queue\RestartCommand:
autowire: true
autoconfigure: true
Dbp\Relay\CoreBundle\Queue\TestCommand:
autowire: true
autoconfigure: true
Dbp\Relay\CoreBundle\Queue\TestHandler:
autowire: true
autoconfigure: true
\ No newline at end of file