5 ms·
On that note, coming back from node.js has been a really frustrating experience for me. I want to scream every time somebody suggests threading as a solution to
by nulagrithom 9y ago
On that note, coming back from node.js has been a really frustrating experience for me. I want to scream every time somebody suggests threading as a solution to non-blocking database calls and HTTP requests. It's made me painfully aware of how often parallelism is suggested in place concurrency.
C# in particular does a great job at conflating concurrency and parallelism. Both fall under the same Task namespace and it drives me mad to no end. I've also seen a couple instances of Execute and ExecuteAsync both blocking because the underlying driver didn't support async, with no indication other than my async calls blocking.
It's quite different from the async-by-default sort of thing that's going on in the node.js world.
- cdelsolar 9y agobut why? Go's model is perfect. They're not real threads, it's basically very similar to Node, except that you can write code without a mess of callbacks and it's easier to reason about...
- stouset 9y agoGo's model doesn't even statically prevent data races (as Rust's does). You might think Go's model is good, but it's a far cry from perfect. Although I'll be happy to point out why Go's model isn't even good. Go's lack of ability to perform meaningful abstraction combined with the low level of its concurrency primitives means you end up having to copy/paste and slightly tweak dozens of lines of flow-control logic every time you use them. This[1] is an excellent critique of Go's concurrency model. [1]: https://gist.github.com/kachayev/21e7fe149bc5ae0bd878#so-what-about-patterns https://gist.github.com/kachayev/21e7fe149bc5ae0bd878#so-wha...
- a13n 9y agoasync await though
- paulddraper 9y agoAnd no shared-memory CPU parallelism.
- a13n 9y agoNo threading bugs though.
- owaislone 9y agoNot just that. It can use multiple OS threads and multiplex the goroutines on actual threads so programs can actually leverage multiple cores.
- brightball 9y agoNothing's perfect. Go's is Erlang's with a shared memory model. That creates a lot of trade offs and limitations. In some places, it's a perk. In others, it's not. No such thing as perfect, only trade offs.
- int_19h 9y agoGo's model breaks down as soon as you have to invoke into non-Go code, because the latter has no idea about goroutines. This is a general problem with all "green thread" abstractions - they are not OS level, or if they are (as e.g. fibers are on Win32), nobody cares to use them. Promises, on the other hand, can be mapped to a straightforward callback-oriented C API, thus allowing a fully async execution stack end-to-end across different languages. You can even go one step further and define a uniform API for all such callbacks, as WinRT did.
- thomasz 9y agoIt's hardly the fault of the language if people are lying in their method signatures. I'm not aware of a mainstream PL with a type system that is powerful enough to avoid something like that.
- nulagrithom 9y agoIn this case, the .NET-provided base class defaults to using the synchronous version when the async version hasn't been overridden. https://msdn.microsoft.com/en-us/library/system.data.common.dbcommand.executedbdatareaderasync(v=vs.110).aspx#Version%20Information https://msdn.microsoft.com/en-us/library/system.data.common.... > Providers should implement this method to provide a non-default implementation for ExecuteReader overloads. > The default implementation invokes the synchronous ExecuteReader method and returns a completed task, blocking the calling thread. The default implementation will return a cancelled task if passed an already cancelled cancellation token. Exceptions thrown by ExecuteReader will be communicated via the returned Task Exception property. Found that after several hours of tearing my hair out trying to figure out why my async calls were still blocking...
- int_19h 9y agoThis is a bug in the library. The correct way to do these "async but not really" wrappers is to call the synchronous implementation in a separate thread pool worker thread, and wrap that into a task (as Task.Run does). This is hardly optimal perf-wise, but it is truly asynchronous wrt to the caller. If I remember correctly, it's what Stream does for its default implementations of async methods.
- AgentME 9y agoA little tip from someone coming back into Java after using modern javascript / node.js lately: Java 8's CompletableFutures are basically Java's Promises, and they have good support for doing steps in specific thread pools. (Regular Futures are way too limited: if you want to do an action as soon as a Future resolves, then you have to dedicate a thread just to blocking on that Future, which is not exactly what you want if you have a lot of simultaneous asynchronous operations of multiple steps going on.)
- davedx 9y agoElixir does it very well, I think.
- corford 9y ago> I want to scream every time somebody suggests threading as a solution to non-blocking database calls and HTTP requests. Rather than screaming, perhaps read this (from the developer of the Python world's most popular ORM) to see why they might be suggesting it: http://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/ http://techspot.zzzeek.org/2015/02/15/asynchronous-python-an... tl;dr: If your database is properly setup and provisioned it shouldn't be a source of blocking I/O (and if it is, throwing thousands of concurrent async connections at it isn't going to help you). For standard CRUD applications, your program will spend much more time in CPU processing the database response than it will waiting on the database to deliver it. Furthermore, when querying a traditional RDBMS like postgres or mysql, safe concurrency is ultimately enforced by the ACID capabilities built in to the database itself i.e. transactions. Whether you're using async, threads, multiple processes or something else entirely doesn't matter. Given the database itself controls how much concurrency it can support, real world tests (at least for Python) show that threads give you better performance than event driven callbacks. Of course, threads are completely wrong for the HTTP side of things and this is where async (e.g. nginx or node) offers all of its advantages. That doesn't mean it's wrong to put your DBMS behind a thread pool.