Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can Redux guarantee no race condition?

I've recently learned about Redux.
I well understood the concept but I don't figure out this line in the official documentation:

Because all changes are centralized and happen one by one in a strict order, there are no subtle race conditions to watch out for.

How can Redux guarantee no subtle race conditions?

Indeed, I can imagine this scenario (in order):

  1. Some component dispatches ACTION_TYPE_1.
  2. Some component dispatches ACTION_TYPE_2.
  3. ACTION_CREATOR_1 makes an ajax call to grab some data.
  4. ACTION_CREATOR_2 makes an ajax call to grab some data.
  5. ACTION_CREATOR_2 treats grabbed data before ACTION_CREATOR_1 does.
  6. Possible weird behavior due to this race condition?

So actions creators dispatching would be applied in order, but implementations of those actions creators might not apply in order, possibly leading to non-deterministic code.

How to figure out the quote?

I can understand that with Redux, there's a kind of trace about dispatched actions' history (helping to understand the program workflow at runtime), but what about the real implementations of those actions?

like image 468
Mik378 Avatar asked Dec 11 '16 00:12

Mik378


2 Answers

I've just came across this point, very meaningful, by @DanAbramov himself.

I think it well answers to my OP.

The point is that as long as dispatching of actions remains synchronous (despite that actions creators internal process might not be synchronous at all), it's easy to figure out quickly about a race condition (or other issues regarding non-determinism) by establishing and logging an history of dispatched actions.
Especially it's easy to reproduce the "weird" state to then figure out how to avoid it (like Event-Sourcing).

Without any synchronous and visible point in time, it would be very hard to master what happened; that's why Redux brings a benefit.

Redux does not avoid race conditions, but does reduce drastically subtle (hard to analyse) race conditions, as documentation states.

like image 147
Mik378 Avatar answered Oct 04 '22 04:10

Mik378


  1. Javascript is thread safe so 2 functions cannot run at the same time.

  2. Redux does not know about asynchronous operations, it only cares about the current state, events that are dispatched to it and how to transition current state to some other state given an event.

  3. Thus ensuring action dispatching order is your responsibility, it's not a responsibility of Redux.

  4. If there are two events, X and Y, and you want to prevent handling Y before X is handled, then you can trace it in your Redux state using some state properties. Thus you can easiliy prevent handling Y before X is handled.

  5. There are too many different requirements for asynchronous operations and error handling people may wish to apply. Thus it is difficult to provide a general solution for "race conditions" you are talking about.

  6. Design your system, find all edge cases, and create a new event/event name/event handling for each edge case you can have. Then handle them in your redux reducer, make proper state transitions. In Web applications, nothing is a deadly error (it's not a good UI/UX to ask users to refresh their browsers) so you must recover from every possible edge case, thus throwing errors don't make much sense.

like image 22
mostruash Avatar answered Oct 04 '22 04:10

mostruash