Ok, I'm working on DynamoDb-based caching. We have an API where each call costs us real money and the information retrieved is "fresh" for 2-3 weeks, so it makes sense to cache it.
There's no problem with calling dynamoDbClient.get(apiUrl)
and retrieving the stored JSON response. They have batches - 25 batch items for PUT and 100 batch items for GET. So it means if we need get JSON response for 100 items we do one call instead of 100.
The question I have is how to organize this in the best way for threading.
Here's general idea and I'm open to suggestions.
Assuming we have a batch call with 100 items, we can use a BlockingQueue<String>
to store the keys which we can use later. We would use blockingQueue.put()
method, to make other threads wait if 150 threads arrived into method having a batch of only 100 available.
So thread that enters method, gets his place in batch queue, needs some "locking" mechanism to wait until response arrives and "wake him up" that his response is available.
pseudoCodeMethod(String resourceUrl) {
blockingQueue.put(resourceUrl); // sleep if no place
LockableResponse lockableResponse = getLockableResponse();
lockableResponse.setKey(resourceUrl);
lockableResponse.getSemaphore().acquire();
String jsonApiResponse = lockableResponse.getJsonApiResponse();
lockableResponse.clean();
return jsonApiResponse;
}
LockableResponse{
String resourceUrl;
String jsonApiResponse;
Semaphore semaphore = new Semaphore(0);
public void clean(){
resourceUrl = null;
jsonApiResponse = null;
}
}
My though is that we would associate a resourceUrl for each dynamodb response with a data structure that has semaphore to await for api response which arrives for ~100 items in one batch call.
A separate thread performs the call and then iterates through response, assigns jsonApiResponse
to proper resourceUrl
[concurrentMap
for that?? ] and then calls lockableResponse.release()
to wake up thread, so thread takes resourceUrl
and exists the method.
The clean()
method could be added to allow reuse of the same structure. I'm thinking about array of lockable resource according to batch capacity. So they could be cleared and reused for other batch GET call.
Thoughts? Suggestions?