Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
nChauhan91 opened this issue Jun 26, 2024 · 7 comments
Labels

Comments

@nChauhan91
Copy link

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)

  • Start the machine manually.
  • Stop the machine manually.
  • Start the machine manually again.

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

@nChauhan91 nChauhan91 added the bug label Jun 26, 2024
@Andarist
Copy link
Member

Andarist commented Jun 26, 2024

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
Copy link
Author

nChauhan91 commented Jun 26, 2024

@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
Copy link
Member

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
Copy link
Author

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
Copy link
Member

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

@andrecrimb
Copy link

@Andarist maybe this is already explained somewhere, but is there a reason why the .getSnapshot().status after restarting the actor doesn't go back to active? If i try to log the .status after restarting is always stopped.

@Andarist
Copy link
Member

@andrecrimb currently actors are not exactly suited for reuse, so you shouldn't do smth like actorRef.start().stop().start(). If you need to rehydrate an actor I recommend this:

const snapshot = actorRef.getPersistedSnapshot()
actorRef.stop()
const newActorRef = createActor(machine, { snapshot })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants