swarrot / SwarrotBundle

A symfony bundle for swarrot integration
MIT License
89 stars 59 forks source link

Retrieve channel to perform manual action on a queue #97

Closed j0k3r closed 7 years ago

j0k3r commented 7 years ago

I would like to get the number of messages from a queue without re-connecting manually to the broker.

The getChannel method from both AmqpLibFactory & PeclFactory looks great to achieve that. But there are both protected so I can't access them.

I would like to achieve sth like that (from inside a project):

public function isQueueEmpty()
{
    $message = $this
        ->get('swarrot.factory.default')
        ->getChannel('rabbitmq')
        ->basic_get('queue_name');

    if (null === $message) {
        return true;
    }

    return $message->delivery_info['message_count'] < 0;
}

And I know that swarrot.factory.default might not have the getChannel method since it's not in the FactoryInterface :slightly_smiling_face:.

Should I open a PR to put getChannel public and add it to the FactoryInterface? Or do you have a better option?

odolbeau commented 7 years ago

Adding a getChannel method in the FactoryInterface is not a good idea as this concept is specific to RabbitMQ. If you use Redis for example, this method is not implementable. Furthermore, your getChannel won't return the same class in all implementations.

I see 2 solutions here.

Solution 1:

In the PeclFactory you can use the getQueue public method to achieve your need. Changing the visibility of the getChannel method in the AmqpLibFactory could be a way to retrieve the number of messages. This solution is abviously a hack. You won't be able to switch between implementations.

Solution 2:

The cleanest solution is probably to add a getMessageCount method (or something like this) into the MessageProviderInterface (directly in swarrot library).

It looks like it's easy to implement for SQS as there is a method to retrieve the approximative number of messages in a queue (see here).

For both Pecl & AmqpLib implementations, it looks like it's possible to retrieve the amount of messages using 2 different ways:

None of those implementations are perfect unfortunately.

At the end, I don't have any clean solution for your need... :/

The first solution is definitively the easiest to implement but it means you won't be able to easily switch from an implementation to another if you need to. The second one is cleaner but way harder to implement... (I'm not even sure it's possible! :o)

WDYT?

j0k3r commented 7 years ago

Thanks for all these explanations :+1:

I noticed the getQueue after posting my issue. But I'm using amqp lib atm (didn't took time to compile the pecl extension).

I agree the second solution looks cleaner but more complex. I'll go with the first solution.

So should I just open a PR with that?

    /**
     * getChannel.
     *
     * @param string $connection
     *
     * @return AMQPChannel
     */
-   protected function getChannel($connection)
+   public function getChannel($connection)
odolbeau commented 7 years ago

Yes, it looks fine for me.

odolbeau commented 7 years ago

May I ask you what's your need exactly? :)

j0k3r commented 7 years ago

I have a command that push thousand messages in a queue every 10 minutes. I would like that command to check if the queue is empty (or have less than XX messages) before sending again new messages.

See https://github.com/j0k3r/banditore/issues/37 :slightly_smiling_face:

odolbeau commented 7 years ago

Thanks. :)