4 ms·
That's really interesting. Care to share a link to 1 or 2 real world examples of this that you've seen? Or even better, examples of how one would write such lo
by ayewo 2y ago
That's really interesting. Care to share a link to 1 or 2 real world examples of this that you've seen?
Or even better, examples of how one would write such locks in JS that would be effective against these type of race conditions?
- mmis1000 2y agoHaving race condition in js is more about having questionable programming practice though. Instead of write result of operations into separate variables and aggregate them later. You write them into the same variable with unspecified order and prey they will work correctly. There won't be memory corruption or something. But the results you got won't be correct either. This type of problems is probably what rust try to address. (Rust will probably tell you to fxxk off because the write permission shouldn't be grant by two place at same time) But unfortunately there isn't rust for js. So only thing you can do is take care of it yourself.
- Yoric 2y agoConceptually, what happened was foo.a = a; foo.b = await b(); // while waiting for b's completion, something happens that changes the value of `a`, making `foo` invalid (or more complex variants of this) In a multi-threaded model, this would be classified as a race condition on `a`. That's why Rust has RefCell for r/w data sharing in single-threaded code. I don't remember the exact details, but I was hit by this many times when refactoring e.g. db access or file access in the (JS) code of Firefox. This can happen without async/await, without Promise and even without an event loop, you just need callbacks. But of course, having an event loop, Promise and async/await give you way more opportunities to hit such an issue.
- mike_hearn 2y agoAdvanced JS is a pain for that reason. Any interaction with a "slow" API, even doing cryptographic operations (super common inside libraries), can introduce points at which literally anything can change and in particular a point where new UI events can be triggered. So it's like concurrency but without any of the tools to manage it: you call a function, and by the time it returns arbitrary unrelated stuff may have executed. I've encountered quite a few programmers over the years who think the absence of tools like locking or concurrent data structures is a feature, that they don't need them because async is simpler. Wrong. They're not unneeded, they're just missing, like many other basic APIs you'd expect that are missing inside browsers. In standard GUI programming you're in control of the event loop and can decide whether to block it or not. This is a powerful tool for correctness. If you need to do a slow IO in response to a button being clicked you can just do it. The user may see the button freeze in the depressed state for a moment if their filesystem is being slow, for example, but they won't suffer data corruption or correctness issues, just a freeze. If you don't want the UI to freeze you can kick off a separate thread and then use mutexes or actor messaging to implement coordination, doing the extra work that surfaces the possible interactions and makes you work out what should happen. In the browser environment there's none of that. You have to find other ways to disable the event loop, like by disabling all the UI the user could interact with once an interation starts, or - more commonly - just ignore race conditions and let the app break if the user does something unexpected. It's partly for this reason that web apps always seem so fragile. And don't get me started on the situation w.r.t. database concurrency ... how many developers really understand DB locking and tx isolation levels?