Effect CommunityEC
Effect Community13mo ago
21 replies
Jambudipa

Understanding scope and finalizers in Effect.Service

I have created a MongoDB service that really just maintains a client.

However, the finalizer is running prematurely. I created this service since this problem existed in the service I originally had this code in directly. This has been working, but I am using a newer version of effect, so perhaps the contract has changed?
export class MongoService extends Effect.Service<MongoService>()('MongoService', {
  scoped: Effect.gen(function* (_) {
    yield* Effect.log('MongoService: Initializing MongoDB Client...');
    const client = new MongoClient(uri);

    yield* Effect.tryPromise({
      try: async () => {
        await client.connect();
        console.log('MongoService: MongoDB connection established');
      },
      catch: (error) => new Error(`MongoService: Failed to connect - ${error}`)
    }).pipe(Effect.orDie);

    // Register finalizer to clean up the client
    yield* Effect.addFinalizer(() =>
      Effect.tryPromise({
        try: async () => {
          await client.close();
          console.log('MongoService: MongoDB client connection closed');
        },
        catch: (error) =>
          new Error(`MongoService: Failed to close connection - ${error}`)
      }).pipe(Effect.orDie)
    );

    const db: Db = client.db('<my-db>');

    return {
      client,
      db
    } as const;
  })
}) {
}

The finalizer block is executed almost as soon as the service itself is yielded here:
export class SearchService extends Effect.Service<SearchService>()('SearchService', {
  dependencies: [Language.Default, MongoService.Default],
  scoped: Effect.gen(function* () {
    const language = yield* Language;
    const mongo = yield* MongoService;
  })
}) {
}

Why might this be?
Was this page helpful?