4 ms·
I'm trying to envision a situation where you'd want to make more than one database request at the same time. Like I guess on a blog or something, you could load
by Cyberdog 4y ago
I'm trying to envision a situation where you'd want to make more than one database request at the same time. Like I guess on a blog or something, you could load the user record of the current user and then load the blog post details at the same time, but then there's a chance that the user doesn't have permission to view that blog post and then the request for the post has gone to waste, right? It goes against my instincts to kill a request as quickly and directly as possible if something can't be accessed.
I don't know, I'm willing to accept that maybe I'm just not used to thinking of developing back-end web apps that way. But async still just doesn't seem as useful as it would in a GUI desktop app.
- eyelidlessness 4y ago> I'm trying to envision a situation where you'd want to make more than one database request at the same time. Because I have two requests active at the same time and the second one which arrived shouldn’t wait for me to stand around doing nothing while I wait for the database to serve the first. > Like I guess on a blog or something, you could load the user record of the current user and then load the blog post details at the same time, but then there's a chance that the user doesn't have permission to view that blog post and then the request for the post has gone to waste, right? It goes against my instincts to kill a request as quickly and directly as possible if something can't be accessed. Here one user represents 2+ events, both of which should fail. This wasn’t part of my original explanation but yielding does give you the opportunity to fail both simultaneously. Albeit in this case it’s just concurrency broadly. Why is that against your instincts, if you know that one request’s failure implies the other will also fail? Why should that user wait in line to get the same error after another cycle of the same trial? > I'm just not used to thinking of developing back-end web apps that way. But async still just doesn't seem as useful as it would in a GUI desktop app Yep I get that. And async takes a bit to get used to in general. The way I think of it is: I have two kinds of work which need to be done, and a long line asking me to work. Some of the work needs labor (CPU), some needs patience and communication (IO). Everyone in line needs some of both. If I do the first person’s immediate labor and wait for further communication, persons 1 and 2 are waiting for me to proceed. If I do the first person’s labor, send off an asynchronous request for feedback on that, I can do N people’s labor before I get any response. As long as no one spends too long making anyone else wait in queue everyone moves as fast as the queue’s capacity.
- Cyberdog 4y ago> Here one user represents 2+ events, both of which should fail. This wasn’t part of my original explanation but yielding does give you the opportunity to fail both simultaneously. Albeit in this case it’s just concurrency broadly. Why is that against your instincts, if you know that one request’s failure implies the other will also fail? Why should that user wait in line to get the same error after another cycle of the same trial? I really have no idea what you're saying here, so let me put it this way. I would code this hypothetical blog page access situation this way in PHP: Get user data from database. Do access checks on user data. See user does not have permissions to view blog article. Show 403 page. Assuming I'm understanding what you're saying about async database requests, this is apparently "correct" in Node: Request user data and blog post data from database. If the blog post data comes first, wait. When the user data comes, do access check and show 403 page. If the blog post data hasn't come yet… it just gets ignored or something, I guess. Otherwise the data just gets thrown out…? What's against my instinct is to make the request for the blog article data unless and until it is known that it will be needed.
- eyelidlessness 4y agoA typical Node service would probably be designed very similarly to your description of the PHP equivalent. The difference in a typical scenario is that, should another request come in while the first query for user data is in flight, the same process would initiate its first query for user data concurrently. Both requests are still pending but suspended until the IO they depend on is available (and until whatever other synchronous work on the event loop yields or completed). The scenario you describe, performing multiple queries for the same request in tandem, certainly isn’t incorrect. It’s a less common design, but one which might make sense depending on the workload. An example where I’d choose that design: both queries are slow individually, but not significantly slower queried concurrently. Even if the query for blog post data turns out to be wasted work for one request, it might halve the time to serve another request. When I say which is more common, it’s probably more a matter of the mental model of the human who implemented it. Fulfilling a request as a series of steps versus a set of concurrent steps only becomes a matter of correctness when one of those steps is dependent on another (and even then only if there’s no other reasonable way to address their dependency afterwards). I’ll add that designing for concurrency this way often leads to better design overall. It helps guide towards minimizing dependencies (or at least minimizing shared state) between functions. Which in turn isn’t just easier to reason about, but also easier to scale should you want (say) to move some expensive function out to its own service or worker.
- afiori 4y agoIt is about multi request concurrency/parallelism. If 20 users log in at the same time node and php would behave very differently. Php would start 20 processes/threads and execute each in independently. Node would dispatch 20 Request events to the event loop in the same process. I will not argue the advantage of server-side async, but here it is clear that node needs it, as those 20 database queries will be executed from the same thread. Without async the 20th user would have 20 times as much latency as the first.