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

disptach updated #1872

Closed

Conversation

Siddharth1605
Copy link

Pull Request

📖 Description

• Identified the code responsible for queuing and executing dispatch requests
• Reproduced the issue by building a page that dispatches multiple actions
• Implemented a fix to ensure that all dispatch requests set the new value
• Tested the fix by reproducing the issue and verifying that all dispatch requests are published to subscribers

This change ensures that the recursive call is properly handled for both synchronous and asynchronous cases, and it also accounts for the case when there are no more queued dispatches.

🎫 Issues

#1871

@bigopon
Copy link
Member

bigopon commented Jan 11, 2024

Thanks @Siddharth1605 can you add tests for this PR?

@Siddharth1605
Copy link
Author

Thanks @Siddharth1605 can you add tests for this PR?

Here https://docs.aurelia.io/community-contribution/building-and-testing-aurelia there are 4 kinds of test to be done, as I'm a newbie to this community, can you say what test I need to do?

@bigopon
Copy link
Member

bigopon commented Jan 11, 2024

Thanks @Siddharth1605 can you add tests for this PR?

Here https://docs.aurelia.io/community-contribution/building-and-testing-aurelia there are 4 kinds of test to be done, as I'm a newbie to this community, can you say what test I need to do?

Right thanks for pointing that out and sorry for the confusion. There should be existing tests in a file state.spec.ts you only need to follow it to create new tests.
After that ill have a closer look at the issue and proceed with this PR/discussion.

@@ -81,6 +81,9 @@ export class Store<T extends object, TAction = unknown> implements IStore<T> {
} else {

Choose a reason for hiding this comment

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

I would also set the state on line 80 (instead of just calling afterDispatch($), i would previously call set_state

Copy link
Member

Choose a reason for hiding this comment

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

the job of afterDispatch is to run the state through the whole action queue to get the final state.
Setting state should only happen after the whole action queue has been exhausted.

@@ -81,6 +81,9 @@ export class Store<T extends object, TAction = unknown> implements IStore<T> {
} else {
return afterDispatch(newState);
}
}else {
// Ensure that in case of no queued dispatches, the result is returned
return $state instanceof Promise ? $state.then(() => {}) : undefined;
}
};
const newState = reduce(this._state, action);

Choose a reason for hiding this comment

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

I also noticed that line 94 is incorrect. this._dispatching--; If I understand the code correctly, this._dispatching--; should only be called after the whole afterDispatch returns. this._dispatching--; seems to work like a lock to ensure only one dispatch is happening and all the other requests are chained since the afterDispatch consumes the next item from the queue.

Copy link
Member

Choose a reason for hiding this comment

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

I think you are right. The lines 89 - 97 currently looks like this

      return newState.then($state => {
        this._setState($state);
        this._dispatching--;

        return afterDispatch(this._state);
      }, ex => {
        this._dispatching--;
        throw ex;
      });

It seems to have 2 problems:

  • calling setState too early, if there's more state changes in afterDispatch (this includes the wrong this._dispatching--)
  • calling setState only once, it'll miss all the other changes in afterDispatch.

I think it should be changed to something like this:

      return newState.then($state => {

        return afterDispatch(this._state);
      }, ex => {
        this._dispatching--;
        throw ex;
      }).then(state => {
        this._setState(state);
        this._dispatching--;
      });

If you agree with this @gtroxler @Siddharth1605 , can you help with the tests for these changes?

Copy link
Member

Choose a reason for hiding this comment

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

On a 2nd thought, maybe we should set state after every action so that it'll be easier & more correct to implement.

Choose a reason for hiding this comment

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

Yes that makes sense

@Siddharth1605 Siddharth1605 closed this by deleting the head repository May 14, 2024
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.

None yet

3 participants