effect-resources-scope

majiayu000's avatarfrom majiayu000

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

⭐0stars🔀0forks📁View on GitHub🕐Updated Jan 5, 2026

When & Why to Use This Skill

This Claude skill specializes in robust resource management and lifecycle safety using the Effect library. It provides expert patterns for implementing 'acquire and release' logic, ensuring that critical resources like file handles, network sockets, and database connections are always properly closed, even during errors. By leveraging Effect.scoped and finalizers, it helps developers build leak-proof, resilient applications with predictable cleanup behavior.

Use Cases

  • Safe File and Stream Handling: Automatically manage file descriptors and data streams to prevent 'too many open files' errors and ensure data integrity during I/O operations.
  • Network and Socket Lifecycle Management: Orchestrate the opening and closing of TCP/UDP sockets or WebSocket connections in high-concurrency environments to prevent resource exhaustion.
  • Wrapping Legacy SDKs: Transform standard Promise-based APIs (such as AWS S3 or database drivers) into typed, resource-safe Effect workflows with built-in error handling and spans.
  • Complex Finalization Logic: Implement multi-step cleanup procedures using finalizers and 'ensuring' blocks to maintain system stability across interdependent services.
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