Question

I have a scenario in which I have to process CSV files from a folder for users and store them into database after processing. We have 5 type of feeds per user. Any user can send any feed in that folder, any time for processing, need to follow below rules:

  • same type of feed for same client can't be processed at same means time must always be blocked from being processed concurrently.
  • do not allow concurrent processing across more than "x" clients
  • do not allow concurrent processing of more than "y" files for the same client

What is the good way to achieve this ?

Was it helpful?

Solution

The first restriction can be implemented with a map of AtomicBoolean. This probably doesn't need to be a ConcurrentHashMap, since you won't be changing the map's keys after initialization. Don't forget to reset the feed's value to false when you're done.

checkAndProcessFeed(Feed feed, Map<String, AtomicBoolean> map) {
    while(!map.get(feed.type).compareAndSet(false, true)) // assuming the AtomicBooleans were initialized to false
        Thread.sleep(500);
    }
    process(feed); // at this point map.get(feed.type).get() == true
    map.get(feed.type).set(false); // reset the AtomicBoolean to false
}

The other two restrictions can be implemented with AtomicInteger, used to maintain a count of clients and per-client files; decrement when processing is complete, and increment with compare-and-set to start a new client/file.

final int maxClient = 5;
AtomicInteger clientCount = new AtomicInteger(0);
ConcurrentLinkedQueue<Client> queue = new ConcurrentLinkedQueue<>(); // hold waiting clients
while(true) {
    int temp = clientCount.intValue();
    if(!queue.isEmpty() && clientCount.compareAndSet(temp, temp + 1) { // thread-safe increment 
        process(clients.poll()); // don't forget to decrement the clientCount when the processing finishes
    } else Thread.sleep(500);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top