If you get to the part about monitors, consider erlang:demonitor(Ref, [flush]) in your own code. This also removes the monitor message from your mailbox if it arrived in between, which is a real problem in an async setting.
Though in some situations, it is better to just ignore the spurious message when it arrives by tracking what monitors you have enabled in the process state. Unkonwn monitors are just gracefully ignored. The same pattern is useful with timeouts as well. Cancel the timeout, but if it arrives in your mailbox while the cancel is happening, you can just detect an old timeout and ignore it.
demonitor flush can be harmful in some instances as it invokes a selective receive to yank the down message from your process's mailbox. In the event that you are demonitor+flushing on a process that has a growing message queue, every flush gets more and more costly - especially if the monitor has already delivered a DOWN message for it to yank.
it's almost always better to ignore down messages that you don't care about.
I love Erlang too, but I don't think Elixir's popularity is stealing love away from Erlang. If anything, I think Elixir compliments Erlang and provides a path for people to enter the world of Erlang, BEAM, and OTP that they didn't have before. Elixir helped to lower the bar of entry. My understanding is that the Elixir team has also helped drive some improvements in Erlang, which is nice.
Personally, I love both Erlang and Elixir and hope to ride out the rest of my career on these platforms.
As someone who has worked two jobs now writing, deploying, and operating Erlang clusters, I recommend switching to Rust. Erlang requires a lot of TLC to get right, it's super slow, and it's hard to burst. Like, super hard to burst. Erlang nodes are meant to cluster as a k graph and never go down. Modern ops, especially container ops, does availability through ephemerality of services. The BEAM just doesn't like to be treated like cattle. Also Erlang has notoriously bad error messages, very little abstraction, and converting between binary strings and lists is a pain. Gaining Erlang operational knowledge also takes a while. We eventually had to rewrite things like gen_server, ditch mnesia etc. as we scaled.
So why Rust? Like Erlang, it's damn good at concurrency and enables functional programming. It also enables event driven programming through tokio, which is a better fit for web servers than green threads (you're mostly waiting on the network). Unlike Erlang, it's super fast (even at math), has a great type system, amazing error messages, low memory usage, and the community is already quite a bit bigger.
I'm going to disagree with you on Rust. It's a very different, very verbose language. It doesn't have any of the stories around immutability that Erlang does.
You say you had to rewrite Mnesia, but Rust doesn't even have transactional memory to start with.
Suggesting that event-driven programming is anything like language-level threading like Erlang and Go is crazypants. A common error in event-driven languages is that you end up writing code that gets slow, and blocks the entire event loop, and everything falls apart, and you get paged at 2 AM, until you add another event loop.
One of the best parts of BEAM is that since processes are isolated and preemptively scheduled, you don't have to manage your own call-backs by hand, and although things may get slow, they'll typically only get slow for that one given process.
In addition to this, the GC in Erlang is great, compared the lack of GC in Rust. I think most of us can agree that unburdening yourself of having to memory management code is a good thing.
Of course, BEAM isn't perfect, after all, it's had no more as much investment as the JVM, and CLR, but I believe its semantics are right for writing predictable, low-latency code.
Also, containers have nothing to do with ephemerality. Cluster management systems which dynamically schedule containers may result in scheduling.
Erlang isn't really a dataplane runtime. Often times, you implement your control plane in Erlang, and farm out your dataplane to something NIFs, ports, or something else entirely.
You're right, disterl is a fucking mess. But, it's better than nothing, and having to write your own IPC.
I suggest you read Joe Armstrong's thesis, or a History of Erlang for more.
Your complaints about Erlang give me the impression that you may have picked the wrong language for your problem domain, and paid for that mistake by having to do things like rewriting gen_server.
Erlang was designed to be reliable and scalable. It was not designed to be fast. If fast is a hard prerequisite for you, you're right, you should go with another language. But Erlang also does a ton of things correctly (again, in the domains it was designed and optimized for), and is battle-tested far beyond Rust, since it has been around for much, much longer. That's not to say Rust is a bad language, but one should probably not judge its merits by its current popularity. That holds true for any language or tool.
Anyways, if you want abstraction (the lack of which was one of your complaints about Erlang), you should take a look at Elixir. Specifically, Phoenix is excellent for web programming, especially if you need real-time messaging at scale.
Rust has too big of a learning curve, and it's quite complex for writing service oriented systems. Granted, having a static compiler eliminates many types of bugs found in other systems.
In my opinion a more sensible approach is Elixir + Rust (via rustler). Your get the elegance and productivity of Elixir, the concurrency and fault tolerance of Erlang/OTP, while still being able to writing super fast, low level code in Rust.
Plus, you shouldn't use a single language across your whole stack. When the only tool you have available is a hammer, everything looks like a nail.
One thing that's pretty frustrating about your comments, is how you both have an answer for everything but don't actually give any specifics, which makes it nearly impossible to actually address or consider your advice.
Also, fundamentally, I think you're way out of the norm in terms of system time to build. Getting the kinds of reliability and business value guarantees out of Rust is enormously harder than what you get out of the box with the BEAM. Having to hand-roll everything would take literally months, where I can be done and providing business value in hours in the BEAM ecosystem. Now, could Rust get to this place in another year or two? Completely. But it isn't there now, and, it still ignores my second issue...
...which is difficulty. I've been programming for just under 7 years, and while I've not learned C++, Rust is not only by far the most difficult language I've encountered thus far, it's exponentially more difficult. Months to grok the basics, likely years to be effective in it. You might've had an easy time hiring for this, but that might say more about your social group and hiring channels than the actual availability of talent.
> As someone who has worked two jobs now writing, deploying, and operating Erlang clusters, I recommend switching to Rust.
I'm surprised to read this, Erlang and Rust have almost nothing in common. It's understandable that BEAM doesn't suit your needs but suggesting that everyone should write Rust instead is grossly misleading. They are suited to solving different problems!
You’re comparing the out of the box, network transparent scaling solution that is fully meshed and doesn’t claim to solve everyone’s problems forever with a solution in rust that probably involves a completely hand rolled implementation of lots and lots of different things OTP is doing. You have made me want to learn Rust though, how does it compare with Golang?
> The BEAM just doesn't like to be treated like cattle.
So don't. Deploy using edeliver and give up docker for the Erlang / Elixir parts of the project. If you really can't, you might want to switch to a language with a runtime that plays more nicely with the container idea of the world, but I know companies that deploy Erlang with docker and they are happy with that. Purists frown at the idea but it works.
The world of ephemeral containers really has changed the dynamic. Erlang solves a lot of problems with good solutions, but writing good software is only part of the battle. Lifecycle management, monitoring, etc make up a huge operational burden and should always be thought of as first-class problems in language design. Rust makes that better in many ways but not uniquely better than alternative languages.
> It also enables event driven programming through tokio, which is a better fit for web servers than green threads (you're mostly waiting on the network)
This is a really strange thing to say. Erlang is still an event-driven I/O runtime, it just doesn't inflict the user with the burden of continuation passing like tokio does. What is the benefit of doing that yourself? Even with futures its far more verbose and awkward than it needs to be. And since the entire ecosystem is not built on this io system, you will always be finding libraries - even very popular ones, such as diesel - that are incompatible with it and forcing you into threadpools. Every library in use with BEAM uses async I/O in exactly the same way.
I also find erlang does not play well with modern ops work flow like docker and kubernetes.
But as for Erlang, a lot of people uses Erlang for building in-memory massive stateful services, and a very fault tolerant system on top of it.
I'm interested in both language, but haven't start playing with Rust yet.
I tried Akka and find it's pretty good but the virtual machine is not as good as BEAM, but Scala is a powerful language.
I'm curious about Rust. Could you please share some insights about if Rust is capable of such stateful services as Erlang does, or there could be other advantages in terms of stateful/fault tolerance?
Isn't the whole point of the BEAM languages to keep distributed state reasonable to work with through the actor model. If you can put a service in a docker container and spin it up or down without losing data, then it doesn't sound like you need any of the BEAMs.
[+] [-] jlouis|7 years ago|reply
Though in some situations, it is better to just ignore the spurious message when it arrives by tracking what monitors you have enabled in the process state. Unkonwn monitors are just gracefully ignored. The same pattern is useful with timeouts as well. Cancel the timeout, but if it arrives in your mailbox while the cancel is happening, you can just detect an old timeout and ignore it.
[+] [-] jhgg|7 years ago|reply
it's almost always better to ignore down messages that you don't care about.
[+] [-] plainOldText|7 years ago|reply
* http://spawnedshelter.com/
* http://beam-wisdoms.clau.se/en/latest/
[+] [-] davidw|7 years ago|reply
[+] [-] the_clarence|7 years ago|reply
[+] [-] innocentoldguy|7 years ago|reply
Personally, I love both Erlang and Elixir and hope to ride out the rest of my career on these platforms.
[+] [-] ilovecaching|7 years ago|reply
So why Rust? Like Erlang, it's damn good at concurrency and enables functional programming. It also enables event driven programming through tokio, which is a better fit for web servers than green threads (you're mostly waiting on the network). Unlike Erlang, it's super fast (even at math), has a great type system, amazing error messages, low memory usage, and the community is already quite a bit bigger.
[+] [-] sargun|7 years ago|reply
You say you had to rewrite Mnesia, but Rust doesn't even have transactional memory to start with.
Suggesting that event-driven programming is anything like language-level threading like Erlang and Go is crazypants. A common error in event-driven languages is that you end up writing code that gets slow, and blocks the entire event loop, and everything falls apart, and you get paged at 2 AM, until you add another event loop.
One of the best parts of BEAM is that since processes are isolated and preemptively scheduled, you don't have to manage your own call-backs by hand, and although things may get slow, they'll typically only get slow for that one given process.
In addition to this, the GC in Erlang is great, compared the lack of GC in Rust. I think most of us can agree that unburdening yourself of having to memory management code is a good thing.
Of course, BEAM isn't perfect, after all, it's had no more as much investment as the JVM, and CLR, but I believe its semantics are right for writing predictable, low-latency code.
Also, containers have nothing to do with ephemerality. Cluster management systems which dynamically schedule containers may result in scheduling.
Erlang isn't really a dataplane runtime. Often times, you implement your control plane in Erlang, and farm out your dataplane to something NIFs, ports, or something else entirely.
You're right, disterl is a fucking mess. But, it's better than nothing, and having to write your own IPC.
I suggest you read Joe Armstrong's thesis, or a History of Erlang for more.
[+] [-] enraged_camel|7 years ago|reply
Erlang was designed to be reliable and scalable. It was not designed to be fast. If fast is a hard prerequisite for you, you're right, you should go with another language. But Erlang also does a ton of things correctly (again, in the domains it was designed and optimized for), and is battle-tested far beyond Rust, since it has been around for much, much longer. That's not to say Rust is a bad language, but one should probably not judge its merits by its current popularity. That holds true for any language or tool.
Anyways, if you want abstraction (the lack of which was one of your complaints about Erlang), you should take a look at Elixir. Specifically, Phoenix is excellent for web programming, especially if you need real-time messaging at scale.
[+] [-] plainOldText|7 years ago|reply
In my opinion a more sensible approach is Elixir + Rust (via rustler). Your get the elegance and productivity of Elixir, the concurrency and fault tolerance of Erlang/OTP, while still being able to writing super fast, low level code in Rust.
Plus, you shouldn't use a single language across your whole stack. When the only tool you have available is a hammer, everything looks like a nail.
[+] [-] quaunaut|7 years ago|reply
Also, fundamentally, I think you're way out of the norm in terms of system time to build. Getting the kinds of reliability and business value guarantees out of Rust is enormously harder than what you get out of the box with the BEAM. Having to hand-roll everything would take literally months, where I can be done and providing business value in hours in the BEAM ecosystem. Now, could Rust get to this place in another year or two? Completely. But it isn't there now, and, it still ignores my second issue...
...which is difficulty. I've been programming for just under 7 years, and while I've not learned C++, Rust is not only by far the most difficult language I've encountered thus far, it's exponentially more difficult. Months to grok the basics, likely years to be effective in it. You might've had an easy time hiring for this, but that might say more about your social group and hiring channels than the actual availability of talent.
[+] [-] dxhdr|7 years ago|reply
I'm surprised to read this, Erlang and Rust have almost nothing in common. It's understandable that BEAM doesn't suit your needs but suggesting that everyone should write Rust instead is grossly misleading. They are suited to solving different problems!
[+] [-] andy_ppp|7 years ago|reply
[+] [-] pmontra|7 years ago|reply
So don't. Deploy using edeliver and give up docker for the Erlang / Elixir parts of the project. If you really can't, you might want to switch to a language with a runtime that plays more nicely with the container idea of the world, but I know companies that deploy Erlang with docker and they are happy with that. Purists frown at the idea but it works.
[+] [-] dev_dull|7 years ago|reply
[+] [-] jeremyjh|7 years ago|reply
This is a really strange thing to say. Erlang is still an event-driven I/O runtime, it just doesn't inflict the user with the burden of continuation passing like tokio does. What is the benefit of doing that yourself? Even with futures its far more verbose and awkward than it needs to be. And since the entire ecosystem is not built on this io system, you will always be finding libraries - even very popular ones, such as diesel - that are incompatible with it and forcing you into threadpools. Every library in use with BEAM uses async I/O in exactly the same way.
[+] [-] namelos|7 years ago|reply
[+] [-] ecthiender|7 years ago|reply
I don't think it's constructive to the discussion here to say X has drawbacks (and then go on at it), use Y (and then go on at it).
I have not used Erlang or Rust, and when I read this comment, it seemed flamewar-ish to me.
[+] [-] tormeh|7 years ago|reply
[+] [-] unknown|7 years ago|reply
[deleted]
[+] [-] stplsd|7 years ago|reply
What exactly does 'burst' mean in this context?
[+] [-] abledon|7 years ago|reply
[+] [-] kauboy|7 years ago|reply
[+] [-] Immortalin|7 years ago|reply
[+] [-] xq3000|7 years ago|reply
PS: Content looks cropped on an iPhone 7 nonmatter how you resize it
[+] [-] Waterluvian|7 years ago|reply
[+] [-] phyrex|7 years ago|reply