Message queues are not a new concept – neither is Push Notifications and surely not HTTP Posts for that matter. However, when you combine these ideas you have a very flexible queueing system.
Sprinkle in a little bit of Symfony's
EventDispatcher... suddenly your Symfony application starts to feel a whole lot more responsive. And that feels great.
The Lead Up...
Underground Elephant is an online performance marketing company, and provides customer acquisition software for its clients. We're constantly weighing the benefits of hosting our own services vs using cloud-based alternatives. More often than not, in our fast paced environment - we have bigger fish to fry then dealing with administrating, scaling, and maintaining simple services that, while are important, are not core to our business.
So, when it came to finding ways to increase the responsiveness of our Symfony2 applications and move non-essential processes to the background, we started exploring job queues and messaging.
Admittedly, spinning up an instance of RabbitMQ or ØMQ ain't hard, neither is writing a script that will keep a socket open waiting for new messages.
I guess, frankly, we just didn't want to do it. It was another moving part that my teams had to maintain outside of their applications and more dependencies and infrastructure in our deployment.
Queue Your Cake and Eat it Asynchronously
What I wanted was to keep my dependencies light and in code – maintained by composer. I wanted a way to write my worker code as simple services within my Symfony application - all maintained within the same repository and deployed just as easily.
I wanted persistence in my queue and a level of failover in case of errors. I wanted hands off scaling and distribution - and I really wanted someone else to manage it.
So, I wanted a lot, actually.
Enter the Symfony2 QPush Bundle, integrated with IronMQ, Iron.io's cloud message queue as a service.
The bundle integrates push queue providers directly into your Symfony application allowing you to create and manage multiple queues. Subscribers are configurable, allowing differing and/or multiple subscribers per queue.
You can publish messages easily...
The bundle leverages the EventDispatcher to dispatch a
MessageEventwhen your published messages are received from your queue. Your services are called automatically based on simple tagging which gives a lot of flexibility in chaining services or handling multiple queues in a single service.
Because it utilizes simple services in Symfony, its very easy to reuse your existing code. For us, this made adoption incredibly easy.
Handle Events in Your Services
Check out the bundle and the documentation on ReadTheDocs for more information on how to incorporate this into your application.
Push Queues are Awesome!
Push Queues may not appeal to everyone or fit each use case, but there is a ton of upside to them.
You know that queue you have that's not heavily utilized, but processing each message as soon as possible is incredibly important? Yeah, the one you're polling on the same 5 second interval at 3am that you are at the heaviest time of day. By pushing notifications directly to you application, you can remove that wasted compute, the wasted api calls, and wasted money.
No more daemon, no more cron.
For PHP specifically, threading has always been a sore spot (read, "non-existent"). However, with Push Queues, you can utilize your web server (Apache, Nginx, etc) to handle the threading for you. This also means you can easily scale horizontally by either registering more subscribers or utilizing a cluster of web servers behind a load balancer.
The QPush Bundle is open source and openly available to use. We're also very welcome to receiving contributions and feedback. If you have any questions, please visit us on GitHub!
About the Author
Keith Kirk is VP Engineering at Underground Elephant. Underground Elephant delivers enterprise marketing software solutions. They were founded in 2008 and are headquartered
in San Diego, California.