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

hirosystems / stacks-blockchain-api / 3631820147

pending completion
3631820147

push

github

Nick Barnett
feat(ibd-mode): merge develop

1872 of 2887 branches covered (64.84%)

695 of 775 new or added lines in 29 files covered. (89.68%)

6914 of 8974 relevant lines covered (77.04%)

338.02 hits per line

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

0.0
/src/shutdown-handler.ts
1
import { logError, logger, resolveOrTimeout } from './helpers';
×
2

3
const SHUTDOWN_SIGNALS = ['SIGINT', 'SIGTERM'] as const;
×
4

5
type ShutdownHandler = () => void | PromiseLike<void>;
6
type ShutdownConfig = {
7
  name: string;
8
  handler: ShutdownHandler;
9
  forceKillable: boolean;
10
  forceKillHandler?: ShutdownHandler;
11
};
12

13
const shutdownConfigs: ShutdownConfig[] = [];
×
14

15
let isShuttingDown = false;
×
16

17
async function startShutdown() {
18
  if (isShuttingDown) {
×
19
    return;
×
20
  }
21
  isShuttingDown = true;
×
NEW
22
  const timeoutMs = parseInt(process.env['STACKS_SHUTDOWN_FORCE_KILL_TIMEOUT'] ?? '60') * 1000;
×
23
  let errorEncountered = false;
×
24
  for (const config of shutdownConfigs) {
×
25
    try {
×
26
      logger.info(`Closing ${config.name}...`);
×
27
      const gracefulShutdown = await resolveOrTimeout(
×
28
        Promise.resolve(config.handler()),
29
        timeoutMs,
30
        !config.forceKillable,
31
        () =>
32
          logError(
×
33
            `${config.name} is taking longer than expected to shutdown, possibly hanging indefinitely`
34
          )
35
      );
36
      if (!gracefulShutdown) {
×
37
        if (config.forceKillable && config.forceKillHandler) {
×
38
          await Promise.resolve(config.forceKillHandler());
×
39
        }
40
        logError(
×
41
          `${config.name} was force killed after taking longer than ${timeoutMs}ms to shutdown`
42
        );
43
      } else {
44
        logger.info(`${config.name} closed`);
×
45
      }
46
    } catch (error) {
47
      errorEncountered = true;
×
48
      logError(`Error running ${config.name} shutdown handler`, error);
×
49
    }
50
  }
51
  if (errorEncountered) {
×
52
    process.exit(1);
×
53
  } else {
54
    logger.info('App shutdown successful.');
×
55
    process.exit();
×
56
  }
57
}
58

59
let shutdownSignalsRegistered = false;
×
60
function registerShutdownSignals() {
61
  if (shutdownSignalsRegistered) {
×
62
    return;
×
63
  }
64
  shutdownSignalsRegistered = true;
×
65

66
  SHUTDOWN_SIGNALS.forEach(sig => {
×
67
    process.once(sig, () => {
×
68
      logger.info(`Shutting down... received signal: ${sig}`);
×
69
      void startShutdown();
×
70
    });
71
  });
72
  process.once('unhandledRejection', error => {
×
73
    logError(`unhandledRejection ${(error as any)?.message ?? error}`, error as Error);
×
74
    logger.error(`Shutting down... received unhandledRejection.`);
×
75
    void startShutdown();
×
76
  });
77
  process.once('uncaughtException', error => {
×
78
    logError(`Received uncaughtException: ${error}`, error);
×
79
    logger.error(`Shutting down... received uncaughtException.`);
×
80
    void startShutdown();
×
81
  });
82
  process.once('beforeExit', () => {
×
83
    logger.info(`Shutting down... received beforeExit.`);
×
84
    void startShutdown();
×
85
  });
86
}
87

88
export function registerShutdownConfig(...configs: ShutdownConfig[]) {
×
89
  registerShutdownSignals();
×
90
  shutdownConfigs.push(...configs);
×
91
}
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

© 2025 Coveralls, Inc