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] An inline child actor cannot be persisted. #4410

Closed
zavx0z opened this issue Oct 28, 2023 · 9 comments
Closed

Bug[v5] An inline child actor cannot be persisted. #4410

zavx0z opened this issue Oct 28, 2023 · 9 comments

Comments

@zavx0z
Copy link

zavx0z commented Oct 28, 2023

Description

<script>
	import { createMachine, assign, createActor } from "xstate"

const rootMachine = createMachine({
  context: {
    atoms: {},
  },
  on: {
    "actor.put": {
      actions: assign(({ context, event, spawn }) => {
        const { atoms } = context
        atoms["atom"] = spawn(event.params.atom, event.params.options)
        return { ...context, atoms: { ...atoms } }
      }),
    },
  },
  initial: "idle",
  states: {
    idle: {},
  },
})

const actor = createActor(rootMachine, { systemId: "root-actor" })
actor.subscribe((state) => {
  console.log(actor.getPersistedState())
})
actor.start()

const childMachine = createMachine({
  initial: "idle",
  states: {
    idle: {},
  },
})

actor.send({ type: "actor.put", params: { atom: childMachine, options: { systemId: "child-id", id: "child" } } })

</script>
<h1>xstate</h1>

Expected result

  VITE v4.5.0  ready in 3801 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h to show help
{
  value: 'idle',
  status: 'active',
  error: undefined,
  historyValue: {},
  matches: [Function: bound matches],
  toStrings: [Function: bound toStrings],
  output: undefined,
  context: { atoms: {} },
  children: {}
}
Error: An inline child actor cannot be persisted.
    at Object.getPersistedState (/home/projects/sveltejs-kit-template-default-je7z77/node_modules/xstate/dist/raise-b69a3d16.development.cjs.js:1441:13)
    at StateMachine.getPersistedState (/home/projects/sveltejs-kit-template-default-je7z77/node_modules/xstate/dist/xstate.development.cjs.js:586:37)
    at Actor.getPersistedState (/home/projects/sveltejs-kit-template-default-je7z77/node_modules/xstate/dist/interpreter-ed3f81f7.development.cjs.js:756:23)
    at eval (/home/projects/sveltejs-kit-template-default-je7z77/src/routes/+page.svelte:29:21)
    at Actor.update (/home/projects/sveltejs-kit-template-default-je7z77/node_modules/xstate/dist/interpreter-ed3f81f7.development.cjs.js:486:24)
    at Actor._process (/home/projects/sveltejs-kit-template-default-je7z77/node_modules/xstate/dist/interpreter-ed3f81f7.development.cjs.js:606:10)
    at Mailbox.flush (/home/projects/sveltejs-kit-template-default-je7z77/node_modules/xstate/dist/interpreter-ed3f81f7.development.cjs.js:54:12)
    at Mailbox.enqueue (/home/projects/sveltejs-kit-template-default-je7z77/node_modules/xstate/dist/interpreter-ed3f81f7.development.cjs.js:46:12)
    at Actor._send (/home/projects/sveltejs-kit-template-default-je7z77/node_modules/xstate/dist/interpreter-ed3f81f7.development.cjs.js:703:18)
    at Object._relay (/home/projects/sveltejs-kit-template-default-je7z77/node_modules/xstate/dist/interpreter-ed3f81f7.development.cjs.js:180:14)

Actual result

{"value":"idle","status":"active","historyValue":{},"context":{"atoms":{"atom":{"xstate$$type":1,"id":"child"}}},"children":{"child":{"state":{"value":"idle","status":"active","historyValue":{},"context":{},"children":{}},"systemId":"child-id"}}}

Reproduction

https://stackblitz.com/edit/sveltejs-kit-xstate?file=src%2Froutes%2F%2Bpage.svelte

Additional context

ts without sveltekit worked
https://stackblitz.com/edit/xstate-ts?file=index.ts

@zavx0z zavx0z added the bug label Oct 28, 2023
@zavx0z zavx0z changed the title An inline child actor cannot be persisted. Bug[v5] An inline child actor cannot be persisted. Oct 28, 2023
@davidkpiano
Copy link
Member

This is working as expected; we currently cannot serialize arbitrary actor logic, nor do we plan to do this since it would require essentially serializing fully executable code. The machine needs to have the actor already defined (named src) to properly rehydrate it.

@Andarist
Copy link
Member

We might be able to improve the situation for the new spawn action (as in entry: spawn(inlineLogic)) but that's it. This one we can always try to "recover" from the same config position (if it stays there)

@zavx0z
Copy link
Author

zavx0z commented Oct 29, 2023

Why does the same code work in vanilla, but give an error in Sveltekit?
sveltekit
vanila ts

@zavx0z
Copy link
Author

zavx0z commented Oct 29, 2023

This is working as expected; we currently cannot serialize arbitrary actor logic, nor do we plan to do this since it would require essentially serializing fully executable code. The machine needs to have the actor already defined (named src) to properly rehydrate it.

If I have a generated actor, then I cannot get PersistedState?
Could you take a closer look at the code examples and the output?
It seems to me that there is still a mistake here.
Everything is very unclear.

Sorry for Google translator.

@davidkpiano
Copy link
Member

This is working as expected; we currently cannot serialize arbitrary actor logic, nor do we plan to do this since it would require essentially serializing fully executable code. The machine needs to have the actor already defined (named src) to properly rehydrate it.

If I have a generated actor, then I cannot get PersistedState? Could you take a closer look at the code examples and the output? It seems to me that there is still a mistake here. Everything is very unclear.

Sorry for Google translator.

No worries; in your code, you are passing an entire machine definition in the event. I would recommend another way of modeling it so that the machine knows about the other kinds of machines it can spawn already, instead of having that passed through an event.

@zavx0z
Copy link
Author

zavx0z commented Oct 29, 2023

No worries; in your code, you are passing an entire machine definition in the event. I would recommend another way of modeling it so that the machine knows about the other kinds of machines it can spawn already, instead of having that passed through an event.

Thanks for your reaction.
The modeling method you suggested does not suit me.
I am developing 3D, where an individual actor is created for each object. The parent state machine is mainly needed as a message passing system. How can I restore the states of dynamic objects? How to create a previously unknown number of actors?

@zavx0z
Copy link
Author

zavx0z commented Oct 29, 2023

is it possible to use actors without a parent actor in a single system?
How to share addresses between users if they are not on the same system?
If the actors can communicate directly, then I could write the logic of the system myself so that the actors can restore their state. It will also be possible to create a dynamic number of actors who can communicate with each other.
Please give me direction on where to go to fulfill my needs.

@burakakca
Copy link

Are there any changes in this regard?

@Andarist
Copy link
Member

Andarist commented Feb 9, 2024

What kind of an inline child actor you'd like to persist? Could you show how your machine looks like?

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

No branches or pull requests

4 participants