es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Usando el Async Event Listener con el módulo EventEmitter de Nestjs y funciones sin servidor.

Estoy intentando implementar un trabajador asíncrono con una función lambda sin servidor con la ayuda del módulo EventEmitter de Nestjs.

El controlador se invoca al emitir un evento, pero la función se cierra antes de la llamada async / await.

He intentado usar tanto las funciones “emit” como “emitAsync” y diferentes argumentos para
“@OnEvent(AccountEvents.NEW_ACCOUNT, {async:true, promisify:true})”.

Fragmento del productor

public async execute(event: EventDetail): Promise<void> {

  await this.eventEmitter.emitAsync(AccountEvents.NEW_ACCOUNT, event);
}

Fragmento del oyente

@OnEvent(AccountEvents.NEW_ACCOUNT)
  public async handleAccountCreatedEvent(event: EventDetail): Promise<void> {
    this.logger.log({ message: <code>Log1: ${AccountEvents.NEW_ACCOUNT} Handler</code>, event });
    const message = await this.testAsync();
    this.logger.log({ message });
    this.logger.log({ message: 'Log 3: Event Processing Successfuly Completed' });
  }

private testAsync(): Promise<string> {
    return new Promise(res => {
      setTimeout(() => {
        res('Log 2: Promise resolved after one sec');
      }, 1000);
    });
  }

Salida esperada: los 3 registros
Salida actual: solo el primer registro (Log1)

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema aquí parece estar relacionado con el hecho de que la función lambda se cierra antes de que se complete la llamada async/await. Una posible solución a este problema sería utilizar la opción callbackWaitsForEmptyEventLoop en la configuración de AWS Lambda. Esta opción, cuando se establece en true, asegura que la función lambda no se cierre antes de que se completen todas las operaciones asíncronas.

    Para implementar esto con NestJS y Serverless Framework, podemos agregar la opción callbackWaitsForEmptyEventLoop al archivo serverless.yml de la siguiente manera:

    custom:
      nest:
        packager: npm
        handler: dist/handler.handler
        server:
          # Otras opciones de configuración del servidor
        aws:
          callbackWaitsForEmptyEventLoop: true # Agregar esta línea
    

    Con esta opción configurada, deberíamos poder ver todas las tres declaraciones de registro en la salida.

    Otra posible solución sería envolver la llamada async/await en una promesa y devolver esa promesa al emisor de eventos. Esto garantizaría que la función no salga antes de que la promesa se resuelva.

    public handleAccountCreatedEvent(event: EventDetail): Promise<void> {
        this.logger.log({ message: `Log1: ${AccountEvents.NEW_ACCOUNT} Handler`, event });
        return new Promise(async (resolve, reject) => {
            const message = await this.testAsync();
            this.logger.log({ message });
            this.logger.log({ message: 'Log 3: Event Processing Successfully Completed' });
            resolve();
        });
    }
    
    

    Con estos cambios, deberíamos poder manejar correctamente las operaciones asíncronas en la función lambda y ver todos los registros impresos en la salida.

Comments are closed.