Effect CommunityEC
Effect Community16mo ago
14 replies
dillania

Stream.flatMap with `switch: true` - can it ignore "previous" streams?

Once the stream has switched to the latest value of the counter, I would expect the output to be "tick 2" from that point on:
tick 2
tick 2
tick 2...


But I'm seeing:
tick 0
tick 1
tick 2
tick 0
tick 1
tick 2...


import { Console, Effect, Ref, Stream, SubscriptionRef } from "effect";

const effect = Effect.gen(function* () {
  const counter = yield* SubscriptionRef.make<number>(0);
  const tickStream = counter.changes.pipe(
    Stream.flatMap(
      (count) => {
        return Stream.tick("300 millis").pipe(Stream.map(() => count.toString()));
      },
      {
        switch: true,
        concurrency: "unbounded",
      }
    )
  );

  yield* Effect.forkDaemon(
    Stream.runForEach(tickStream, (value) => Console.log("tick", value))
  );

  yield* Effect.sleep(100);
  yield* Ref.set(counter, 1);
  yield* Effect.sleep(100);
  yield* Ref.set(counter, 2);
  yield* Effect.sleep(1000000);
});

Effect.runPromise(effect);


I thought with switch: true, the flatMap would stop listening to the previous streams. I came to this conclusion based on other discussions in this Discord server.

How can I achieve the switching behavior that I want? Thank you for your consideration.
Was this page helpful?