Understanding Retry and Timeout in Effect Typescript

Could someone please help me better understand retry/timeout? I have a simple program that's supposed to execute a request. But I want to be able to interrupt the request from outside of the program. It works but the inner timeout seems to keep running until it has reached its set duration. Only then does the process close. The request however stops properly.

Here is the code I am using:

import { Cause, Data, Effect, Fiber, Schedule } from 'effect';
import { setTimeout } from 'node:timers/promises';

class RequestError extends Data.TaggedError('RequestError') {}

let counter = 0;

const task = Effect.gen(function* () {
  const request = Effect.tryPromise({
    catch: () => new RequestError(),
    try: async () => {
      console.log('running request');
      await setTimeout(100);
      counter++;
      if (counter > 12) {
        console.log('request done');
        return 'ok' as const;
      }
      throw new Error('Connection setup failed');
    },
  }).pipe(
    Effect.retry({
      until: (err) => err._tag !== 'RequestError',
      schedule: Schedule.spaced('1 seconds'),
    }),
    Effect.timeoutTo({
      duration: '10 seconds',
      onSuccess: (v) => v,
      onTimeout: () => 'timeout' as const,
    })
  );

  const fiber = yield* request.pipe(Effect.forkDaemon);

  return {
    interrupt: () => {
      Effect.runSync(Fiber.interruptFork(fiber));
    },
    promise: Effect.runPromise(
      Effect.merge(
        fiber.pipe(
          Effect.catchAllCause((cause) => {
            if (Cause.isInterrupted(cause)) {
              console.log('interrupted');
              return Effect.fail('interrupted' as const);
            }

            return Effect.fail('unknown_error' as const);
          })
        )
      )
    ),
  };
});

const result = await Effect.runPromise(task);
console.log('result ---->', result);

await setTimeout(3000);
result.interrupt();

const promise = await result.promise;
console.log('promise ---->', promise);
Was this page helpful?