Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Queue Interop Support #104

Closed
wants to merge 28 commits into from
Closed

Conversation

ASKozienko
Copy link

No description provided.

@ASKozienko ASKozienko changed the title Queue Interop Support [WIP] Queue Interop Support Aug 1, 2017
@makasim
Copy link
Contributor

makasim commented Aug 1, 2017

Tests fail because of php5.5 requirement and dependency on enqueue/amqp-lib 0.7 which has not been released yet.

@makasim
Copy link
Contributor

makasim commented Aug 1, 2017

This approach is based purely on queue-interop interfaces and does require enqueue. We can propose another solution based on enqueue client. It'll introduce a dependency on enqueue but it allows to remove a lot of low-level MQ stuff from here.

@ASKozienko ASKozienko changed the title [WIP] Queue Interop Support Queue Interop Support Aug 1, 2017
while (true) {
if ($message = $consumer->receive()) {
list($ttr, $body) = explode(';', $message->getBody(), 2);
if ($this->handleMessage(null, $body, $ttr, 1)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we reject it on false?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Queue reserves message for handling before method calling.
If method returns false, queue should keep message in reserve. If false, message must be deleted.

Copy link
Contributor

@makasim makasim Aug 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ASKozienko could you please do message requeue on false and ack on true?

$this->getContext()->createQueue($this->queueName)
);

while (true) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be good to add usleep. 10-100ms would be ok.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ability to configure delay would be good with 10ms default.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wrong. There is no need for sleep since receive is blocking (it waits on a socket, or does sleep internally). No need to do it here.


$this->producer->send(
$this->getContext()->createQueue($this->queueName),
$this->getContext()->createMessage("$ttr;$message")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samdark what does ttr mean?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@makasim "time to read"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@makasim
Copy link
Contributor

makasim commented Aug 1, 2017

@samdark could you please have a look?

composer.json Outdated
},
"suggest": {
"ext-pcntl": "Need for process signals.",
"yiisoft/yii2-redis": "Need for Redis queue.",
"pda/pheanstalk": "Need for Beanstalk queue.",
"php-amqplib/php-amqplib": "Need for AMQP queue.",
"ext-gearman": "Need for Gearman queue."
"ext-gearman": "Need for Gearman queue.",
"php-enqueue/amqp-ext": "Needs for support of AMQP with queue interop",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs for support of AMQP with queue interop → Required for AMQP with queue interop

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for below descriptions.


The driver works with many queue brokers.

Full list of supported brokers you can find on the [Queue Interop](https://github.com/queue-interop/queue-interop) page
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can find full list of...


Full list of supported brokers you can find on the [Queue Interop](https://github.com/queue-interop/queue-interop) page

To get it works you have to install and setup one of the supported implementation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order for it to work you need to install and configure one the implementations supported.


To get it works you have to install and setup one of the supported implementation.

Configuration example for the RabbitMQ AMQP:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it's a good example since there's RabbitMQ driver that works w/o Queue Interop already. It all depends on the goal.

@zhuravljov Do we want to remove our own implementations and use Queue Interop ones instead? That would be less maintenance and more profit for PHP overall. Or do we want to have additional drivers through Queue Interop?


`listen` command has options:

- `--verbose`, `-v`: print executing statuses into console.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

print executing statuses into console → print execution status into console

`listen` command has options:

- `--verbose`, `-v`: print executing statuses into console.
- `--isolate`: verbose mode of a job execute. If enabled, execute result of each job will be printed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verbose mode of a job execute → verbose mode of a job execution

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

execute result → execution result

$this->getContext()->createQueue($this->queueName)
);

while (true) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ability to configure delay would be good with 10ms default.

}

$rc = new \ReflectionClass($this->factoryClass);
if (false == $rc->implementsInterface(PsrConnectionFactory::class)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http://php.net/is_a could be used instead of reflection.

@@ -108,8 +110,7 @@ private function getContext()
throw new \LogicException(sprintf('The "factoryClass" option "%s" is not a class', $this->factoryClass));
}

$rc = new \ReflectionClass($this->factoryClass);
if (false == $rc->implementsInterface(PsrConnectionFactory::class)) {
if (false == is_a($this->factoryClass, PsrConnectionFactory::class)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=== could be used.

@samdark
Copy link
Member

samdark commented Aug 2, 2017

Overall the code looks fine but I'd like to hear @zhuravljov opinion on future development and path we should take.

protected function pushMessage($message, $ttr, $delay, $priority)
{
if ($delay) {
throw new NotSupportedException('Delayed work is not supported in the driver.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ASKozienko Could you please implement this (since their support has been merged php-enqueue/enqueue-dev#149)

@@ -117,6 +123,21 @@ private function getContext()
/** @var PsrConnectionFactory $factory */
$factory = new $this->factoryClass(isset($this->factoryConfig['dsn']) ? $this->factoryConfig['dsn'] : $this->factoryConfig);

if ($factory instanceof DelayStrategyAware) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ASKozienko I am not sure factory implements delay strategy aware interface.

@makasim
Copy link
Contributor

makasim commented Aug 7, 2017

Consider marking classes final so it easier for us to change in future (without BC breaks)

@makasim
Copy link
Contributor

makasim commented Aug 8, 2017

@samdark @zhuravljov tests fail only on php5.5 because enqueue requires php5.6 as the minimum version. How should we proceed?

@samdark
Copy link
Member

samdark commented Aug 8, 2017

There are only two ways:

  1. Lowering enqueue requirements. Is it possible? Is 5.6 actually used?
  2. Raising yii2-queue requirements. Doable but we prefer not to do so unless needed.

@makasim
Copy link
Contributor

makasim commented Aug 8, 2017

@samdark I am thinking of dropping 5.x at all. Why are you so stick to it?

@samdark
Copy link
Member

samdark commented Aug 8, 2017

Because we have Yii 2.0 and it works with 5.4. Even when we'll release 2.1 that requires PHP 7.1, we'll have to support 2.0 for some time cause there are countless projects in production using it.

@makasim
Copy link
Contributor

makasim commented Aug 10, 2017

@samdark we decided to skip the tests for php5.5 for now. If someone wants to use yiiqueue with enqueue they have to make sure they are on php5.6 at least.

Could you please review it?


class Queue extends CliQueue
{
const RABBITMQ_DELAY_DLX = 'dlx';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why there are rabbit-specific things in a general purpose class?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We tried to keep it as simple as possible, so everything in one class.

we can move amqp interop specific stuff to separate class. Is it ok?

@@ -45,7 +61,8 @@
"yii\\queue\\file\\": "src/drivers/file",
"yii\\queue\\gearman\\": "src/drivers/gearman",
"yii\\queue\\redis\\": "src/drivers/redis",
"yii\\queue\\sync\\": "src/drivers/sync"
"yii\\queue\\sync\\": "src/drivers/sync",
"yii\\queue\\queue_interop\\": "src/drivers/queue_interop"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we use just yii\queue\interop as a namespace?

@zhuravljov
Copy link
Member

Merged from #158.

@zhuravljov zhuravljov closed this Dec 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:enhancement Enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants