-1

I am facing an issue because of RACE condition. Here is the example to better understand the issue.

We have a service that stores the birthday greets in GreetingsBox. Every birthday boy have a unique bbId. For every BBid only one GreetingBox is allowed.

Request is like - {bbid: 'someId', msg: 'Birthday greetings'}

Flow -

greetingsBox = getGreetIfExistsForBBid(bbId) // calls external service to get the greetingsBox for BBid, returns null if does not exist.
// This means we already have the greetingsBox created for BBid.
if(greet != null) {
  updateTheGreetBox(greetingsBox, request) // calls external service to update in the existing greetingsBox.
} else {
  createTheGreetBox(request) // calls external service to create a new greetingsBox.
}

Issue -

We are receiving thousands of greetings for same BBid in miliseconds.

  1. For the first request, create new GreetingBox will trigger. (This is expected)
  2. Before 1st request create a GreetingsBox, 2nd request came in and the getGreetIfExistsForBBid returns null. This leads to trigger the create request instead of update.

Multiple GreetingBox is getting created for same BBid.

I can't use sync of Java because I only want the sync execution for unique BBid.

Solution I thought of -

  1. Before call the create API, put BBid in a lock.
  2. After create API call gets complete, remove the BBid from lock.
  3. For every request, check if BBid in lock.
    • If it is in lock, wait until it's in lock state.
    • If not in lock, continue the execution, don't wait.

Facing issue with it's implementation, how can we make a function wait ? without check in intervals.

If any one have any other better idea, please let me know.

Pankaj Sharma
  • 2,185
  • 2
  • 24
  • 50

1 Answers1

0

I recommend using a java.util.concurrent.atomic.AtomicReference. In particular, the compareAndSet method should be useful. This will allow you to atomically 1) determine if the current value is null, and 2) if it is, set the value to a new BBid.

DBear
  • 312
  • 2
  • 9