effect-resources-scope

mepuka's avatarfrom mepuka

Resource safety with acquireRelease, Effect.scoped, and finalizers. Use when opening files, sockets, servers, or external handles.

⭐0stars🔀0forks📁View on GitHub🕐Updated Dec 25, 2025

When & Why to Use This Skill

The Effect Resources Scope skill provides advanced resource management capabilities for TypeScript developers using the Effect library. It simplifies the implementation of the 'acquire-use-release' pattern, ensuring that critical resources like files, sockets, and database connections are always closed correctly, even in the event of errors. By leveraging acquireRelease, Effect.scoped, and finalizers, this skill helps eliminate resource leaks and improves application reliability through structured concurrency and safety-first programming patterns.

Use Cases

  • Safe File Operations: Automatically closing file handles and descriptors to prevent 'too many open files' errors in high-throughput Node.js applications.
  • Database Connection Management: Ensuring database connections are properly returned to the pool and transactions are handled safely using scoped effects.
  • Network Socket Lifecycle: Managing the acquisition and release of sockets or server listeners to ensure clean network communication and port availability.
  • Cloud SDK Integration: Wrapping Promise-based APIs (like AWS S3) with typed errors and guaranteed cleanup logic using finalizers and spans for observability.
  • Complex Cleanup Logic: Using Effect.ensuring and addFinalizer to guarantee that temporary resources or background processes are terminated during application shutdown.
nameeffect-resources-scope
descriptionResource safety with acquireRelease, Effect.scoped, and finalizers. Use when opening files, sockets, servers, or external handles.
allowed-toolsRead, Grep, Glob, Edit, Write

Resource Management (Scope)

Acquire/Release

const withConn = Effect.acquireRelease(
  Effect.sync(() => open()),
  (conn) => Effect.sync(() => close(conn))
).pipe(Effect.flatMap(use))

Scoped

yield* Effect.scoped(
  Effect.gen(function* () {
    const h = yield* Effect.acquireRelease(acquire(), release)
    return yield* use(h)
  })
)

Finalizers

yield* Effect.addFinalizer(() => cleanup)

Ensuring

operation.pipe(Effect.ensuring(cleanup))

Real-world snippet: wrap Promise APIs with typed errors and spans

const wrapS3Promise = <T>(promise: Promise<T> | Effect.Effect<Promise<T>>) =>
  Effect.gen(function* () {
    if (promise instanceof Promise) {
      return yield* Effect.tryPromise({ try: () => promise, catch: (cause) => new S3Error({ cause }) })
    }
    return yield* promise.pipe(
      Effect.flatMap((cb) =>
        Effect.tryPromise({ try: () => cb, catch: (cause) => new S3Error({ cause }) })
      )
    )
  }).pipe(Effect.catchTag("UnknownException", (cause) => new S3Error({ cause })))

// Usage with spans
const put = wrapS3Promise(client.send(new S3.PutObjectCommand(args))).pipe(
  Effect.withSpan("S3.putObject", { attributes: { key: args.Key } })
)

Local Source Reference

CRITICAL: Search local Effect source before implementing

The full Effect source code is available at docs/effect-source/. Always search the actual implementation before writing Effect code.

Key Source Files

  • Effect: docs/effect-source/effect/src/Effect.ts
  • Scope: docs/effect-source/effect/src/Scope.ts

Example Searches

# Find acquireRelease patterns
grep -F "acquireRelease" docs/effect-source/effect/src/Effect.ts

# Study scoped operations
grep -F "scoped" docs/effect-source/effect/src/Effect.ts
grep -F "addFinalizer" docs/effect-source/effect/src/Effect.ts

# Find ensuring patterns
grep -F "ensuring" docs/effect-source/effect/src/Effect.ts

# Look at Scope implementation
grep -F "export" docs/effect-source/effect/src/Scope.ts | grep -F "function"

Workflow

  1. Identify the resource management API you need (e.g., acquireRelease)
  2. Search docs/effect-source/effect/src/Effect.ts for the implementation
  3. Study the types and resource patterns
  4. Look at test files for usage examples
  5. Write your code based on real implementations

Real source code > documentation > assumptions

References