The scalability in question here is more about scaling the code base than scaling in terms of software performance. Data in streaming systems is easily monitored, because each store is registered for each action, and actions determine each application event that can occur in the system. Each store can determine how it should be updated in response to each action, without the need for a programmer to determine which stores are connected to which actions, and in most cases you can change or read the code for the store without worrying about how it affects to any other store.
At some point, the programmer will need to register the store. The store is very specific to the data that it will receive from the event. How to accurately search for data inside the store is better than registering for a particular event, and does the store always expect the data that it needs / cares for?
Actions in the system are things that can happen in the system, as well as relevant data for this event. For instance:
- The user is logged in; comes with user profile
- User added a comment; comes with comment data, identifier of the item that was added to
- The user updated the message; comes with message data
So you can think of actions as a database that stores can know about. Every time an action is sent, it is sent to each store. Thus, at any point in time you only need to think about your data mutations in one storage + action at a time.
For example, when a message is updated, you may have a PostStore that monitors the POST_UPDATED action, and when it sees it, it will update its internal state to save the new message. This is completely separate from any other store that can also take care of the POST_UPDATED event - any other programmer from any other team working on the application can make this decision separately, with the knowledge that they can connect to any action in the action database, which may take place.
Another reason it is useful and scalable in terms of the code base is the inverse of control; each store decides what actions it cares and how to respond to each action; all data logic is centralized in this repository. This contrasts with a pattern such as MVC, where the controller is explicitly configured to call mutation methods on models, and one or more other controllers can also call mutation methods on the same models at the same time (or at different times); The logic for updating data is spread across the system, and understanding the data flow requires understanding every place that a model can update.
Finally, another thing to keep in mind is that registration or not registration is a kind of semantics question; trivially ignore the fact that the store receives all the actions. For example, in Fluxxor in stores, there is a method called bindActions that associates specific actions with specific callbacks:
this.bindActions( "FIRST_ACTION_TYPE", this.handleFirstActionType, "OTHER_ACTION_TYPE", this.handleOtherActionType );
Despite the fact that the store receives all the actions, under the hood it searches for the type of action in the internal map and calls the corresponding callback in the store.