Effect.ts: Absence as First-Class

ConcurrencyLesson 13 of 51

13. Interruption - Cancelling Absence

Sometimes we stop waiting for absent values

Code Example
const longTask = Effect.gen(function* () {
  yield* Effect.sleep("10 seconds");
  return "Done!";
});

// Start resolving absence
const fiber = Effect.runFork(longTask);

// Changed our mind!
fiber.interrupt();

// The absence resolution is cancelled.
// Any acquired resources are cleaned up.
Interactive Example
const { Fiber } = await import('effect');
const longTask = Effect.gen(function* () {
      yield* Effect.sleep('100 millis');
      return 'Done!';
});
let completed = false;
const fiber = Effect.runFork(longTask.pipe(
      Effect.tap(() => Effect.sync(() => { completed = true; }))
));
await Effect.runPromise(Effect.sleep('20 millis'));
await Effect.runPromise(Fiber.interrupt(fiber));
return `Interruption!

Task started (100ms duration)
Interrupted after 20ms
Completed: ${completed}

Task cancelled cleanly!`;
Explanation

Interruption: stopping absence resolution mid-flight.

Traditional approach: once started, hard to cancel cleanly. Effect types cancellable unavailability:

  • Data is unavailable (long task)
  • We start trying to make it available
  • No assumptions it will complete
  • Describe: "Stop trying to resolve this absence"

Absence-first thinking: we can give up on making data available!


Part 13 of 51 in the Effect.ts Absence Modeling series