Proposal: improve state management in the player
See original GitHub issueAfter building the first(< 0.8) and the second(0.8.x) version of rrweb’s replayer, I found we need to improve the state management in the replayer for two goals:
- Keep states and actions explicit. It should be straight forward to know the state of the replayer and the valid actions it can do.
- Keep public APIs intuitive, simple, and easy to use. Users should not see unexpected behaviors after calling the APIs.
In the old version, the replayer did not do a good job on the first point. We are using multiple boolean flags to describe the states which make these codes:
if A && B
-> playing
else if C1 && !C2 && D
-> skipping
...
And these states are hard to be re-used in the rrweb-player, which is a UI for the replayer. Then I introduce the state machine to solve the first problem, which is good at strictly handling states. But the refactoring ruined the second point. Users lost in the new APIs and facing many regressions. The main problem here is I’m exposing the state machine to the public APIs which means users should be aware of the states and handle it.
So in this proposal, I suggest refining the state machine and improve the public APIs to achieve both goals.
Refining the state machine
We will have two simple state machines instead of a complex one, and remove some context from the machine.
First, we will have a simple state machine with paused
, playing
, and live
states.
The transitions look like this:
The live
state looks not quite useful at this moment, but I believe it was needed for future development.
Then we will have another state machine with normal
and skipping
states.
The transitions look like this:
This machine responsible for calculating the fast-forward speed and restore to previous normal speed.
Improve the public APIs
Since we are not going to expose the state machine concepts to the users, we still provide APIs look similar to the actions but easier to use.
play
Play accepts an optional time offset number as the params. In the implementation, it will do the following things:
- if the replayer is paused, send the PLAY event to the machine
- if the replayer is playing, send PAUSE and PLAY event to the machine in a sequence.
- if the replayer is skipping, send the BACK_TO_NORMAL event to the machine. We will depart the resume API.
pause
Pause now accept an optional time offset number too. In the implementation, it will do the following things:
- if no time offset number is passed in, and the replayer is playing, send the PAUSE event to the machine
- if time offset number is passed in, call the play API with the time offset number, then call PAUSE to stop at that time offset.
startLive
Currently, it will only send the TO_LIVE event when the replayer is paused.
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (9 by maintainers)
Top GitHub Comments
Invite @eoghanmurray @Juice10 to review this.
Thanks @Yuyz0112 I appreciate your creation of this separate proposal and explanation as to the introduction of the state machine.
My personal approach would be different. I believe it is possible to design software such that there is no such thing as an ‘invalid’ action… applying any action to the software should not result in an error state, along the lines of the https://en.wikipedia.org/wiki/Robustness_principle.
From that point of view, the sets of booleans that were tracking state were just fine, but I’m not aware of the problems they were causing so maybe things are over simplified in my head. E.g. you could have:
I’m happy to see that the problems I’ve raised look set to be addressed with the new simplified state machines.