php-enqueue / enqueue-dev

Message Queue, Job Queue, Broadcasting, WebSockets packages for PHP, Symfony, Laravel, Magento. DEVELOPMENT REPOSITORY - provided by Forma-Pro
https://enqueue.forma-pro.com/
MIT License
2.18k stars 434 forks source link

Laravel queue worker timeout after any job is handled #1068

Closed atrauzzi closed 4 years ago

atrauzzi commented 4 years ago

I'm putting together a PoC of using Enqueue pointed at ActiveMQ Artemis via STOMP. Everything is working quite well and I'm coming up to the last item on my list for "can this work" :clap:.

This last item seems a bit tricky, although it seems as though it might be to do with an interaction between Enqueue and the queueing abstraction in Laravel.

If I run ./artisan queue:work with no parameters, my queue starts and connects to my STOMP broker (Artemis) no problem. It will even stay connected indefinitely. The moment any job is processed however, after 60 seconds, the process terminates. Even despite the job finishing up and showing success.

I've been able to trace the termination down to this line in the Laravel Queue class.

The problem is that I'm not sure why it's happening when I'm using the Enqueue Laravel driver. The only way I've been able to get around this is to disable timeouts all together using --timeout=0, but this seems bad as now any job can jam up my queue worker.

Is there any chance that the Enqueue Laravel driver is not reporting back to Laravel correctly and this is causing the queue abstraction to think the worker is stuck?

makasim commented 4 years ago

Could you try commenting this IF statement and see what happens?

makasim commented 4 years ago

Ignore that comment. It has nothing to do with the issue. Though I suggest debugging Worker class from larave-queue package.

If it works for other queues and does not work for Enqueue than it means something wrong in the integration package and I suspect Worker class.

atrauzzi commented 4 years ago

Took a look, the first thing that jumps out at me is the fact that the daemon method doesn't call resetTimeoutHandler in the same way that the original implementation does. So after the first job is processed, the timer gets started, but never reset.

I assume the customized Worker subclass is to support push semantics, which is definitely appreciated. But continuing with my hunch, I think that makes everything look like one big job to the Laravel implementation. The Worker either needs to be flagged as not supporting async to the Laravel framework to suppress zombie detection, or the QueueConsumer needs to ping back to the Worker subclass so that the Worker can call parent::resetTimeoutHandler and let Laravel know that everything is okay.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

atrauzzi commented 4 years ago

:confused: