Concurrent Event Handlers have race conditions. How to fix fix them?

Viewed 23

Event handler E1 makes a long running network request. Event handler E2 is very quick and doesn't make a network request. It writes to database.

E1 is guaranteed to start to execute before E2 however, E1 finishes after E2. How can I force that E2 always finishes after E1?

Thanks.

1 Answers

You didn't mention any language. I like Java, but you can find something like Semaphore in many languages and libraries.

Semaphore sem = new Semaphore(0);

void E1(...) {
    doSomeStuff();
    sem.release();
}

void E2(...) {
    doStuffThatsSafeToDoWhile_E1_StillIsDoingItsStuff();
    sem.acquire();
    doStuffThatMustWaitUntilAfter_E1_IsFinished();
}

This will work for just one pair of calls to E1 and E2. I don't want to suggest any way to "reset" it to be used again and again. I'll leave that part up to you because I don't want to assume anything about the relationship between E1 and E2. I don't know why there is stuff that must wait until E1 is finished. I don't know what "finished" really means. If E1 and E2 are allowed to be called again, I don't know what had to happen in order to allow it.


Edit:

Maybe, at a high level, you're really only handling one "event," but at a low-level, you get the notification of that event in two parts.

If so, then how about we do all of the work to handle the high-level event within one handler function, and let the other handler function do nothing except open a gate when it's safe for the first one to finish whatever needs to be finished?

Semaphore sem = new Semaphore(0);

void E1(...) {
    doStuffThatCanBeSafelyDoneBefore_E2_isCalled();
    sem.acquire();
    doStuffThatMustNotBeDoneUntilAfter_E2_isCalled();
}

void E2(...) {
    sem.release();
}
Related