Skip to content

Implement mongoose health check depends on ping command #2661

@ahmad-athra

Description

@ahmad-athra

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

in case of mongo replica set, when primary node restart or not stable, secondary nodes go to elections procces, connection.readyState() still return 1, but queries and command return timeout,

  private async pingDb(connection: any, timeout: number) {
    const promise =
      connection.readyState === 1 ? Promise.resolve() : Promise.reject();
    return await promiseTimeout(timeout, promise);
  }

Describe the solution you'd like

I suggest to use conection.db.command({ ping: 1 }), this is more realistic.

@Injectable()
export class CMongooseHealthIndicator {
  constructor(
    private readonly healthIndicatorService: HealthIndicatorService,
    @InjectConnection()
    private readonly mongooseConnection: Connection
  ) {}


  async isHealthy(key: string, timeout: number){
      const indicator = this.healthIndicatorService.check(key);
    try {
        if (!this.mongooseConnection?.db) {
            throw new Error('No MongoDB connection or db object found');
          }
        const result = await firstValueFrom(
            from(this.mongooseConnection.db?.command({ping: 1 }))
            .pipe(
                timeout(timeout)
            )
        )
    
        console.log('result', result);
    
        const isHealthy = result?.ok === 1;
    
        if (!isHealthy) {
          return indicator.down({ status: 'down' });
        }
    
        return indicator.up();
        
    } catch (error) {
        return indicator.down({ status: 'down', error });
        
    }
  }
}

Teachability, documentation, adoption, migration strategy

// terminus/lib/health-indicator/database/mongoose.health.ts
  private async pingDb(connection: any, timeout: number) {
    const promise =
      connection.readyState === 1 ? Promise.resolve() : Promise.reject();
    return await promiseTimeout(timeout, promise);
  }

to be like the above example in CMongooseHealthIndicator class

What is the motivation / use case for changing the behavior?

Give more details about the connection status in case of error, and do an actual ping to the mongo server

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions