6 ms·
Not knowing enough about Erlang/OTP or Go: Would it be possible for more of OTP to be replicated in a Go 2.0? What's missing? What would it take? What can ne
by Nogwater 13y ago
Not knowing enough about Erlang/OTP or Go: Would it be possible for more of OTP to be replicated in a Go 2.0? What's missing? What would it take? What can never be replicated?
- seiji 13y agoErlang is like Lisp in that once you build a language up to a level of "reliable disturbed system language," you've basically re-implemented Erlang.
- limmeau 13y agoIs "disturbed system" intentional? Nice term for a bunch of processes which are expected to die occasionally.
- jerf 13y agoYou can recover a substantial portion, but there's a few things you can't quite get back. Since Go is a mutable-state language, and also a shared-state language (isolation is by convention, not by language design), you have to live with the consequences of that. In my supervisor tree implementation, the restart of a monitored goroutine is just to fire off a new goroutine on the exact same object again; if you still have bad state lying around and immediately crash again, well, too bad, the supervisor can't do anything about that. (Except not thrash the processor with endless restarts.) In contrast, when an Erlang supervisor restarts a process, it is guaranteed to be a fresh process with no shared state from the one that just crashed. It's much more likely to not immediately crash. (I fiddled with having the user specify a closure that is supposed to "create" a new object for the restart, but then simplified that away when I realized that the closure itself could well have mutable state too. Better just to stick with the simpler interface and document the consequences of failing to clean out state at the beginning of your monitored code. On the plus side, so far the interface for the supervised-things is "Serve()" and "Stop()", and nothing else; hard to argue with that level of simplicity!) You also won't ever be able to recover live code restarts; you can try to transfer all state to a new process, including file handles, but that's a lot of implementation work. (I'm stuck right now on the fact that my connections are encrypted, and the encryption code won't let me even get to the state, let alone transfer and reconstitute it somewhere else. Someone's got some code for moving file handles around on GitHub but I can't seem to Google it up.) Most people already live in a world where live restarts are difficult or impossible, though, so they won't miss that. Getting a REPL into a live Go server is impossible, at least with Go itself, and will also probably never be as clean as Erlang. (Go "2.0" could fix that with an official Go interpreter, which is the missing bit. I can handle the sockets, I can bind readline and give you a nicer REPL, but interpreting Go is a challenge. Progress is being made, I believe as part of the new compiler implementation, but I'm not sure anyone has this as an explicit goal.) Again, most people live in a world where they already don't have a REPL into their running code, and therefore won't miss this. There's also some more subtle semantic differences, but I'm saving that for a blog post. (It gets long, especially if I first have to explain Erlang, which is what the blog post does.)
- mh- 13y agoreally looking forward to that blog post. I clicked to your github profile in your other comment upthread, but realized I was already following you there after seeing gomempool. :)
- mononcqc 13y agoI'd have to say your idea of supervisors misses the point. Supervised processes provide guarantees in their initialization phase, not a best effort. This means that they are always restarted to a known stable state. It's not just a question of retrying, it's a question of returning to a piece of data and environment that is reliable. I wrote on this more in details at http://ferd.ca/it-s-about-the-guarantees.html http://ferd.ca/it-s-about-the-guarantees.html If you reuse the same exact object again that can be modified, you lose these guarantees entirely, and it becomes a question of convention and attention to detail rather than something provided for you. The REPL is a vital part of my every day Erlang experience. I can't imagine living without one when things get tricky in production and that pre-built tools aren't enough. Being able to poke around and inspect everything while it runs is great.
- pjungwir 13y agoIt is funny to me that Erlang combines unique tools for application stability with the ability to edit stuff online in production. I'm not saying I never launch a production Rails console, but seeing that in Erlang is a weird juxtaposition. I'd love to understand better how those fit together comfortably in an Erlanger's world view.
- uwiger 13y agoIn practice, one will have to refrain from some of the crazier stuff when working interactively in the shell of a production system. However, it's extremely useful for debugging and minor adjustments by a skilled engineer. Things you can do include inspection of data structures, (very) careful tracing, loading of instrumented modules or minor corrections. Since Erlang is dynamically typed, practically all data structures can be inspected at run-time, and one particularly nice thing about the Erlang shell is that it tends to be responsive even when the system is operating at near-maximum load.
- waffle_ss 13y agoBesides the issues that jerf mentioned, Erlang also has per-process garbage collection built right into the VM. Last time I checked Go's garbage collection was still stop-the-world, mark-and-sweep, making it less suitable for soft real-time systems than Erlang.
- jerf 13y ago"Go 2.0" probably can't ever quite fix that, but there's some potential for improvement; one can imagine as an optimization the compiler being able to determine a particular goroutine really is isolated (no shared state with anything else at start time, communicates only via channels that are full copiers of state, etc.) and independently GC's them, and also excludes them from the "stop" in the "stop the world". But yes, it is stop-the-world, and I'm keeping a close eye on the GC performance in the app I'm transitioning. (So far the numbers are working out OK, but it's definitely in the range I have to watch out.)
- waffle_ss 13y agoYeah I don't doubt there are some smart people out there that could make something like that happen (look at Azul and their pauseless GC for the JVM for example). However, it will be a tough fix when compared to the simple/pure approach Erlang takes.
- erichocean 13y agoFor the life of me, I cannot understand why Oracle hasn't bought Azul and made it available to all, for free. Azul only works well on multi-processor machines with LOTS of RAM, but when it does, it beats everything else out there by a mile. You'd think Oracle would want that.
- deleted 13y ago[deleted]
- voidlogic 13y agoThe Go situation is changing: runtime: concurrent GC sweep Moves sweep phase out of stoptheworld by adding background sweeper goroutine and lazy on-demand sweeping. https://codereview.appspot.com/46430043/ https://codereview.appspot.com/46430043/