1

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.

4

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.

2
  • Thanks. Though I don't literally mean instantaneous, what I mean is the driver would've gotten a failed or accepted response in a single request, so it's quite instantaneous vesus having to do a second async poll request to verify the status of the pick-up request, making the UI a bit more complex. The other drivers hitting the accept button would've also gotten a faster failed status. Anyway, I'm just trying to get my head around why synchronous requests are considered not a good approach in cases like this.
    – IMB
    Jun 20 '19 at 12:05
  • Async doesn't have to be a second request. You can make a single request and get an async callback when the response is received. Likewise on the server side, you receive a single request, and send an async response when the response is ready. Jun 20 '19 at 15:12
1

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.

1
  • If the call fails or gets accepted, the drivers would've gotten a failed or accepted response in a single request. If it's a network failure, the accept button would just pop again so it's not entirely a "nobody picks up riders" scenario. Thanks for the insights.
    – IMB
    Jun 20 '19 at 12:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.