I have a servlet S which handles callbacks from a 3rd party site.
The callback invocations happen in a specific order. Thus, I need to queue them.
I propose to use an in-memory queue like
java.util.ConcurrentLinkedQueue
So the logic looks like this:
- Servlet S receives a callback & queues the received item into queue Q.
- By this time, the thread that hosted an instance of servlet S would have terminated.
- A consumer thread reads from Q and processes each one serially.
As I understand it, each instance of Servlet S is executed in its own Thread.
How do I create a single Consumer Thread for the whole webapp (war) that will service a Queue ? Basically I need singleton instances of:
- Threadpool
- ConcurrentLinkedQueue
This isn’t the sort of thing a servlet container is for. You really need a more full-blown J2EE application server if you’re going to use a standards-based approach. What you’re going to have are hacks otherwise but they might be sufficient for your task.
What I would probably try is creating a DaemonServlet. This is just a normal servlet that is not mapped to a URL (except, perhaps, a blind URL for monitoring purposes, although prefer JMX for this kind of thing). The
init()method is called when the servlet is loaded. You could start a thread in that. Arguably you may need to create two: one that does the work. The other makes sure the first one is running and gracefully terminates it oncedestroy()is called.Alternatively, if you’re using Spring (and, let’s face of it, what kind of whacko doesn’t use Spring?), you could simply create a bean in the application context that does much the same thing, except with Spring lifecycle events (eg afterPropertiesSet() on InitializingBean).
Actually, I have an even better suggestion. Use asynchronous message consumers, which will be a lot cleaner and more scalable but this is predicated on a JMS-based solution, rather than just a
LinkedBlockingQueue(and JMS is probably a better idea anyway). Depending on your constraints, you may not have JMS available as an option however.