4 ms·
Go’s concurrency model and Erlangs concurrency model are fundamentally the same. Erlangs mailbox and Go’s channels are the same primitive. And Erlangs process
by avianlyric 4y ago
Go’s concurrency model and Erlangs concurrency model are fundamentally the same.
Erlangs mailbox and Go’s channels are the same primitive.
And Erlangs processes and Go’s Goroutines are also the same primitive.
The big difference between the languages (from a concurrency perspective, there are other differences) is that idomatic Go is generally built around spinning off many short lived goroutines passing objects back and forth via channels, whereas Erlang generally spins off many long lived processes that represent objects, communicating mutation requests via mailboxes.
But you can do go style concurrency in Erlang, and Erlang style concurrency in go. You’ll just be swimming upstream the entire time, because your concurrency style won’t mesh well with any of the libraries out there which will be written in the idiomatic go/Erlang concurrency style.
So the idea you can create an Erlang style concurrency framework in Go isn’t actually surprising. Go and Erlang concurrency models are just opposite sides of the same coin.
- throwawaymaths 4y agoIt's not about concurrency, it's about failure domains. The go VM doesn't natively let you take out monitors/links, so if "the right thing to do" when some part of a set of concurrent tasks fails is to "just give up" (suppose task 3/5 reaches out to an external service and comes back with a 500 error)... Handling the teardown of the whole thing (and potentially rollback state) is gnarly in go. In Erlang it's often zero lines of code. In Elixir, this architecture let the anointed db engine roll back a partially completed database transaction by default (0loc) in such a scenario.
- rad_gruchalski 4y agoThere’s a very interesting aspect to what you mention here that is often overlooked. In Erlang every process has its own garbage collection. Every process has a stack and a heap. Stopping a process, or a process dying, automatically cleans up any resources used.
- jibbit 4y agoI actually think it’s rather difficult to mimic Erlang message passing in go, but trivial (and not uncommon) to mimic go channels in Erlang.
- _0w8t 4y agoIdiomatic Erlang and Go are fundamentally different. In Erlang there is one mailbox per process and multiplexing is archived via polymorphic messages. In Go there can be multiple channels and one multiplexes them using the select statement. Erlang message queue is a priority queue, while in Go a channel is a strict FIFO. In fact implementing a priority queue on top of channels in Go is rather hard. A much better approach is to code a priority queue directly using mutexes. In Erlang (at least the last time I checked this) the message queue is unbound while Go gives a lot of control over the channel queue size. As was already pointed, Erlang also supports reliable cancelation of threads, while in Go a thread has to be coded explicitly to support cancelation. All of this leads to very different style of multithreaded code in the two languages.
- toast0 4y ago> In Erlang (at least the last time I checked this) the message queue is unbound while Go gives a lot of control over the channel queue size. You can bound the queue by proxy, becsause there is a max_heap_size process flag you can set. If your process is configured to use on-heap messages, and you have a max_heap_size, that provides a bound, although maybe not in the units you'd like. You can also do things where your process might check it's own queue length (which is very cheap) and discard messages if it's too long. This doesn't work if your process gets stuck, or if discarding is still slower than the incoming message rate. Another option is a process that lists all processes and finds their queue length (not so cheap) and kills process above a threshold. You could also modify BEAM to do what you want. When I was at WhatsApp, we had a patch so you could do process_flag(flush_message_queue, N) and it would drop N messages (or all of them if N == 0), and this worked with process_flag/3 if you wanted to drop messages from the queue of another process. Of course, that sort of thing doesn't fit the BEAM messaging guarantees, so unlikely to be accepted upstream. (See also the message prepending patch, to put a message to another process at the front of its mailbox)
- yumaikas 4y agoSo, the big difference between Go and Erlang style concurrency is that go style concurrency doesn't give you a readily available reliable way to keep an eye on other goroutines, as I understand it, where there are mechanisms in Erlang (links and monitors come to mind) to help accomplish that, and, in fact, it's one of the core parts of the Erlang model of concurrency
- jerf 4y agoIt does not give you a way to reliably track arbitrary goroutines that "this" goroutine (for whatever that may be) wants to track, the way an Erlang process can just "link" to anything it is capable of naming the PID for. However, you can construct a reliable mechanism where one goroutine can start another and know whether or not the one it started has failed by using the available primitives, as I did in https://github.com/thejerf/suture https://github.com/thejerf/suture . It's an easier problem since there's no cluster and no network that can get in the way. I've also done the exercise for the network case: https://pkg.go.dev/github.com/thejerf/reign#Address.OnCloseNotify https://pkg.go.dev/github.com/thejerf/reign#Address.OnCloseN... but that only functions within the network defined by that library because, again, it just isn't arbitrarily possible. (I suppose it's relevant to some of my other comments to point out that I've also implemented basically Erlang-style concurrency in Go, with network, but as a relatively idiomatic translation rather than a blind one.)
- jerf 4y ago"Go’s concurrency model and Erlangs concurrency model are fundamentally the same." See https://news.ycombinator.com/item?id=34564228 https://news.ycombinator.com/item?id=34564228 . At the 30,000 foot view, yes. On the ground, no.