I think Spring Batch is overkill, not what you are looking for. This is more for batch processing, like writing all orders to a file, and then processing all at once, whereas it looks like asynchronous processing, where you just want to have a work queue and process it that way.
If this is true, I would consider using a pub / submodel using JMS. There are several JMS providers, such as Apache ActiveMQ or Pivotal RabitMQ. Essentially, your OrderService would break the CSV into units of work, push them to the JMS queue, and you would have a few Consumer settings to read from the queue and complete the work task. There are many ways to tune this, but I would just make a class to hold worker threads and tune the number of threads. Other additional benefits are here:
- You can screen the user code and even run it on completely different hardware if you want.
- MQ is a fairly well-known process, and there are many commercial offers. This means that you can easily write your order processing system in C # using MQ to move messages, or even use the Spring Package if you want. Heck, there is even an MQ series for the host, so you could process your order on the mainframe in COBOL if you liked it.
- It's stupid to just add more consumers or manufacturers. Just subscribe to the Queue and they will leave!
- Depending on the product used, the queue maintains state, so messages are not "lost". If all users are disconnected, the queue will simply back up and save messages until consumers return.
- Queues are also usually more reliable. The producer can come down, and you wonβt even flinch consumers. Consumers can go down, and the manufacturer does not even need to know.
However, there are some disadvantages. You now have an additional error. You probably want to control the depth of the queue, and you will need to provide enough space to store messages when caching messages. In addition, if processing time can be a problem, you may need to monitor how quickly the queues in the queue are processed to make sure that it does not copy too much or violates any SLA that might be in place.
Edit: Add an example ... If I had a streaming class, for example:
public class MyWorkerThread implements Runnable { private boolean run = true; public void run() { while (run) {
Then I would start creating threads using a class like this:
@Service("MyThreadManagerService") public class MyThreadManagerServiceImpl implements MyThreadManagerService { private Thread[] workers; private int workerPoolSize = 5; @PostConstruct private void init() { workers = new Thread[workerPoolSize]; for (int i=0; i < workerPoolSize; i++) { workers[i] = new Thread(new MyWorkerThread());
Now you have a good class of service that you can add to track, restart, stop, etc. all your workflows. I did this @Service because it felt more right than a simple @Component , but technically it could be anything as long as Spring knows how to pick it up when you perform auto-installation. The init() method in the service class is what starts the threads, and dismantle() used to gracefully terminate them and wait for them to complete. They use the @PostConstruct and @PreDestroy , so you can name them whatever you want. You probably have a constructor on MyWorkerThread for setting up queues, etc. Also, as a disclaimer, all of this was written from memory, so there may be some minor compilation issues or method names may be slightly disabled.
There may be classes that are already available for this kind of thing, but I have never seen them myself. Does anyone know of a better way to use the finished parts that I would like to get more educated.