Live data from Hacker News

Why Discord is switching from Go to Rust

blog.discordapp.com

641–650 of 670 posts

Re: Why Discord is switching from Go to Rust

#641
post #477

Earlier quoted context omitted.

Third, there was also a language I can't remember the name of that happened at the same time as Alef.

Newsqueak?

That may have been what I was thinking of (or Squeak, for that matter, if my sense of time was off), but I'm not sure!

Re: Why Discord is switching from Go to Rust

#642

Earlier quoted context omitted.

This may be overly cynical, but don’t you have it backwards? 1000x greater memory usage is acceptable for most applications. There are only a few applications for which it isn’t acceptable. Just look at all the massive apps built on Electron. People wouldn’t do that if it wasn’t effective.

Wouldn't you say there's a difference between "effective" and "getting away with it"? If non-technical users see that their daily computing lives are made more complicated (because of lowered performance) by having n Electron apps running at the same time, they may not understand the reasons, but they will certainly choose a different solution that has the features they need, where available.

Wouldn't you say there's a difference between "effective" and "getting away with it"?

I used to think that but now I’m not so sure. :(

Re: Why Discord is switching from Go to Rust

#643
post #614
post #482

Earlier quoted context omitted.

Yeah the scale is what makes this problem a problem here. I've done exactly that "online" stuff per user process and it works fine on a small scale, even when it needs to be globally inferred. But I suspect it'd quickly become the bottleneck when scaling. I had no idea mnesia was that fragile though, what gives? What kind of issues did you encounter with it? What do you use now to solve those issues with Erlang/Elixi…

"I had no idea mnesia was that fragile though, what gives? What kind of issues did you encounter with it? What do you use now to solve those issues with Erlang/Elixir?" I had ~10,000 devices in the field with unique identifiers creating long-term, persistent connections to a central cluster. An mnesia table stored basically $PERSISTENT_ID -> PID they are connected to. It needed to be updated when they connected and d…

Thanks for the comprehensive reply!

I guess I better experiment more with mnesia before really using it for anything serious. Or find alternatives. We had Redis before but that experience turned out just awful so we got rid of it.

As for the community, I think Elixir is where it's at nowadays. There is, unsurprisingly, a very strong focus on webby stuff with Elixir, and a lot of the things you would build with it are just easy. Like a multi-machine chat server.

If I started to build a new distributed chat server today, Elixir would still be the easiest way to go, despite eventually likely not being the most performant solution out there. Discord likewise seems happy with their choice for this particular use case, only supplementing it with the likes of Rust for specific problems in their domain.

I mean you yourself built a lot of the Erlang's/BEAM's logic from the scratch on Go just to be able to use it there. I'm expecting I'd end up in a similar alley with Rust/Haskell/take your pick if I was attacking the problems where Elixir has all the facilities already set up and battle tested.

Re: Why Discord is switching from Go to Rust

#644
post #71

Earlier quoted context omitted.

Keeping GC off for a long running service might become problematic. Also, the steady state might have few allocations, but startup may produce a lot of garbage that you might want to evict. I've never done this, but you can also turn GC off at runtime with SetGCPercent(-1). I think with that, you could turn off GC after startup, then turn it back on at desired intervals (e.g. once an hour or after X cache misses). It…

> ...all instances might OOM near the same time. CloudFront, for this reason, allocates heterogeneous fleets in its PoPs which have diff RAM sizes and CPUs [0], and even different software versions [1]. > When they all restart with cold caches, they might hammer the database again and cause the issue to repeat. Reminds me of the DynamoDB outage of 2015 that essentially took out us-east-1 [2]. Also, ELB had a similar…

Google's SRE book covers some of this (if you aren't cheekily referring to that). E.g. chapters 21 and 22 are "Handling Overload" and "Addressing Cascading Failures". The SRE book also covers mitigation by operators (e.g. manually setting traffic to 0 at load balancer and ramping back up, manually increasing capacity), but it also talks about engineering the service in the first place.

This is definitely a familiar problem if you rely on caches for throughput (I think caches are most often introduced for latency, but eventually the service is rescaled to traffic and unintentionally needs the cache for throughput). You can e.g. pre-warm caches before accepting requests or load-shed. Load-shedding is really good and more general than pre-warming, so it's probably a great idea to deploy throughout the service anyway. You can also load-shed on the client, so servers don't even have to accept, shed, then close a bunch of connections.

The more general pattern to load-shedding is to make sure you handle a subset of the requests well instead of degrading all requests equally. E.g. processing incoming requests FIFO means that as queue sizes grow, all requests become slower. Using LIFO will allow some requests to be just as fast and the rest will timeout.

Re: Why Discord is switching from Go to Rust

#645
post #423

Earlier quoted context omitted.

You don't need microservices for that, though. One might as well have moved that piece into a library.

And then deal with cross-language FFI boundaries and cross-language builds.

RPC is pretty much also a "cross-language FFI boundary", except it can fail.

Of course it has some advantages, but it's hardly universally better.

Re: Why Discord is switching from Go to Rust

#646

Earlier quoted context omitted.

Really depends on the domain. There's some things that are a lot easier to make scale up in a language with a great concurrent gc, because that makes writing some lock free data structures quite fundamentally easier (no complicated memory reclamation logic, trivial to avoid ABA problems).

GC makes it easier to write, but not necessarily better. Modern state-of-the-art Java GCs operate a global heap, so you often pay for what you do not use. In languages like Rust or C++ your can build small locally GCed heaps, where you can limit GC overhead to just a few particular structures that need GC, not everything. Therefore other structures like caches don't affect GC pause times. And the "hardness" of writin…

“GC makes it easier to write.” I disagree. GC means I don’t get deterministic destruction which means I can’t use RAII properly.

Re: Why Discord is switching from Go to Rust

#647

Earlier quoted context omitted.

However the memory usage difference is astonishing for some of those benchmarks - using 1000x more memory is only acceptable for some situations.

Agreed, and ironically the most widely used Java platform (Android), despite its VM optimizations, is the one which would benefit the most from running only native code. I mean, those 1GB RAM 7 years old slow as molasses phones getting dust into drawers or being littered into landfills would scream if they didn't have to run everything behind a VM.

Make no mistake — Android isn't memory hungry because of Java alone. Android 4 used to comfortably fit in 1Gb of RAM, but Android 10 no longer can run on such devices. Both old and new versions use JVM, but newer Android has a lot of "helpful" system services, such as "Usage Statistics" service [1] and "Autofill Servide" [2].

Google's spyware is becoming more invasive and thus more memory-hungry.

1: https://developer.android.com/reference/android/app/usage/Us...

2: https://developer.android.com/reference/android/service/auto...

Re: Why Discord is switching from Go to Rust

#648
post #66

Earlier quoted context omitted.

Offtopic but what are you missing when you have to use tabs instead of spaces? I can understand different indentation preferences but I can change the indentation width per tab in my editor. And then everyone can read the code with the indentation they prefer, while the file stays the same.

I don't know about anyone else, but I like aligning certain things at half-indents (labels/cases half an indent back, so you can skim the silhouette of both the surrounding block and jump targets within it; braceless if/for bodies to emphasize their single-statement nature (that convention alone would have made "goto fail" blatantly obvious to human readers, though not helped the compiler); virtual blocks created by…

So you are the person that ruins it for everyone (are you emacs user by any chance?). Tabs are more versatile, you can even use proportional fonts with them. Projects end up using tabs because many people end up mixing them together (unknowingly or in your case knowingly using configuration that is unavailable in many IDEs).

BTW when you mix spaces with tabs you eliminate all benefits that tabs give (for example you no longer can dynamically change tab size without ruining formatting.

Re: Why Discord is switching from Go to Rust

#650
post #582

Earlier quoted context omitted.

Once you experience protocol buffers it becomes hard to go back.

How is a serde IDL relevant to microservices? XDR would do just as well, so would JSON.

Because protocol buffers are actually pleasant to use.
Post reply on HN