• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

safe-global / safe-client-gateway / 10304487389

08 Aug 2024 02:56PM UTC coverage: 46.92% (+0.001%) from 46.919%
10304487389

push

github

web-flow
Remove database availability hard dependency at boot (#1815)

Prevent postgres-database.migration.hook.ts from throwing an error that blocks the service startup

476 of 2885 branches covered (16.5%)

Branch coverage included in aggregate %.

1 of 7 new or added lines in 1 file covered. (14.29%)

1 existing line in 1 file now uncovered.

4551 of 7829 relevant lines covered (58.13%)

12.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

30.77
/src/datasources/db/postgres-database.migration.hook.ts
1
import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
16✔
2
import { ILoggingService, LoggingService } from '@/logging/logging.interface';
16✔
3
import postgres from 'postgres';
16✔
4
import { PostgresDatabaseMigrator } from '@/datasources/db/postgres-database.migrator';
16✔
5
import { IConfigurationService } from '@/config/configuration.service.interface';
16✔
6
import { asError } from '@/logging/utils';
16✔
7

8
/**
9
 * The {@link PostgresDatabaseMigrationHook} is a Module Init hook meaning
10
 * that it will be executed once the dependencies are resolved.
11
 *
12
 * This happens before the Application Bootstraps, so route listeners are not
13
 * initiated and potentially generating queries.
14
 */
15
@Injectable({})
16
export class PostgresDatabaseMigrationHook implements OnModuleInit {
16✔
17
  private static LOCK_MAGIC_NUMBER = 132;
16✔
18
  private readonly runMigrations: boolean;
19

20
  constructor(
21
    @Inject('DB_INSTANCE') private readonly sql: postgres.Sql,
×
22
    @Inject(PostgresDatabaseMigrator)
23
    private readonly migrator: PostgresDatabaseMigrator,
×
24
    @Inject(LoggingService) private readonly loggingService: ILoggingService,
×
25
    @Inject(IConfigurationService)
26
    private readonly configurationService: IConfigurationService,
×
27
  ) {
28
    this.runMigrations = this.configurationService.getOrThrow<boolean>(
×
29
      'application.runMigrations',
30
    );
31
  }
32

33
  /**
34
   * Function executed when the module is initialized.
35
   *
36
   * This function will check if the migrations are enabled and if so, it will
37
   * acquire a lock to perform a migration. If the lock is not acquired, then
38
   * a migration is being executed by another instance.
39
   *
40
   * If the lock is acquired, the migration will be executed and the lock will
41
   * be released.
42
   */
43
  async onModuleInit(): Promise<void> {
44
    if (!this.runMigrations) {
×
45
      return this.loggingService.info('Database migrations are disabled');
×
46
    }
47

48
    try {
×
NEW
49
      this.loggingService.info('Checking migrations');
×
NEW
50
      await this.acquireLock();
×
51
      await this.migrator.migrate();
×
NEW
52
      await this.releaseLock();
×
UNCOV
53
      this.loggingService.info('Pending migrations executed');
×
54
    } catch (e) {
NEW
55
      this.loggingService.error(`Error running migrations: ${asError(e)}`);
×
56
    }
57
  }
58

59
  private async acquireLock(): Promise<void> {
NEW
60
    await this
×
61
      .sql`SELECT pg_advisory_lock(${PostgresDatabaseMigrationHook.LOCK_MAGIC_NUMBER})`;
62
  }
63

64
  private async releaseLock(): Promise<void> {
NEW
65
    await this
×
66
      .sql`SELECT pg_advisory_unlock(${PostgresDatabaseMigrationHook.LOCK_MAGIC_NUMBER})`;
67
  }
68
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc