How do you maintain responsiveness when you have lots of tasks that needs to synchronous and whole operation needs to be transactional.
Posted by Embarrassed-Sand5191@reddit | ExperiencedDevs | View on Reddit | 28 comments
How would you handle a scenario in a backend update API where changes in data trigger many other changes? Some of these changes need to be synchronous, while others can be asynchronous. You could offload asynchronous tasks, but what about the synchronous changes that involve heavy computation and slow down your API?
zulrang@reddit
Create a task/job/object and return the ID and/or REST URI immediately which can be polled for status.
The client occasionally polls the resource, communicates to the user, and forwards to the completed resource when it's all completed, or displays any errors.
Unhappy_Ad6706@reddit
Is this not just a long-winded way of saying "make it asynchronous"? What am i missing?
Dangerous_Stretch_67@reddit
I thought this for a second but was then like "no, he's right." Reading between the lines for a product requirement, what does "needs to be synchronous" even mean? From a requirements standpoint, this likely just that certain processes must happen in a specific order.
It will be asynchronous in the "there will be polling on some process somewhere and a worker on some process somewhere" sense, but restricting that most likely isn't what is needed from a requirements standpoint.
zulrang@reddit
The ask was "how do you maintain responsiveness"
The tasks can still be synchronous or not. But the client is no longer held up.
PuzzleheadedPop567@reddit
Yes. Because there’s really no way around it. If you need a response to the frontend in under 2 seconds, but the user is requesting that the backend do 30 seconds of work, there’s really no other option.
Most applications can do fine with eventual consistency, even if product and management think differently.
I will say, I probably would try to avoid “rolling my own” the backend these days. Between tools like temporal and Kafka, there are a lot of already built ways to handle durable but async tasks. I’m not 100% sold on those particular tools, but I see us containing to move in that direction.
I will not be programming with callbacks or rolling my own async task executor anymore.
Unhappy_Ad6706@reddit
That might be all fine and correct but I don’t think the answer was to trick OP into accidentally implementing asynchronous tasks
pl487@reddit
And provide example polling code for someone who does not want to think outside of synchronous land. Show them that there's nothing difficult about it.
sleeping-in-crypto@reddit
This is the answer. I’ve found over time that it’s immature tech teams that insist that all responses be synchronous, any meaningfully complex system will always have elements that can’t be represented that way.
grahambinns@reddit
If I had a quid for each time in the last 10 years that I’ve come to a company / project and seen a horrible nest of synchronous API calls and then said “so, let’s bring {insert queue broker of choice} into the mix…”. Well, I’d have 6 quid. But still. 6 quid is 6 quid.
Most distributed systems should be built with the assumption that everything is brittle and thus it’s safer to be async.
SatisfactionOk2873@reddit
God yes. I've spent countless hours arguing with product management insisting all endpoints have to be synchronous.
sleeping-in-crypto@reddit
Becoming comfortable with eventual consistency/async responses unlocks a whole universe of architectures you couldn’t consider otherwise.
Certainly they can be taken too far, but speaking as a principal who has done this for far too many years, the problem you’re describing is an ideal use case for this model.
Constant-Listen834@reddit
This is it
gfivksiausuwjtjtnv@reddit
I’ll go against the grain here and say that there’s almost always a way to make things way faster but it potentially requires serious optimisation work and probably ripping apart half of the system and making new architectural choices that are probably outside corporate orthodoxy
float34@reddit
Celery workers I think?
gfivksiausuwjtjtnv@reddit
Isn’t that a Python library? If raw synchronous perf is an issue, I’d consider putting part of it in not Python
Suepahfly@reddit
The easy shortcut here is doing optimistic updates on the client. E.g. make the request assume the results are good, update the UI. Signal a rollback if the are not.
maxlstylee@reddit
Make it event driven, push message to the user as tasks complete. Avoid polling.
cougaranddark@reddit
I would find any way to change this - if a step needs to execute after a long-running task, it can either poll for status, or a message can be queued when it's complete to trigger the next task
forgottenHedgehog@reddit
This has nothing to do with CAP.
g0fry@reddit
Does the caller of the api endpoint need to wait for the result of that chain of operations? If yes, then there’s nothing you can do. If no, then simply use one of many techniques that allow you to schedule the operation to run outside of the api. Synchronicity has nothing to do with it.
BoBoBearDev@reddit
Aside from just making the endpoint async using requestId. You should evaluate why the overall transaction is so big and why it is touching multiple backends if any.
For example, let's say you have two services, a user is main user DB and another is storing preference and another is storing details like address. You should be able to update the enties in child services without going through the main user service. So, the transaction is much smaller.
Forsaken-Ad3524@reddit
synchronous changes are an illusion. they can be atomic, transactional. synchronous - depends on level of analysis what do you really mean, and is impossible in a distrubuted system. including client-server requests. embrace the async, embrace reality.
mxldevs@reddit
What is the task?
FarYam3061@reddit
no no lets not worry about details
Adept_Carpet@reddit
Assuming "make everything happen instantly" isn't a realistic option, then the key for the backend component will be the ability to provide status updates and also thinking carefully about validation so that bad requests fail fast.
There's nothing more frustrating than submitting a lengthy form and getting an email the next day to tell you that the filename of your 17th upload was too long and so the entire submission was rejected and you need to start from scratch.
morosis1982@reddit
Are the synchronous changes blocking, as in a second call to the API would need to wait for the first to finish (or at least would need to wait behind certain gates)? Or are they only synchronous within the context of that API call, in that the Async tasks can be run in parallel to a 'main thread' but they all need to meet up at the end and check that the transaction is done?
Alokeen011@reddit
TBH, if that's the issue then it's a matter of bad architecture.
Yweain@reddit
You either make those synchronous tasks into asynchronous and deal with the consequences.
Or you make the whole process asynchronous.
Or you accept that it will never be really all that responsive and spend a lot of effort on optimising every little thing as much as possible.