4 ms·
I'm not a Go expert but preemptive scheduling of goroutines is supposed to be one of the primary benefits of Go as a language [1]. Although I'm not sure if ther
by ksbrooksjr 4y ago
I'm not a Go expert but preemptive scheduling of goroutines is supposed to be one of the primary benefits of Go as a language [1]. Although I'm not sure if there's any runtime that adopts preemptive scheduling as fervently as the BEAM. Even the regular expression engine is preemptive in Erlang, which prevents regular expression denial of service attacks [2].
[1] https://go.dev/src/runtime/preempt.go https://go.dev/src/runtime/preempt.go
[2] https://www.erlang.org/doc/man/re.html#:~:text=run/3%20always%20gives%20control%20back%20to%20the%20scheduler%20of%20Erlang%20processes%20at%20intervals%20that%20ensures%20the%20real%2Dtime%20properties%20of%20the%20Erlang%20system https://www.erlang.org/doc/man/re.html#:~:text=run/3%20alway....
- Fire-Dragon-DoL 4y agoIt wasn't non-cooperative pre-emptive scheduling for a while, which is why I kept pushing Elixir, until Go implemented it. Now Go has the same benefit as Elixir, but it's very, very fast.
- ksbrooksjr 4y agoYeah with preemptive scheduling, static typing, and better cpu utilization Go is a pretty compelling option for Erlang and Elixir users.
- cztomsik 4y agoIt's not immutable, there is no messaging, no hot-swap, no supervisors, it's not FP, and it doesn't have transparent support for clustering. Also, it's not memory-safe, 30ys old, and battle-tested pretty much everywhere.
- ksbrooksjr 4y agoThere are definitely trade offs when switching from Elixir or Erlang to Go. If you're a functional programmer who can't live without immutability, or you plan on running a cluster of machines that can communicate with each other and hot-swap code into the running system, then Elixir and Erlang are good choices. If you have some extremely CPU intensive code, or you like cross compiling to a lightweight binary, or you need static typing (without giving up preemptive scheduling), Go is a decent choice. Elixir and Erlang are not slow by any metric, but there are faster languages. Discord famously had to augment their Elixir code with Rust for example to scale to 11 million users [1]. [1] https://discord.com/blog/using-rust-to-scale-elixir-for-11-million-concurrent-users https://discord.com/blog/using-rust-to-scale-elixir-for-11-m...
- cztomsik 4y agothat is much better point, but erlang gives you reliable system by default and you have to try really hard to make it crash, whereas go is just regular compiled language and such programs typically crash more easily/often.
- ksbrooksjr 4y agoErlang is definitely more fault tolerant than most languages, but I've found that static typing tends to catch a lot of errors in development that would otherwise crash an application in production. The compiler won't catch every bug, and you'll still typically have to restart a crashed service periodically (via systemd, or a container orchestrator, or whatever process manager you use), but it definitely helps. Gleam is a pretty good choice if you need type safety and you want to run on the BEAM https://gleam.run/ https://gleam.run/. It still has the same performance characteristics as Erlang (which it compiles to), but at least it gives you type safety.
- ogogmad 4y agoRegex DoSes can be made impossible without using any concurrency. See Go's and Rust's implementation. Also see https://swtch.com/~rsc/regexp/ https://swtch.com/~rsc/regexp/
- ksbrooksjr 4y agoI wasn't trying to imply that concurrency is the only way to mitigate ReDos attacks, I was just pointing out that the BEAM applies preemption seemingly everywhere, which I found interesting.
- toast0 4y agoThe BEAM misbehaves when a scheduler gets stuck in a process (or other activity) for too long. As a result, anything that can take a long time needs to have yield points. This is a human process; when I started using Erlang, garbage collection didn't yield, List1 ++ List2 took forever with large lists and didn't yield, we didn't have line numbers in backtraces, and we had to hotload our code uphill in the snow both ways. It's not unusual for a new OTP release to have added new yield points in BIFs or NIFs that could run long or even in core VM workings.
- ogogmad 4y agoThere was someone recently on HN who didn't know about the possibility of non-backtracking implementations of regex.