7 ms·
> Once you use async/await it's hard to go back, since the code is as easy to write as synchronous code. Wait until you try goroutines :)
by weberc2 8y ago
> Once you use async/await it's hard to go back, since the code is as easy to write as synchronous code.
Wait until you try goroutines :)
- zzzcpan 8y agoI don't think anyone would enjoy going back to goroutines (threads) after async/await. Multithreaded code is actually much harder to write and deal with. Go is inappropriate example here.
- WoodenChair 8y agoGoroutines are not threads: https://rcoh.me/posts/why-you-can-have-a-million-go-routines-but-only-1000-java-threads/ https://rcoh.me/posts/why-you-can-have-a-million-go-routines...
- zzzcpan 8y agohttps://en.wikipedia.org/wiki/Thread_(computing)#M:N_(hybrid_threading) https://en.wikipedia.org/wiki/Thread_(computing)#M:N_(hybrid...
- giancarlostoro 8y agoGoroutines are probably closer to Fibers which D also has: https://en.wikipedia.org/wiki/Fiber_(computer_science) https://en.wikipedia.org/wiki/Fiber_(computer_science)
- zzzcpan 8y agoThey used to be closer to fibers years ago, when they were running on a single thread by default. Now they behave exactly like normal threads with the same problems. And fibers are threads anyway.
- giancarlostoro 8y agoCare to share a reference to them no longer being lightweight?
- zzzcpan 8y agoThey still start with tiny stacks, if that's what you are asking. I believe it's somewhere around 2 KB nowadays.
- hu3 8y agogoroutines are anything but threads. Here's a 40min talk explaining how Go's scheduler works: https://youtu.be/YHRO5WQGh0k https://youtu.be/YHRO5WQGh0k
- zzzcpan 8y agoNo, they are threads. It doesn't matter if they start with tiny growing stacks and whether blocking syscall wrappers call into the scheduler. Those are just implementation details.
- Groxx 8y agoI mean, sure, but they have all the same problems as threads for most / application-level developers. They're indeed quite different when you get into calling out to C or other kinds of FFI, but relatively few developers need to do so directly. For everyone else, they come with very nearly exactly the same semantics as threads.
- tiuPapa 8y agoI have used both and its hard to argue that goroutines and channels are as easy to use as async/await.
- weberc2 8y agoOn the surface, perhaps, but when you factor in the gotchas of both approaches and the debugging difficulty, I much prefer goroutines. In particular, I’ve never witnessed someone DOS a fleet of servers in Go by scheduling a task was making a sync call under the covers, by doing an intensive computation in the event loop, or by scheduling tens of thousands of tiny events. We also have a lot of bugs involving accidentally putting the task/coroutine into a variable instead of the result of the task because the programmer forgot the “await” keyword, but that’s a dynamic typing problem.
- tigershark 8y agoGoroutines are not threads. Async await behind the scenes uses threads.
- wallstop 8y agoDoes it? https://blog.stephencleary.com/2013/11/there-is-no-thread.html https://blog.stephencleary.com/2013/11/there-is-no-thread.ht...
- tigershark 8y agoIn that case and in some others it doesn’t, but in general it does: https://stackoverflow.com/questions/17661428/async-stay-on-the-current-thread https://stackoverflow.com/questions/17661428/async-stay-on-t... Probably it makes sense to say that async await can try to use a continuation passing style or run on a different thread because there is no actual guarantee that it will use one or the other.
- Groxx 8y agoaka "threading without thread handles". no thanks.
- weberc2 8y agoIt works out okay for the most part, but fair point.
- tapirl 8y agoAfter I used Go channels (https://go101.org/article/channel-use-cases.html https://go101.org/article/channel-use-cases.html), I feel async/await is much like a rigid toy. :)
- benaadams 8y agoCan use System.Threading.Channels https://docs.microsoft.com/en-us/dotnet/api/system.threading.channels?view=dotnet-plat-ext-2.1 https://docs.microsoft.com/en-us/dotnet/api/system.threading... if you like that programming model
- coder543 8y agoDo those channels support async? Since C# is built around async/await for scaling to large numbers of connections / tasks, they wouldn't be very useful if they didn't support async, but I'm not familiar enough with modern C# to figure out if they do or not.
- manigandham 8y agoYes. It's a library that is fully async. We process millions of records/second using these.
- noir_lord 8y agoDo you happen to have any public information on this approach, it sounds interesting but I'm not up on the C# world like I used to be.
- manigandham 8y agoThis is the best overview article so far: https://ndportmann.com/system-threading-channels/ https://ndportmann.com/system-threading-channels/
- 8y ago
- sifoobar 8y agoThe thing about Go is that you're always writing preemptively threaded code, with all of its issues. The holy grail is cooperative multitasking and always-on, opt-out async [0] if you ask me. [0] https://gitlab.com/sifoo/snigl#tasks https://gitlab.com/sifoo/snigl#tasks
- weberc2 8y agoI guess I think of that as a feature, but I also write threadsafe code by default. It’s not an issue compared to our async python code. Someone calling a library that makes sync calls under the hood can block the event loop until the load balancer kills it. Same thing with CPU intensive tasks or just a lot of tasks on the event loop. Never mind the problems of async code in a dynamic language.
- int_19h 8y ago> Never mind the problems of async code in a dynamic language. Such as?
- weberc2 8y agoForgetting the “await” keyword and trying to use a variable which now actually holds a future/coroutine as though it were the awaited future. We write tests to cover those cases.
- int_19h 8y agoAn interesting point. But this could be mitigated in a fairly obvious way by requiring an equivalent of "await" that is basically an identity transform for future-returning function calls (i.e. if a call is returning a future, you must always either explicitly indicate that you're awaiting it, or else explicitly indicate that you want the raw future - a naked call is an error).
- weberc2 8y agoThat wouldn't solve the problem at all--at best I'm getting a marginally clearer error message. It doesn't help me (the programmer) remember (before runtime) that my expression is evaluating to an async function and not a sync function. Whether I get the runtime error, "invalid call to async function" or "future has no property 'status_code'" is of little consequence.