Earlier quoted context omitted.
> 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…
A 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 ot…
Build your own web framework
151–155 of 155 posts
Re: Build your own web framework
#152This is too funny. I predicted that when I entered this post the first comment would be HN people bemoaning complexity. And indeed it was. The commenter's proposed solution was WASM. Wasm doesn't solve the issues in this post. What does this post talk about: - serving content from the edge (wasm doesn't do anything there) - asset optimization (wasm doesn't help) - pre-rendering complex pages to static HTML+css (wasm…
That's HN. 8 years ago it would have been how Ethereum will make this all redundant
Re: Build your own web framework
#153Earlier quoted context omitted.
A 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 ot…
Okay, then it sounds like we've been using a different definition of "async" all along then.
Maybe some pseudocode will help illustrate. Here is a hypothetical[1] implementation of the Node equivalent of the PHP design you described:
const handleRequest = async (request) => {
try {
const userData = await getUserData(request)
const blogData = await getBlogData(request)
return whatever(userData, blogData)
} catch (error) {
return errorResponse(error)
}
}
In this function, both `await` expressions suspend the current call and yield to the event loop, until the `Promise` returned by the awaited function resolves. During this time, Node will be idle and able to accept additional requests on the same thread.But because, in this hypothetical implementation, `getBlogData` doesn’t depend on `getUserData`, it could be written this way too:
const handleRequest = async (request) => {
try {
const [ userData, blogData ] = await Promise.all([
getUserData(request),
getBlogData(request)
])
return whatever(userData, blogData)
} catch (error) {
return errorResponse(error)
}
}
Both implementations are functionally equivalent, but the latter speculatively risks wasted work for the potential benefit of IO concurrency in the non-error case. This is a common performance optimization technique for single-threaded runtimes like Node, where `await` might represent a significant portion of the response time.To your original wondering, why `await` at all? Well, for one because you have no choice. With very few exceptions, all IO is asynchronous in Node. And async colors[2] JS functions. More importantly, because JS is (mostly) single threaded and generally spawning new processes is either not available or expensive to do on demand. Getting the most processing out of a single process is the whole point.
Other environments will either accomplish something similar with threads, or spin up a process per request and depend on the OS for scheduling work. They’re all slightly different trade offs along the same general theme: make idle resources available while waiting. Node’s trade-off is that it has to handle a global (or process-wide anyway) task queue. Threaded approaches and similar put more scheduling control, resources, and complexity, in the hands of devs. Process-per-request eliminates the need to think about any of this, at the expense of cold start times and memory.
All of those trade-offs are reasonable depending on the workload and depending on the environment. Part of the reason `async` (the keyword and/or language facility) has gained popularity across a wide variety of use cases is that the combination of concurrent state complexity, cold start time, and memory pressure makes it appealing to model the problem in a way that almost looks synchronous.
1: Node devs stumbling upon this: yes I realize this isn’t the typical interface for a request callback. That’s intentional to keep it simple, but you can do it this way if the traditional callback hell interfaces are not your cup of tea… you just need a simple wrapper.
2: http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...
Re: Build your own web framework
#154Earlier quoted context omitted.
This isn’t helpful. They very clearly and frankly asked. Don’t shame people for not knowing something you already know, they’ll very probably be turned off from learning it.
It is a different story if they asked in good faith, but they clearly started their initial comment as a derisive declaration of something being useless, so it sounded to me that they had no real intention of actually learning.
I think the various “assume best intent” rules and adages would benefit greatly from a huge “assume limited familiarity when dismissiveness seems out of place” addendum. At least for technical topics where the stakes are “whoops we actually just disagree on the merits”.
Re: Build your own web framework
#155Earlier quoted context omitted.
Not sure if they edited their comment (although it seems unlikely given that your comment was four hours later), but that sounds exactly like what they said they did. Maybe I'm old-fashioned, but the idea that I need to upload a plaintext file to have it converted to another plaintext file so I can download it instead of just having a command to run locally seems almost surreal.
There is a command to run locally, `babel`. It works in the command line as well as part of a build tool. It seemed me that the parent however didn't want to spend more time learning all that if they needed to convert just one file.