Question

Say there are two microservices (example is simplified)

PickupRequestService: lists pick-up requests of passengers

DriverService: drivers use to accept pickup requests

On a completely decoupled communication method (via message queues), DriverService would make an async call to accept a pick-up request e.g., PickupRequestService->accept(pickupId). This looks fine however, for a few seconds, this will cause other drivers to see pick-up requests that are already taken.

You could probably eventually send a compensating failed message for those hopeful drivers that accepted a taken pick-up request e.g., "your request to accept the passenger has been rejected..." but that won't be a good UX.

My question is, for scenarios similar to this, where a state changing operation is time sensitive, is it okay to make synchronous inter-microservice REST calls? E.g., DriverService synchronously calls PickupRequestService->accept(pickupId) so that the state change is instantaneous and no other driver sees old pick-up requests anymore.

Was it helpful?

Solution

Synchronous is not instantaneous. The network operation still takes just as long, possibly longer because synchronous operations occupy threads longer, which decreases server resources. It's still possible for two drivers to hit the accept button at the same time.

If you don't want the UX of a driver's acceptance not being confirmed, the only real concurrency-safe option is to only offer a pick-up to one driver at a time, giving him or her the exclusive option to accept or reject for a limited amount of time. This has the trade off of making the passenger sometimes wait longer for an acceptance, but has other benefits, like being able to offer to closer drivers first, which might decrease the overall wait time.

OTHER TIPS

My question is, for scenarios similar to this, where a state changing operation is time sensitive, is it okay to make synchronous inter-microservice REST calls?

Sure, but what happens if that call fails?

Now you're in a state where the passenger is still looking for a ride and the person trying to accept the request gets the error with bad UX. Worse, your business suffers because nobody can pick up riders.

It becomes a design decision based on your needs. Is it important to know if that handoff succeeds? The eventual consistency is usually tons better since it allows for increased scalability, easier versioning of contracts, better error resilience, and a few other benefits at the cost of complexity and squishier timing. But sometimes those costs are high enough that it becomes a bad idea.

Licensed under: CC-BY-SA with attribution
scroll top