News for hackers. Stuff that matters.
Re:Memory usage of a toy C# server and client with 500K conc... by weberc2 on Saturday January 26, 2019 @05:24PM (#19008934)
> 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 :)

Re:Memory usage of a toy C# server and client with 500K conc... by zzzcpan on Saturday January 26, 2019 @05:52PM (#19009085)
I 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.
Re:Memory usage of a toy C# server and client with 500K conc... by WoodenChair on Saturday January 26, 2019 @07:22PM (#19009499)
Re:Memory usage of a toy C# server and client with 500K conc... by zzzcpan on Saturday January 26, 2019 @07:24PM (#19009512)
Re:Memory usage of a toy C# server and client with 500K conc... by giancarlostoro on Saturday January 26, 2019 @07:56PM (#19009659)
Goroutines are probably closer to Fibers which D also has:

https://en.wikipedia.org/wiki/Fiber_(computer_science)

Re:Memory usage of a toy C# server and client with 500K conc... by zzzcpan on Saturday January 26, 2019 @08:15PM (#19009770)
They 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.
Re:Memory usage of a toy C# server and client with 500K conc... by giancarlostoro on Saturday January 26, 2019 @10:11PM (#19010151)
Care to share a reference to them no longer being lightweight?
Re:Memory usage of a toy C# server and client with 500K conc... by zzzcpan on Sunday January 27, 2019 @01:11PM (#19012893)
They still start with tiny stacks, if that's what you are asking. I believe it's somewhere around 2 KB nowadays.
Re:Memory usage of a toy C# server and client with 500K conc... by hu3 on Sunday January 27, 2019 @06:37AM (#19011341)
goroutines are anything but threads.

Here's a 40min talk explaining how Go's scheduler works:

https://youtu.be/YHRO5WQGh0k

Re:Memory usage of a toy C# server and client with 500K conc... by zzzcpan on Sunday January 27, 2019 @01:05PM (#19012860)
No, 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.
Re:Memory usage of a toy C# server and client with 500K conc... by Groxx on Tuesday January 29, 2019 @07:01PM (#19031204)
I 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.
Re:Memory usage of a toy C# server and client with 500K conc... by tiuPapa on Sunday January 27, 2019 @12:06AM (#19010427)
I have used both and its hard to argue that goroutines and channels are as easy to use as async/await.
Re:Memory usage of a toy C# server and client with 500K conc... by weberc2 on Monday January 28, 2019 @09:36AM (#19017661)
On 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.
Re:Memory usage of a toy C# server and client with 500K conc... by tigershark on Sunday January 27, 2019 @03:00AM (#19010823)
Goroutines are not threads. Async await behind the scenes uses threads.
Re:Memory usage of a toy C# server and client with 500K conc... by wallstop on Sunday January 27, 2019 @03:48AM (#19010944)
Re:Memory usage of a toy C# server and client with 500K conc... by tigershark on Sunday January 27, 2019 @04:02AM (#19010981)
In that case and in some others it doesn’t, but in general it does: 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.
Re:Memory usage of a toy C# server and client with 500K conc... by tapirl on Saturday January 26, 2019 @06:56PM (#19009387)
After I used Go channels (https://go101.org/article/channel-use-cases.html), I feel async/await is much like a rigid toy. :)
Re:Memory usage of a toy C# server and client with 500K conc... by benaadams on Saturday January 26, 2019 @07:47PM (#19009608)
Can use System.Threading.Channels https://docs.microsoft.com/en-us/dotnet/api/system.threading... if you like that programming model
Re:Memory usage of a toy C# server and client with 500K conc... by coder543 on Saturday January 26, 2019 @08:16PM (#19009777)
Do 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.
Re:Memory usage of a toy C# server and client with 500K conc... by manigandham on Saturday January 26, 2019 @08:27PM (#19009818)
Yes. It's a library that is fully async. We process millions of records/second using these.
Re:Memory usage of a toy C# server and client with 500K conc... by noir_lord on Sunday January 27, 2019 @01:43PM (#19013074)
Do 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.
Re:Memory usage of a toy C# server and client with 500K conc... by manigandham on Sunday January 27, 2019 @02:43PM (#19013402)
This is the best overview article so far: https://ndportmann.com/system-threading-channels/
Re:Memory usage of a toy C# server and client with 500K conc... by noir_lord on Sunday January 27, 2019 @02:53PM (#19013451)
Thank you.
Re:Memory usage of a toy C# server and client with 500K conc... by benaadams on Saturday January 26, 2019 @08:28PM (#19009826)
Yeah you have a triple for different use cases; the sync call is `TryRead` so its non-blocking; `ReadAsync` for async reading and `WaitToReadAsync` to wait for data to be available without reading (likely then followed by the non-blocking `TryRead` in usage)
Re:Memory usage of a toy C# server and client with 500K conc... by tapirl on Saturday January 26, 2019 @08:24PM (#19009809)
Does it support select? Almost half of concurrrent programming use cases in Go are select related.
Re:Memory usage of a toy C# server and client with 500K conc... by benaadams on Saturday January 26, 2019 @09:02PM (#19009955)
Yeah, at a guess you'd combine the multiple `WaitToReadAsync` with `await Task.WhenAny`; then use `TryRead` to run though the bunch of channels in a non-blocking way.

Could even use the return `await Task.WhenAny` to tell you the specific one to check. Shouldn't be a very hard construct to make; to make it more select like.

Re:Memory usage of a toy C# server and client with 500K conc... by tapirl on Saturday January 26, 2019 @09:46PM (#19010093)
good. It looks it is much like the reflect.Select (https://golang.org/pkg/reflect/#Select) in Go.

It has the benefit that any number of tasks can be selected, but the efficiency is not good as hard-coded select blocks.

But it looks C# Task.WhenAny has much less use case variants than Go select block.

Re:Memory usage of a toy C# server and client with 500K conc... by Groxx on Saturday January 26, 2019 @06:20PM (#19009215)
aka "threading without thread handles". no thanks.
Re:Memory usage of a toy C# server and client with 500K conc... by weberc2 on Saturday January 26, 2019 @09:35PM (#19010064)
It works out okay for the most part, but fair point.
Re:Memory usage of a toy C# server and client with 500K conc... by sifoobar on Saturday January 26, 2019 @08:17PM (#19009781)
The 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

Re:Memory usage of a toy C# server and client with 500K conc... by weberc2 on Saturday January 26, 2019 @09:42PM (#19010083)
I 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.
Re:Memory usage of a toy C# server and client with 500K conc... by int_19h on Sunday January 27, 2019 @05:24AM (#19011187)
> Never mind the problems of async code in a dynamic language.

Such as?

Re:Memory usage of a toy C# server and client with 500K conc... by weberc2 on Sunday January 27, 2019 @10:32AM (#19012021)
Forgetting 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.
Re:Memory usage of a toy C# server and client with 500K conc... by int_19h on Sunday January 27, 2019 @09:41PM (#19015059)
An 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).
Re:Memory usage of a toy C# server and client with 500K conc... by weberc2 on Wednesday January 30, 2019 @06:38PM (#19040809)
That 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.