diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 3d8d32c253..bb9c6d455e 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -3,5 +3,5 @@ Contributing to Yii2 - [Report an issue](https://github.com/yiisoft/yii2/blob/master/docs/internals/report-an-issue.md) - [Translate documentation or messages](https://github.com/yiisoft/yii2/blob/master/docs/internals/translation-workflow.md) -- [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/) +- [Give us feedback or start a design discussion](https://forum.yiiframework.com/c/yii-2-0/general-discussions/16) - [Contribute to the core code or fix bugs](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md) diff --git a/.php_cs b/.php_cs index 663d77e28d..6e1c230a1c 100644 --- a/.php_cs +++ b/.php_cs @@ -1,8 +1,8 @@ queueTest; +$queue->setMessageHeaders = [ + 'header1' => 'header-value1', + 'header2' => 'header-value2', +]; +$queue->push(new TestJob()); +``` + +> Note! Existing headers will not be overwritten by default. diff --git a/docs/guide-ja/driver-db.md b/docs/guide-ja/driver-db.md index 360375ec6e..744b1e8878 100644 --- a/docs/guide-ja/driver-db.md +++ b/docs/guide-ja/driver-db.md @@ -84,7 +84,7 @@ CREATE INDEX priority ON queue (priority); マイグレーションが [src/drivers/db/migrations](../../src/drivers/db/migrations) にありますので、利用して下さい。 アプリケーションにマイグレーションを追加するためには、コンソールの構成ファイルを編集して、 -[名前空間化されたマイグレーション](http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#namespaced-migrations) を構成して下さい。 +[名前空間化されたマイグレーション](https://www.yiiframework.com/doc-2.0/guide-db-migrations.html#namespaced-migrations) を構成して下さい。 ```php 'controllerMap' => [ diff --git a/docs/guide-ja/retryable.md b/docs/guide-ja/retryable.md index 01ab246925..f490440099 100644 --- a/docs/guide-ja/retryable.md +++ b/docs/guide-ja/retryable.md @@ -9,7 +9,7 @@ 後者の場合においては、いくらか時間をおいて再試行できる方が良いでしょう。そうするための方法がいくつかあります。 > **Note:** 下記で説明する `ttr` 機能を使用するためには -> [PHP プロセス制御 (pcntl) 拡張](http://php.net/manual/ja/book.pcntl.php) がインストールされている必要があり、 +> [PHP プロセス制御 (pcntl) 拡張](https://php.net/manual/ja/book.pcntl.php) がインストールされている必要があり、 > ワーカのコマンドが `--isolate` オプション (デフォルトで有効になっています) を使用する必要があります。 再試行のオプション diff --git a/docs/guide-ja/usage.md b/docs/guide-ja/usage.md index b0a39a43ff..838573a8e4 100644 --- a/docs/guide-ja/usage.md +++ b/docs/guide-ja/usage.md @@ -166,7 +166,7 @@ Yii::$app->queue->on(Queue::EVENT_AFTER_ERROR, function ($event) { イベントのロギング ------------------ -queue コンポーネントは [Yii の内蔵ロガー](http://www.yiiframework.com/doc-2.0/guide-runtime-logging.html) +queue コンポーネントは [Yii の内蔵ロガー](https://www.yiiframework.com/doc-2.0/guide-runtime-logging.html) を使ってキューのイベントを記録する `LogBehavior` を提供しています。 これを有効にするためには、queue コンポーネントを以下のように構成するだけです。 diff --git a/docs/guide-ru/driver-amqp-interop.md b/docs/guide-ru/driver-amqp-interop.md index 4cfd858ebd..146401e505 100644 --- a/docs/guide-ru/driver-amqp-interop.md +++ b/docs/guide-ru/driver-amqp-interop.md @@ -69,3 +69,20 @@ yii queue/listen - `--verbose`, `-v`: состояние обработки заданий выводится в консоль. - `--isolate`: каждое задание выполняется в отдельном дочернем процессе. - `--color`: подсветка вывода в режиме `--verbose`. + +## Работа с заголовками в сообщениях + +Для отправки произвольных заголовков в очередь, вместе с сообщением, можно использовать атрибут `setMessageHeaders`. + +Например: + +```php +$queue = Yii::$app->queueTest; +$queue->setMessageHeaders = [ + 'header1' => 'header-value1', + 'header2' => 'header-value2', +]; +$queue->push(new TestJob()); +``` + +> Обратите внимание! Существующие заголовки не будут перезаписаны по умолчанию. diff --git a/docs/guide-ru/driver-db.md b/docs/guide-ru/driver-db.md index 33d02b5d81..cf0f2c0078 100644 --- a/docs/guide-ru/driver-db.md +++ b/docs/guide-ru/driver-db.md @@ -50,7 +50,7 @@ CREATE TABLE `queue` ( Миграции смотрите в [src/drivers/db/migrations](../../src/drivers/db/migrations). Расширение предлагает использовать -[миграции с неймспейсами](http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#namespaced-migrations). +[миграции с неймспейсами](https://www.yiiframework.com/doc-2.0/guide-db-migrations.html#namespaced-migrations). Чтобы добавить их в ваше приложение отредактируйте консольный конфиг: ```php diff --git a/docs/guide-ru/usage.md b/docs/guide-ru/usage.md index 349de26a33..230c426560 100644 --- a/docs/guide-ru/usage.md +++ b/docs/guide-ru/usage.md @@ -158,7 +158,7 @@ Yii::$app->queue->on(Queue::EVENT_AFTER_ERROR, function ($event) { ------------------- Этот компонент предоставляет `LogBehavior` для логирования событий, используя -[встроенный в Yii логгер](http://www.yiiframework.com/doc-2.0/guide-runtime-logging.html). +[встроенный в Yii логгер](https://www.yiiframework.com/doc-2.0/guide-runtime-logging.html). Чтобы использовать его, просто подключите это поведение в конфигурации компонента, как показано в примере: diff --git a/docs/guide-zh-CN/driver-amqp-interop.md b/docs/guide-zh-CN/driver-amqp-interop.md index 3176247fd4..7aa06ade8a 100644 --- a/docs/guide-zh-CN/driver-amqp-interop.md +++ b/docs/guide-zh-CN/driver-amqp-interop.md @@ -65,3 +65,20 @@ daemonized via [supervisor](worker.md#supervisor) or [systemd](worker.md#systemd - `--verbose`, `-v`: 详细模式执行作业。如果启用,将打印每个作业的执行结果。 - `--isolate`: 隔离模式。将在子进程中执行作业。 - `--color`: 在详细模式下高亮显示输出结果。 + +## Working with headers in messages + +The `setMessageHeaders` attribute can be used to send random headers to the queue along with the message. + +For example: + +```php +$queue = Yii::$app->queueTest; +$queue->setMessageHeaders = [ + 'header1' => 'header-value1', + 'header2' => 'header-value2', +]; +$queue->push(new TestJob()); +``` + +> Note! Existing headers will not be overwritten by default. diff --git a/docs/guide-zh-CN/driver-db.md b/docs/guide-zh-CN/driver-db.md index 6876579db3..eafe17ba59 100644 --- a/docs/guide-zh-CN/driver-db.md +++ b/docs/guide-zh-CN/driver-db.md @@ -49,7 +49,7 @@ CREATE TABLE `queue` ( 迁移文件存放在 [src/drivers/db/migrations](../../src/drivers/db/migrations). -添加迁移到您的应用程序,编辑控制台配置文件以配置[命名空间迁移](http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#namespaced-migrations): +添加迁移到您的应用程序,编辑控制台配置文件以配置[命名空间迁移](https://www.yiiframework.com/doc-2.0/guide-db-migrations.html#namespaced-migrations): ```php 'controllerMap' => [ diff --git a/docs/guide-zh-CN/usage.md b/docs/guide-zh-CN/usage.md index 126f0f803c..46aaf7a5f6 100644 --- a/docs/guide-zh-CN/usage.md +++ b/docs/guide-zh-CN/usage.md @@ -154,7 +154,7 @@ Yii::$app->queue->on(Queue::EVENT_AFTER_ERROR, function ($event) { -------------- 此组件提供了使用日志 `LogBehavior` 记录队列事件 -[Yii built-in Logger](http://www.yiiframework.com/doc-2.0/guide-runtime-logging.html). +[Yii built-in Logger](https://www.yiiframework.com/doc-2.0/guide-runtime-logging.html). 要使用它,只需按照以下方式配置队列组件: diff --git a/docs/guide/driver-amqp-interop.md b/docs/guide/driver-amqp-interop.md index 5d19ebd1d0..e902f7a665 100644 --- a/docs/guide/driver-amqp-interop.md +++ b/docs/guide/driver-amqp-interop.md @@ -60,3 +60,20 @@ yii queue/listen The `listen` command launches a daemon which infinitely queries the queue. If there are new tasks they're immediately obtained and executed. This method is most efficient when the command is properly daemonized via [supervisor](worker.md#supervisor) or [systemd](worker.md#systemd). + +## Working with headers in messages + +The `setMessageHeaders` attribute can be used to send random headers to the queue along with the message. + +For example: + +```php +$queue = Yii::$app->queueTest; +$queue->setMessageHeaders = [ + 'header1' => 'header-value1', + 'header2' => 'header-value2', +]; +$queue->push(new TestJob()); +``` + +> Note! Existing headers will not be overwritten by default. diff --git a/docs/guide/driver-db.md b/docs/guide/driver-db.md index 160f582d09..860e1642c7 100644 --- a/docs/guide/driver-db.md +++ b/docs/guide/driver-db.md @@ -84,7 +84,7 @@ CREATE INDEX priority ON queue (priority); You can use migrations which are available from [src/drivers/db/migrations](../../src/drivers/db/migrations). To add migrations to your application, edit the console config file to configure -[a namespaced migration](http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#namespaced-migrations): +[a namespaced migration](https://www.yiiframework.com/doc-2.0/guide-db-migrations.html#namespaced-migrations): ```php 'controllerMap' => [ diff --git a/docs/guide/retryable.md b/docs/guide/retryable.md index 20218f56d8..16109e5ed2 100644 --- a/docs/guide/retryable.md +++ b/docs/guide/retryable.md @@ -9,7 +9,7 @@ timeouts. In the latter cases, it's good to be able to retry a job after some time. There are several ways to do this. > **Note:** The `ttr` feature described below requires the -> [PHP Process Control (pcntl) extension](http://php.net/manual/en/book.pcntl.php) to be installed +> [PHP Process Control (pcntl) extension](https://php.net/manual/en/book.pcntl.php) to be installed > and the worker command has to use the `--isolate` option (which is enabled by default). Retry options @@ -122,4 +122,4 @@ You should set an address of a Dead Letter Queue and a maximum number of attempt [RabbitMQ]: driver-amqp.md [AMQP Interop]: driver-amqp-interop.md [AWS SQS]: driver-sqs.md -[Dead Letter Queue]: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html \ No newline at end of file +[Dead Letter Queue]: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html diff --git a/docs/guide/usage.md b/docs/guide/usage.md index 483a9b635a..0dc5eda167 100644 --- a/docs/guide/usage.md +++ b/docs/guide/usage.md @@ -167,7 +167,7 @@ Logging events -------------- The component provides the `LogBehavior` to log Queue events using -[Yii's built-in Logger](http://www.yiiframework.com/doc-2.0/guide-runtime-logging.html). +[Yii's built-in Logger](https://www.yiiframework.com/doc-2.0/guide-runtime-logging.html). To enable it, simply configure the queue component as follows: diff --git a/src/cli/SignalLoop.php b/src/cli/SignalLoop.php index 485666950f..3dbcd83dea 100644 --- a/src/cli/SignalLoop.php +++ b/src/cli/SignalLoop.php @@ -22,6 +22,7 @@ class SignalLoop extends BaseObject implements LoopInterface */ public $exitSignals = [ 15, // SIGTERM + 3, // SIGQUIT 2, // SIGINT 1, // SIGHUP ]; diff --git a/src/drivers/amqp_interop/Queue.php b/src/drivers/amqp_interop/Queue.php index 8b99a5488e..23383c4c0b 100644 --- a/src/drivers/amqp_interop/Queue.php +++ b/src/drivers/amqp_interop/Queue.php @@ -234,6 +234,20 @@ class Queue extends CliQueue */ public $commandClass = Command::class; + /** + * Headers to send along with the message + * ```php + * [ + * 'header-1' => 'header-value-1', + * 'header-2' => 'header-value-2', + * ] + * ``` + * + * @var array + * @since 3.0.0 + */ + public $setMessageHeaders = []; + /** * Amqp interop context. * @@ -351,8 +365,13 @@ protected function pushMessage($payload, $ttr, $delay, $priority) $message->setDeliveryMode(AmqpMessage::DELIVERY_MODE_PERSISTENT); $message->setMessageId(uniqid('', true)); $message->setTimestamp(time()); - $message->setProperty(self::ATTEMPT, 1); - $message->setProperty(self::TTR, $ttr); + $message->setProperties(array_merge( + $this->setMessageHeaders, + [ + self::ATTEMPT => 1, + self::TTR => $ttr, + ] + )); $producer = $this->context->createProducer(); diff --git a/src/drivers/sqs/Queue.php b/src/drivers/sqs/Queue.php index 4b675de677..898ea019a7 100644 --- a/src/drivers/sqs/Queue.php +++ b/src/drivers/sqs/Queue.php @@ -230,7 +230,7 @@ protected function getClient() ]; } else { // use default provider if no key and secret passed - //see - http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html#credential-profiles + //see - https://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html#credential-profiles $credentials = CredentialProvider::defaultProvider(); } diff --git a/tests/JobEventTest.php b/tests/JobEventTest.php index 808f39264e..4cf46a7c92 100644 --- a/tests/JobEventTest.php +++ b/tests/JobEventTest.php @@ -1,8 +1,8 @@ security->generateRandomString(12); $receivedRoutingKey = null; - $queue = $this->getQueue(); - $queue->routingKey = $uniqKey; - $queue->push($this->createSimpleJob()); + $yiiQueue = $this->getQueue(); + $yiiQueue->routingKey = $uniqKey; + $yiiQueue->push($this->createSimpleJob()); - $factory = new AmqpConnectionFactory([ - 'host' => $queue->host, - ]); - $context = $factory->createContext(); - - $queue1 = $context->createQueue($queue->queueName); - $queue1->addFlag(AmqpQueue::FLAG_DURABLE); - $queue1->setArguments(['x-max-priority' => 10]); - $context->declareQueue($queue1); - $topic = $context->createTopic($queue->exchangeName); - $topic->setType($queue->exchangeType); - $topic->addFlag(AmqpTopic::FLAG_DURABLE); - $context->declareTopic($topic); - $context->bind(new AmqpBind($queue1, $topic, $queue->routingKey)); + $context = $this->getNativeAMQPContext($yiiQueue); - $queue2 = $context->createQueue($queue->queueName); - $consumer = $context->createConsumer($queue2); + $queue = $context->createQueue($yiiQueue->queueName); + $consumer = $context->createConsumer($queue); $callback = function (AmqpMessage $message) use (&$receivedRoutingKey) { $receivedRoutingKey = $message->getRoutingKey(); return true; @@ -76,7 +62,53 @@ public function testSendMessageWithRoutingKey() $subscriptionConsumer->subscribe($consumer, $callback); $subscriptionConsumer->consume(1000); - $this->assertSame($queue->routingKey, $receivedRoutingKey); + sleep(3); + + $this->assertSame($yiiQueue->routingKey, $receivedRoutingKey); + } + + /** + * Test push message with headers + * @return void + */ + public function testPushMessageWithHeaders() + { + $actualHeaders = []; + $messageHeaders = [ + 'header-1' => 'header-value-1', + 'header-2' => 'header-value-2', + ]; + + $yiiQueue = $this->getQueue(); + $yiiQueue->setMessageHeaders = $messageHeaders; + $yiiQueue->push($this->createSimpleJob()); + + $context = $this->getNativeAMQPContext($yiiQueue); + + $queue = $context->createQueue($yiiQueue->queueName); + $consumer = $context->createConsumer($queue); + $callback = function (AmqpMessage $message) use (&$actualHeaders) { + /** + * This not mistake. In original package this function mixed up + * getHeaders() => getProperties() + */ + $actualHeaders = $message->getProperties(); + return true; + }; + $subscriptionConsumer = $context->createSubscriptionConsumer(); + $subscriptionConsumer->subscribe($consumer, $callback); + $subscriptionConsumer->consume(1000); + + sleep(3); + + $expectedHeaders = array_merge( + $messageHeaders, + [ + Queue::ATTEMPT => 1, + Queue::TTR => 300, + ] + ); + $this->assertEquals($expectedHeaders, $actualHeaders); } public function testListen() @@ -139,7 +171,6 @@ public function testSignals() $process->signal($signal); $process->wait(); $this->assertFalse($process->isRunning()); - var_dump($exitCode, $process->getExitCode()); $this->assertEquals($exitCode, $process->getExitCode()); } } @@ -160,4 +191,30 @@ protected function setUp() parent::setUp(); } + + /** + * @param Queue $yiiQueue + * @return mixed + */ + private function getNativeAMQPContext($yiiQueue) + { + $factory = new AmqpConnectionFactory([ + 'host' => $yiiQueue->host, + ]); + $context = $factory->createContext(); + + $queue = $context->createQueue($yiiQueue->queueName); + $queue->addFlag(AmqpQueue::FLAG_DURABLE); + $queue->setArguments(['x-max-priority' => 10]); + $context->declareQueue($queue); + + $topic = $context->createTopic($yiiQueue->exchangeName); + $topic->setType($yiiQueue->exchangeType); + $topic->addFlag(AmqpTopic::FLAG_DURABLE); + $context->declareTopic($topic); + + $context->bind(new AmqpBind($queue, $topic, $yiiQueue->routingKey)); + + return $context; + } } diff --git a/tests/drivers/beanstalk/QueueTest.php b/tests/drivers/beanstalk/QueueTest.php index 8219d50560..a78283ac4d 100644 --- a/tests/drivers/beanstalk/QueueTest.php +++ b/tests/drivers/beanstalk/QueueTest.php @@ -1,8 +1,8 @@