top | item 15701238

Fearless Concurrency in Firefox Quantum

611 points| ahomescu1 | 8 years ago |blog.rust-lang.org

174 comments

order

kibwen|8 years ago

I like this explanatory comment by Manishearth, a Servo dev, in the thread over on /r/rust:

"This blog post brought to you by the 'how many times can you say 'fearless concurrency' and keep a straight face' cabal.

"Seriously though, I now appreciate that term a lot more. One thing that cropped up in the review of this post was that I didn't have examples of bugs Rust prevented. Because I couldn't think of any concrete ones. Because Rust's safety doesn't work that way, it prevents your concurrency bugs before you realize you had them, by making sure you don't paint yourself into a corner. 'Fearless concurrency' really is the best way of putting this; the benefit was not that it prevented concrete bugs, but that it let us fearlessly and aggressively write code knowing that it would be concurrency bug free."

https://www.reddit.com/r/rust/comments/7cwpbq/fearless_concu...

ekidd|8 years ago

I've spent the last few days aggressively parallelizing some Rust code with crossbeam, and it's really just... painless (once you're used to Rust). Rust actually understands data races, and it grumbles at me until my code is provably safe, and then everything Just Works.

The Rayon library is also lovely for data parallelism.

Sometimes, I think, "Rust is basically a nicer C++ with the obvious foot guns removed and great tooling", but then there are those moments where I'm just blown away by what a good job it does.

(I think it helps that I have some functional programming experience under my belt, and that I tend to use mutability sparingly, and mostly in very simple ways.)

pimeys|8 years ago

I've built now several concurrent services with Rust. The language definitely gives confidence to try several things with different approaches to concurrency. None of my services crash (except once per 3-4 months when I deployed something "that will never crash" using `.unwrap()`). The crashes are always my own laziness, but if I follow the pattern of checking return values and unwraping only when the input is static and visible a few lines before, the resulting programs are fast, have a small footprint and basically never crash.

Oh and the tooling! I hope other projects take a serious example how cargo works. It's very hard to use any other build system.

vanderZwan|8 years ago

Quoting what I just replied in that thread:

> Given that this Servo code replaces an existing code base, couldn't we get a "guestimate" by looking at how many unsolved bug reports are now closed because their associated previous (presumably C++) code has been replaced? How many open bugs existed in Stylo's precursor that are removed now?

pornel|8 years ago

Rayon is pretty cool. It's about as powerful as OpenMP, and a bit easier to use.

The fearless concurrency really is ass-saving. For example, my most recent non-bug: I launched two parallel tasks where one would free a shared resource when done. In C that would be intermittent use-after-free. In Rust it was a compile-time error.

tareqak|8 years ago

Congratulations to the Mozilla and Rust teams!

Accounts like this one really help people who advocate investing in and building new tools to help against the heavy-handed application of phrases like "a bad workman always blames his tools" [0][1].

[0] https://en.wiktionary.org/wiki/a_bad_workman_always_blames_h...

[1] https://en.oxforddictionaries.com/definition/a_bad_workman_a...

Edit: formatting and typo

Analemma_|8 years ago

I hate that phrase and its reflexive usage so much. Yes, a bad workman blames his tools, but so does a good workman using lousy tools.

vatotemking|8 years ago

Firefox Quantum is blazing fast, and I finally ditched Chrome.

My only problem is that it drains my battery life fast. So whenever I'm not plugged I use Edge. Other than that, FF is amazing.

It is now my default browser and I even wrote a FF add-on a few days ago using their new API!

Zenbit_UX|8 years ago

As a front end Dev I'll never fully ditch Chrome as its Dev tools are vastly superior. I've tried the Firefox inspect menu and I'm just immediately turned off and confused..

However Firefox has been, and always will be my daily driver for all Web browsing. It's eco system is richer, noscript and the fact that it's not a Google product is a huge selling point.

dnate|8 years ago

Can someone confirm this? Like do a simple energy consumption comparison pre- and post-quantum?

margorczynski|8 years ago

From the article it seems Rust is really a great replacement for C++ and all it's complexity and quirks. I wonder how many other C++ projects are considering moving to it, anyone know about any major one like FF?

simias|8 years ago

I'm a former C++ dev who went all in on Rust. I think the main problem is that the learning curve works in Rust's disadvantage here.

If you start learning C++ it's relatively smooth sailing at first, especially if you're already familiar with C. Basic OOP, basic RAII, inheritance, virtual functions, basic templates. Easy peasy.

It's once you start getting to the advanced topics that the footguns become apparent. The sometimes intricate resolution rules (and how they compound with template substitution rules), the various subtleties surrounding copy constructors, const, mutable, concurrency and the way they play with each others, the various quirks inherited from C that sometimes don't play very well with modern constructs etc...

Rust is the other way around. There's a very steep curve right at the start where you need to understand how the borrow checker works and how to make it happy. You have to learn the right mindset right away. You need to get over that to reach the "fearless confidence" goodness.

I think that's going to be a big problem for experienced C++ coders to do the jump (especially if you need to convince multiple devs to make the jump at the same time).

It kind of reminds me of the switch from SVN to git. At first I didn't get it, git felt a lot more complicated and I didn't really see the benefit compared to good old SVN. Of course after a few years I'd curse under my breath every time I had to use SVN for some legacy codebase, it feels so clunky and limited now that I'm familiar with a proper git workflow.

sidlls|8 years ago

It's not moving, per se, but I've almost convinced my colleagues to use Rust for future projects to move our prototype and research grade machine learning pipeline implementations and data services to Rust. The alternatives were go and C++.

Rust is a clear winner over either in my view because of its traits system and immutable-by-default story. It feels like the kind of C++ I write, but with less boilerplate and typing. The safety story is irrelevant in our case (it's nice, but wasn't an explicit factor in the decision: the other features in Rust may have been developed to support safety, but safety need not exist to provide them). The biggest pain point is that it's not an appropriate language for high performance numerical computation, so we'll have some "glue" there. How that will work is yet to be determined, but the data engineering and infrastructure around the pipeline is definitely going to Rust.

throwaway613834|8 years ago

Could someone give a very simple, to-the-point example of a kind of concurrency bug that Rust prevents, for those of us who don't know Rust? (The author explicitly fails to think of any, so I'm hoping someone else can. It'd be more convincing to see one.)

EDIT: I meant a code example, not a paragraph. And I would obviously expect to see how the intended goal is achieved without the bug... otherwise it'd be trivial to prevent any bug (just make everything impossible).

maffydub|8 years ago

Borrowing from https://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.h... (linked to from the original post), the following code tries to access a lock-protected vector.

    fn use_lock(mutex: &Mutex<Vec<i32>>) {
        let vec = {
            // acquire the lock
            let mut guard = lock(mutex);
    
            // attempt to return a borrow of the data
            access(&mut guard)
    
            // guard is destroyed here, releasing the lock
        };
    
        // attempt to access the data outside of the lock.
        vec.push(3);
    }
It doesn't compile because the lock is not held long enough.

    error: `guard` does not live long enough
    access(&mut guard)
                ^~~~~
There are several more examples in that article, but you can read them there rather than here!

TheCycoONE|8 years ago

Sure, the obvious example is your classic thead1 i++, thead2 i-- bug. In C you run each thread a large number of times in parallel and you end up with something other than 0. The solution is to use atomic operations or locks.

Rust doesn't allow having two mutable references to the same memory location at the same time, so you would never encounter that.

seren|8 years ago

The most basic example would be two threads trying to write the same variable concurrently without synchronisation. As far as I know, as long as you don't use any unsafe code block, it is not possible, i.e. the compiler will protest loudly and the program won't compile.

You are forced by the compiler to implement an explicit exclusion mechanism.

The point is that kind of issue are silent bugs most of the time(up to point) in C, C++. It can work in most cases, and one day, something goes awfully wrong because the thread scheduling is slightly different than usual.

majewsky|8 years ago

Many (most?) of the non-deterministic bugs in concurrent programs arise from two threads trying to write to the same place in the same time, or one thread writing to one place while the other thread just read that place and assumed that it was going to be constant for the moment.

Rust prevents that by having the concepts of "ownership" and "borrowing" built into the language. The Rust book probably explains this better than I ever could, but the basic idea is that you can only have one actor writing to a variable, OR any number of actors reading a variable. But you cannot have multiple actors having write access the same variable at the same time, or one actor writing to it while anyone has read access to it, unless you use some sort of serialization or copy-on-write mechanism.

ape4|8 years ago

The new Firefox is actually faster.

MaxBarraclough|8 years ago

My only complaint is the marketing.

Firefox isn't slow, sure enough. But it wasn't slow last week either. I've been using it as my primary browser for a long time, and performance was never an issue.

Also, 'Quantum'? Come on now. If they're aiming Firefox at power-users (which they should be), they should know that kind of buzzword abuse is only going to annoy.

howard941|8 years ago

It was, but lacking NoScript support triggered a speedy manual downgrade to 56.0.2

_bax|8 years ago

YEP really!

faragon|8 years ago

Any side effects on web applications? E.g. event handling race conditions or different behavior?

jsf666|8 years ago

> It replaces approximately 160,000 lines of C++ with 85,000 lines of Rust

Wow! This is great, especially considering how bad and complex (in the bad sense) C++ is. Maybe Rust and Go will finally make the Frankenstein go to sleep

zellyn|8 years ago

Is this reduction in line count typical? I'm surprised. Or is this discounting parts of the code that have been moved out into separate crates?

mangatmodi|8 years ago

Is it a concern that acid3 test as terribly faild? - http://acid3.acidtests.org/

24gttghh|8 years ago

I'm sorry? I just scored a 97/100 using FF v57.0 x64. That's decent right? The newest version of Chrome fails likewise.

Also this:

>Acid3, in particular, contains some controversial tests and no longer reflects the consensus of the Web standards it purports to test, especially when it comes to issues affecting mobile browsers. The tests remain available for historical purposes and for use by browser vendors. It would be inappropriate, however, to use them as part of a certification process, especially for mobile browsers.[0]

[0]http://www.acidtests.org/

mangatmodi|8 years ago

So basically it has something to do with my system. It scored only 93, with really dirty rendering. I need to check what's wrong

bpicolo|8 years ago

Both firefox dev edition and chrome (mac) score 97 for me.

wahern|8 years ago

tazjin|8 years ago

I clicked a few of those links and they were mostly instances of the word "race" appearing as part of, for example, "Traceable".

Somewhere on the second page I found a brief mention of a data race in rustc itself (that was fixed).

Looks pretty fearless to me!

Argorak|8 years ago

Rust only saves you from simple races, not more complex ones. That's quite a lot already.

Most importantly, though, it preserves _memory safety_ in concurrent situations, so your stuff won't randomly crash, but properly panic.

It's no silver bullet, but it _is_ the "magic sauce" behind Stylo.

ric2b|8 years ago

Try opening some of those and ctrl+f to realize what was actually matched. Hint: not "thread race"