statelyai / xstate

Actor-based state management & orchestration for complex app logic.
https://stately.ai/docs
MIT License
26.5k stars 1.22k forks source link

Bug: [V5] Manually Stopping & then Restarting a Machine doesn't trigger it's entry action #4953

Open nChauhan91 opened 1 week ago

nChauhan91 commented 1 week ago

XState version

XState version 5

Description

In V4, I manually started and stopped the machine based on certain conditions, which worked correctly (see the provided CodeSandbox link below).

Problem: In V5, while the machine starts correctly for the first time, it fails to trigger the entry action when manually stopped and started again. The entry action in the initial state does not execute on the second attempt to start the machine.

Steps to Reproduce: (check output in console)

V4 Example: https://codesandbox.io/p/sandbox/xstate-v4-start-stop-l2xrs6 V5 Example: https://codesandbox.io/p/sandbox/xstate-v5-start-stop-t5xld6

Expected result

The machine should reset on stop() & The entry action in the initial state should trigger each time the machine is started.

Actual result

The entry action does not trigger on the second start.

Reproduction

https://codesandbox.io/p/sandbox/xstate-v5-start-stop-t5xld6

Additional context

No response

Andarist commented 1 week ago
createMachine({
    initial: "a",
    states: {
        a: {
            on: {
                FOO: "b"
            }
        },
        b: {
            entry: ({ event }) => {
                // event is gone after transition takes place
                // we can't call entry actions again on anothr start
                // what event they should be called with?
            }
        }
    },
})
nChauhan91 commented 1 week ago

@Andarist In my example I am running the event on entering the initial state itself, this works fine with v4, Is there a change between v4 & v5 in how machines handle the entry event? I couldn't find anything in the Documentation about this.

This is what I was doing with v4, should we change the approach while upgrading to v5?

createMachine({
    initial: "a",
    states: {
        a: {
            entry: 'doSomething'
        }
    },
})
Andarist commented 1 week ago

A restarted machine like this doesn't completely forget its previous snapshot. When u start again u don't start completely from scratch. If you want to start from scratch then it would be best to create a new instance of this actor.

nChauhan91 commented 1 week ago

Ok, so this is different from how interpret did it, it was also mentioned in the docs for it. https://xstate.js.org/docs/guides/interpretation.html#starting-and-stopping

Thanks, I will try to find a different approach but do you think this might be something that can be a possibility in the future as by stopping a machine you would expect it to destroy itself & then restart from scratch like interpret did.

davidkpiano commented 4 days ago

Ok, so this is different from how interpret did it, it was also mentioned in the docs for it. https://xstate.js.org/docs/guides/interpretation.html#starting-and-stopping

Thanks, I will try to find a different approach but do you think this might be something that can be a possibility in the future as by stopping a machine you would expect it to destroy itself & then restart from scratch like interpret did.

This would require persisting which effects (actions, invocations) were executed. This may be possible with the future "transition API" #4954