Skip to content

[RED-13] [ListenerMiddleware][Breaking] - Improve listernerApi.fork scheduling logic #2280

Open
@FaberVitale

Description

@FaberVitale

Description

Current implementation of listernerApi.fork has an implicit contract:

1. The output forked task is scheduled **synchronously** in a microtask.
2. The output forked task will **always** run if it is not cancelled **synchronously**.

The second clause can be problematic in certain situations because It is possible to cancel a forked task that we're going to execute anyway:


Examples

1. using process.nextTick

listenerMiddleware.startListening({
  actionCreator: increment,
  async effect(action, listenerApi) {
    const task = listenerApi.fork(async (forkApi) => { console.log(2); })

    globalThis?.process?.nextTick(() => { task.cancel(); console.log(1); })  // nextTick (node only) runs before the microtask queue
  },
})

2. using task.cancel in a scheduled microtask

listenerMiddleware.startListening({
  actionCreator: increment,
  async effect(action, listenerApi) {
   let task: ForkedTask<void>;
   
   globalThis?.queueMicrotask(() => { task?.cancel(); console.log(1); }) 

   task = listenerApi.fork(async (forkApi) => { console.log(2); })
  },
})

While these examples might seem contrived, we do not generally use node-only primitives in universal code, it highlights an issue with the current implementation that might cause problems if the user does not use forkApi.signal or the other forkApi methods.


Suggested changes

Change the listernerApi.fork contract to:

1. The output forked task is scheduled **synchronously** in a microtask.
- 2. The output forked task will **always** run if it is not cancelled **synchronously**.
+ 2. The output forked task will **always** run if it is not cancelled before the scheduled execution.

RED-13

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions