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

Make updated context available to invokes #4351

Merged
merged 5 commits into from
Oct 13, 2023
Merged

Conversation

Andarist
Copy link
Member

No description provided.

@Andarist Andarist requested a review from davidkpiano October 12, 2023 15:58
@changeset-bot
Copy link

changeset-bot bot commented Oct 12, 2023

🦋 Changeset detected

Latest commit: 35ab007

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
xstate Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codesandbox-ci
Copy link

codesandbox-ci bot commented Oct 12, 2023

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 35ab007:

Sandbox Source
XState Example Template Configuration
XState React Template Configuration

@@ -63,10 +63,10 @@ export function fromCallback<TEvent extends EventObject, TInput = unknown>(
const logic: CallbackActorLogic<TEvent, TInput> = {
config: invokeCallback,
start: (_state, { self, system }) => {
system._relay(self, self, { type: XSTATE_INIT });
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was super confusing because XSTATE_INIT is a special event and yet this "custom" logic was sending the same type to itself manually

@@ -1191,9 +1213,9 @@ function enterStates(
stateNodeToEnter.output
? resolveOutput(
stateNodeToEnter.output,
currentState.context,
nextState.context, // TODO: this was likely buggy, write a test case that proved it
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: I need to look into this before landing this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, this was buggy - I'm gonna add a test case for this in a sec: https://stackblitz.com/edit/typescript-yg1pad?file=index.ts

@@ -424,11 +415,14 @@ describe('predictableExec', () => {
entry: sendTo('myChild', { type: 'KNOCK_KNOCK' }),
invoke: {
id: 'myChild',
src: fromCallback(({ receive }) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, a callback actor couldn't be used here for this test case because the event sent from an entry action to an invoked actor is being received by it before a callback actor has a chance to setup listeners.

It's a timing issue that we should fix but that's outside of the scope of this PR.

Comment on lines -276 to -278
entry: assign(({ system }) => {
expect(system!.get('test')).toBeDefined();
})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, this is an ability that we'd "lose" if we gonna land this PR. I think it's fine though because this:

invoke: { src: logic, id: 'myId' },
entry: sendTo('myId', event)

is way more useful and probable than:

invoke: { src: logic, systemId: 'mySystemId' },
entry: sendTo(({ system }) => system.get('mySystemId'), event)

Note that this whole problem is only relevant when an entry action tries to grab the actor that is just about to be invoked by the very same state from the system. As showcased by the test adjustment - the actor becomes available in the system right after entry+invoke on a single state are resolved

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that makes sense

Copy link
Member

@davidkpiano davidkpiano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused about the retries part - what's happening there?

@Andarist
Copy link
Member Author

I'm a bit confused about the retries part - what's happening there?

Entry actions are executed first (before invokes) so sendTo('foo', ...) might try to target a yet-not-available invoked actor that is meant to be created by the same "action block". When resolving entry blocks, I set aside all actions that have .retryResolve on them (so basically just send actions) and I attempt to call those retries at the end of the block. At that time, the invoked actors are already available so I have a chance to mutate the already created action params. This wouldn't work for just any action type though - it specifically works for sends because their execution is wrapped with defer.

@Andarist Andarist merged commit 6f18183 into next Oct 13, 2023
1 check passed
@Andarist Andarist deleted the fix/invoke-vs-context branch October 13, 2023 18:16
audionerd pushed a commit to audionerd/xstate that referenced this pull request Oct 19, 2023
* Call actions while executing algorithm and not at the end of it

* Make updated context available to invokes

* add a test case for delayed events

* add a test case for done.state output

* add changeset
audionerd pushed a commit to audionerd/xstate that referenced this pull request Oct 19, 2023
* Call actions while executing algorithm and not at the end of it

* Make updated context available to invokes

* add a test case for delayed events

* add a test case for done.state output

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

Successfully merging this pull request may close these issues.

2 participants