Fullfillment Service: Race Condition?

Hello all,

I am currently trying to refactor our custom fulfillment software to use fulfillment services and the corresponding flow, but I noticed an issue.

We have a rather specialized fulfillment chain, involving multiple human interactions, but the gist of it is, that each fulfillment is checked for validity (1-24h) and then processed (1-2 days) and it is a lengthy process.

Now as per the documentation here, I was a little puzzled about the process here.

I get a request towards the fulfillment service endpoint on my side, where no information about the orders to process is given. Then I am to fetch ALL assigned orders to process and accept or reject them. When another order is placed until this update has been sent to shopify, the same orders will be eligible for processing again. We try to keep all data within shopify and visible to the merchants at all times, so this is a conflict for us.
But more importantly, this basically introduces a race condition, as order processing on our end could be triggered in parallel by this flow.

My issue would be resolved by simply including the fulfillment id into the payload of the original request, letting me skip 5-10 queries towards the graphql and our own db, a ton of computation and headaches, so if I am missing something obvious, I would be happy to hear it.

Currently thinking about just implementing some microservices that listen to the webhooks for “FULFILLMENT_ORDERS_FULFILLMENT_REQUEST_SUBMITTED” and the like to use, as they at least contain a specific id, but that carries its own set of problems.

Thanks for your time

Theo

Hi @Theodor_Freund,

Thank you for reaching out with your question.

I’d like to clarify that the fulfillment_order_notification callback is designed with scalability in mind. This callback can debounce events, which means that during high-traffic periods, like a flash sale, the app won’t receive a callback for every single request if thousands are made in a short span, such as one minute. This is why the payload of these requests doesn’t include an ID; the app is simply notified that there are new fulfillment requests to process.

However, it’s possible for the app to receive a fulfillment_order_notification callback while still processing a previous one. Here are a few strategies to handle this situation:

  1. Serialize Querying: On the app side, serialize the querying of assignedFulfillmentOrders. If multiple requests are received for a single shop, process them sequentially to ensure the same fulfillment request isn’t read multiple times.
  2. Ignore Processed Requests: Run the query for each notification and continue processing until all fulfillment orders are handled. The processor should ignore requests that have already been read by a previous consumer.
  3. Use Webhooks as you mentioned: if flash sales and scaling aren’t a concern for your use case, consider using fulfillment webhooks to receive a single event per fulfillment request.

I hope this message addresses your concerns. Please feel free to reach out if you have any further questions or need clarification on the behavior and suggested solutions.

3 Likes

Thanks @Soroosh-Shopify ,
that clears things up nicely, I just have one follow up question:
Since our order process takes such a long time, I don’t put a lot of emphasis on delivery times of the webhooks or anything, but much more on the reliability. Are they guaranteed to be delivered (at all and/or in order)?
To be precise with a use case:
Lets presume there would be a flash sale or something that increases the order volume for a given time. Now we have a stack of REQUEST_SUBMITTED events and -for some customer related reasons- some of them have been cancelled in the meantime. Is it guaranteed, that the cancellation event for the fulfilment order follows the request submission if it happened before in terms of logical order (cannot cancel order that has not been created yet)

I don’t believe that this is guaranteed. These are two separate topics, so the app needs to be designed in a way can handle these events in any order.