Feature Request: Virtual time scheduler
dilame opened this issue · comments
What is the problem this feature would solve?
In RxJS, I often use the VirtualTimeScheduler to test algorithms on historical data by simulating real-time data streams. This feature allows for a seamless transition between real-time and historical data testing without changing the core logic of the application.
I noticed that effect
currently lacks a similar functionality in its Scheduler
concept. The ability to virtualize time would be extremely beneficial for developers like me who need to test their reactive systems more thoroughly by controlling the flow of time in tests.
What is the feature you are proposing to solve the problem?
I would like to request the addition of a VirtualTimeScheduler
in effect. This scheduler would ideally allow:
- Simulating the passage of time, enabling deterministic and controlled testing environments.
- Testing time-sensitive operations without real delays, thus speeding up the test suite.
- Flexibility to interoperate with existing Scheduler functionalities for seamless integration.
Are you maybe looking for our TestClock
? https://github.com/Effect-TS/effect/blob/main/packages/effect/src/TestClock.ts
This also comes as part of our TestContext
(https://github.com/Effect-TS/effect/blob/661004f4bf5f8b25f5a0678c21a3a822188ce461/packages/effect/src/TestContext.ts) which is also utilized by our @effect/vitest
package.
Closing this for now. Feel free to re-open if this didn't answer your question!
It is almost the same, but actually, not:) RxJS VirtualTimeScheduler automatically tracks the time, while Effect TestClock requires user to manually adjust
time.
VirtualTimeScheduler
doesn't even have any methods to manually set time. The only method it offers is VirtualTimeScheduler.flush()
which execute all of its queued actions
and takes care of adjusting time. It is crucial when you have multiple parallel processes, each with different delays, and each of them wants to know the current time at different points of executions.
Something like this. I know, it looks non realistic, but it's just a simple simulation of real world scenarios
const waitRandomTimeAndPrintCurrentTime = Effect.gen(function *(){
const randomSleepTime = yield* Random.nextIntBetween(1000,5000);
yield* Effect.sleep(randomSleepTime);
const currentTime = yield* Clock.currentTimeMillis;
yield* Console.log(currentTime);
})
const test = Effect.gen(function* () {
yield* Effect.forkDaemon(waitRandomTimeAndPrintCurrentTime)
yield* Effect.forkDaemon(waitRandomTimeAndPrintCurrentTime)
})
I would like to have something like TestClock.flush
that will execute all the actions that are waiting for execution. Something like tick in event loop, but for fibers.