22 ms·
Fearless Concurrency in Firefox Quantum
- wahern 9y agoFearless, indeed: https://github.com/servo/servo/issues?page=1&q=thread+race https://github.com/servo/servo/issues?page=1&q=thread+race
- Argorak 9y agoRust 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.
- qznc 9y agoMore precisely, Rust saves you from data races but not race conditions. https://blog.regehr.org/archives/490 https://blog.regehr.org/archives/490
- deckarep 9y agoI’m pretty sure Rust saves you from ALL data races so long as you stay within the boundaries of safe code. Do you have anything at all to reference otherwise that says only certain data races are detected while others are not? To my knowledge you can defeat the compile-time data race detection if you are either doing unsafe or certain scenarios with Cell/RefCell but even in that case you are guaranteed runtime detection rather than compile time detection. These feature alone is worth its weight in gold.
- Argorak 9y agoqznc puts that better then I do. It saves you from data races, but not from race conditions. Cell and RefCell are both not Sync (that means they can't be used from multiple threads) for a reason. RefCell does, however, allow borrow checking at runtime, for wrapping it with something that establishes Sync.
- s17n 9y agoGiven the a "data race" is essentially defined to be the class of races that Rust's type system guards again, yeah it saves you from all of them.
- kibwen 9y agoRust's definition of "data race" isn't just "what the Rust compiler rejects", it has a specific meaning: "Safe Rust guarantees an absence of data races, which are defined as: 1. two or more threads concurrently accessing a location of memory, 2. one of them is a write, 3. one of them is unsynchronized." https://doc.rust-lang.org/nomicon/races.html https://doc.rust-lang.org/nomicon/races.html
- wahern 9y agoHere's a potential use-after-free, listed in my query: https://github.com/servo/servo/issues/14014 Of course it's using unsafe code and doing other crazy stuff--a lot of these issues are related to shared, mutable, tree structures. But that's precisely my point. When you're implementing something as sophisticated as Servo and trying to keep things performant and multi-threaded, concurrency is hardly fearless. Servo does this and they have bugs. Indeed, being "fearless" is precisely how you end up with these bugs, in Rust or any other language. If you're fearless you're more apt to move from a big lock to a fine-grained locking mechanism. That's error prone, including in Rust. It's like that dude in Florida whose Tesla flew under the tractor trailer. He was fearless in the same way inexperienced engineers using Rust will be when they hear "fearless concurrency". They'll push the envelope when they have no need to, because that's what inexperienced engineers do who haven't been burned, especially when they think their tools make them fire-proof.
- tazjin 9y agoI 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!
- wahern 9y agoAfter some digging I found that the issue is that whenever src is set and then contentDocument is called right after, there is a race condition and contentDocument will return null because the Document hasn't been created in the script thread yet. -- https://github.com/servo/servo/pull/14764 I decided not to cherry pick because I figured people could look through themselves and decide. And because culprits are not always found (or at least documented) before a fix is committed. This is how thread races work in any language--they're hard to definitively pin down, not to mention reliably reproduce, but generally easy to fix (or at least make disappear) once something suspicious comes to your attention. Concurrency is easy when you don't share mutable data. But when you do have to share mutable data--core, performance-sensitive shared data structures--Rust hardly makes doing so "fearless". What Rust does is make it difficult to _accidentally_ share mutable data.
- ric2b 9y agoTry opening some of those and ctrl+f to realize what was actually matched. Hint: not "thread race"
- wahern 9y agoSome are, some aren't. It's difficult to pick them out because some aren't resolved, and some that are resolved were fixed with "works for me" without nailing down the culprit. I just take issue with "fearless concurrency". All concurrency is fearless if you use a share-nothing architecture. But often times for performance you can't do that. And while Rust may be better than most languages about making it more difficult to screw up, even the Servo folks create race conditions.
- jsf666 9y 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 9y agoIs 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?
- Rusky 9y agoThere's some good discussion of how it happened here: https://www.reddit.com/r/rust/comments/7cwpbq/fearless_concurrency_in_firefox_quantum/dpt9gq0/ https://www.reddit.com/r/rust/comments/7cwpbq/fearless_concu... One of the biggest contributors is "custom derive," which cuts out a lot of boilerplate. Another is that Gecko C++ is also pretty old and so doesn't rely on a lot of what is now standard. It's also just a ground-up rewrite, which has the advantage of hindsight. It's not a trick of moving code around.
- zellyn 9y agoOh, thanks. Perfect link. It makes sense that rewrites are smaller, but the reduction factor was still surprising.
- kibwen 9y agoI 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_concurrency_in_firefox_quantum/ https://www.reddit.com/r/rust/comments/7cwpbq/fearless_concu...
- pimeys 9y agoI'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.
- rkangel 9y agoNote that the panic you get by calling unwrap() where you shouldn't isn't a crash. It's a controlled program exit due to an unexpected condition. While yes, the panic will cause your program to stop, it will do it in a clean deterministic way (with a backtrace). Actual crashes (due to segfaults) can happen a long way from the bug that actually caused the issue, can happen intermittently and generally be a nightmare to debug.
- pimeys 9y ago
- pornel 9y agoRayon 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.
- ape4 9y agoThe new Firefox is actually faster.
- _bax 9y agoYEP really!
- MaxBarraclough 9y agoMy 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.
- s_kilk 9y agoFirefox was, up until today, noticeably slower than Chrome. Today it's faster.
- Cyph0n 9y agoEspecially on Mac. In my experience, FF on Windows was pretty snappy. Quantum is on a whole other level though.
- Santosh83 9y agoAgree about marketing. Mozilla needs to get the word out to those who don't follow the tech scene in any way, shape or form. That's the real challenge, but there also lie the bulk of its potential user base. Not sure exactly how they can do that without resorting to annoying, almost sleazy stuff that Google do (like bundling their browser with many other s/w and OEM system builders)... Quantum... I like to think of 57 and beyond as a quantum leap from before. They did after all let go of XUL overnight, and people do praise its speed overnight. :-)
- Crespyl 9y ago
- margorczynski 9y agoFrom 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 9y agoI'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.
- adrianN 9y agoAlready basic C contains more than enough footguns. If you think basic C++ is relatively free of footguns you're kidding yourself. Rust has a steep learning curve because the compiler nags you a lot about things that would have been a potential footgun in C. Unfortunately it is not smart enough to see in all cases that your code wouldn't have triggered that particular footgun and has to be overly conservative.
- throwaway613834 9y agoCould 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).
- seren 9y agoThe 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.
- arielb1 9y agoFor example, accidentally sharing a lock-less cache or a non-atomic reference counted pointer between threads. For example this code, which tries to send a reference-counted pointer between threads, which can cause the reference counter to become unsynchronized and random use-after-free: use std::thread; use std::rc::Rc; fn main() { let rcs = Rc::new("Hello, World!".to_string()); let thread_rcs = rcs.clone(); thread::spawn(move || { println!("{}", thread_rcs); }); } Is detected by the compiler and causes this error error[E0277]: the trait bound `std::rc::Rc<std::string::String>: std::marker::Send` is not satisfied in `[closure@src/main.rs:8:19: 10:6 thread_rcs:std::rc::Rc<std::string::String>]` --> src/main.rs:8:5 | 8 | thread::spawn(move || { | ^^^^^^^^^^^^^ `std::rc::Rc<std::string::String>` cannot be sent between threads safely | = help: within `[closure@src/main.rs:8:19: 10:6 thread_rcs:std::rc::Rc<std::string::String>]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::string::String>` = note: required because it appears within the type `[closure@src/main.rs:8:19: 10:6 thread_rcs:std::rc::Rc<std::string::String>]` = note: required by `std::thread::spawn`
- vatotemking 9y agoFirefox 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!
- dnate 9y agoCan someone confirm this? Like do a simple energy consumption comparison pre- and post-quantum?
- Zenbit_UX 9y agoOn what OS? It will vary for sure.
- Zenbit_UX 9y agoAs 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.
- nwah1 9y agoFrom a feature standpoint, I can't think of anything that Firefox devtools are lacking. This seems like a gripe about the UI, and my feeling is precisely the opposite of yours, but equally subjective.
- deleted 9y ago[deleted]
- benjvmin 9y agoJust testing out FF devtools, I do appreciate how similar they are to Chrome. The biggest differences seem to be geared towards PWAs, such as auditing w/ Lighthouse.
- tareqak 9y agoCongratulations 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_his_tools https://en.wiktionary.org/wiki/a_bad_workman_always_blames_h... [1] https://en.oxforddictionaries.com/definition/a_bad_workman_always_blames_his_tools https://en.oxforddictionaries.com/definition/a_bad_workman_a... Edit: formatting and typo
- Analemma_ 9y agoI 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.
- chowells 9y agoYou can respond with "that's because a good workman doesn't use poor tools." It nicely suggests that maybe it's the programmer's responsibility to advocate for something better.
- nitrogen 9y agoWhen I was a kid I used to pride myself on how many things I could take apart and reassemble with just a butter knife. But that was only because I didn't have access to real screwdrivers. Likewise with software, each improved tool I learn (or new but worse tool I learn to avoid) makes me appreciate how much time I could have been wasting by using inferior tools/practices/languages.
- Manishearth 9y agoSee also: https://www.schneems.com/2016/08/16/sharp-tools.html https://www.schneems.com/2016/08/16/sharp-tools.html
- mangatmodi 9y agoIs it a concern that acid3 test as terribly faild? - http://acid3.acidtests.org/ http://acid3.acidtests.org/
- 24gttghh 9y agoI'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/ http://www.acidtests.org/
- bpicolo 9y agoBoth firefox dev edition and chrome (mac) score 97 for me.
- mangatmodi 9y agoSo basically it has something to do with my system. It scored only 93, with really dirty rendering. I need to check what's wrong
- nobodyorother 9y agoMy kingdom for Tab Groups! https://addons.mozilla.org/en-US/firefox/addon/tab-groups-panorama/ https://addons.mozilla.org/en-US/firefox/addon/tab-groups-pa...
- faragon 9y agoAny side effects on web applications? E.g. event handling race conditions or different behavior?