better health check
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -142,4 +142,4 @@ src/**.js.map
|
|||||||
lib
|
lib
|
||||||
src/playground.ts
|
src/playground.ts
|
||||||
|
|
||||||
dump.rdb
|
*dump.rdb
|
||||||
@@ -7,7 +7,13 @@ import {
|
|||||||
MeterProvider,
|
MeterProvider,
|
||||||
View,
|
View,
|
||||||
} from '@opentelemetry/sdk-metrics-base';
|
} from '@opentelemetry/sdk-metrics-base';
|
||||||
import { commitHash, driftEnv, endpoint, wsEndpoint } from '..';
|
import {
|
||||||
|
commitHash,
|
||||||
|
driftEnv,
|
||||||
|
endpoint,
|
||||||
|
getSlotHealthCheckInfo,
|
||||||
|
wsEndpoint,
|
||||||
|
} from '..';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {count} buckets of size {increment} starting from {start}. Each bucket stores the count of values within its "size".
|
* Creates {count} buckets of size {increment} starting from {start}. Each bucket stores the count of values within its "size".
|
||||||
@@ -110,15 +116,35 @@ const responseStatusCounter = meter.createCounter(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const startupTime = Date.now();
|
const healthCheckInterval = 2000;
|
||||||
|
let lastHealthCheckSlot = -1;
|
||||||
|
let lastHealthCheckSlotUpdated = Date.now();
|
||||||
const handleHealthCheck = async (req, res, next) => {
|
const handleHealthCheck = async (req, res, next) => {
|
||||||
|
const { lastSlotReceived, lastSlotReceivedMutex } = getSlotHealthCheckInfo();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (req.url === '/health' || req.url === '/') {
|
if (req.url === '/health' || req.url === '/') {
|
||||||
if (Date.now() > startupTime + 60 * 1000) {
|
// check if a slot was received recently
|
||||||
healthStatus = HEALTH_STATUS.LivenessTesting;
|
let healthySlotSubscriber = false;
|
||||||
|
await lastSlotReceivedMutex.runExclusive(async () => {
|
||||||
|
const slotChanged = lastSlotReceived > lastHealthCheckSlot;
|
||||||
|
const slotChangedRecently =
|
||||||
|
Date.now() - lastHealthCheckSlotUpdated < healthCheckInterval;
|
||||||
|
healthySlotSubscriber = slotChanged || slotChangedRecently;
|
||||||
|
logger.debug(
|
||||||
|
`Slotsubscriber health check: lastSlotReceived: ${lastSlotReceived}, lastHealthCheckSlot: ${lastHealthCheckSlot}, slotChanged: ${slotChanged}, slotChangedRecently: ${slotChangedRecently}`
|
||||||
|
);
|
||||||
|
if (slotChanged) {
|
||||||
|
lastHealthCheckSlot = lastSlotReceived;
|
||||||
|
lastHealthCheckSlotUpdated = Date.now();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!healthySlotSubscriber) {
|
||||||
|
healthStatus = HEALTH_STATUS.UnhealthySlotSubscriber;
|
||||||
|
logger.error(`SlotSubscriber is not healthy`);
|
||||||
|
|
||||||
res.writeHead(500);
|
res.writeHead(500);
|
||||||
res.end('Testing liveness test fail');
|
res.end(`SlotSubscriber is not healthy`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
src/index.ts
14
src/index.ts
@@ -42,6 +42,7 @@ import {
|
|||||||
} from './utils/utils';
|
} from './utils/utils';
|
||||||
import { handleResponseTime } from './core/middleware';
|
import { handleResponseTime } from './core/middleware';
|
||||||
import { handleHealthCheck } from './core/metrics';
|
import { handleHealthCheck } from './core/metrics';
|
||||||
|
import { Mutex } from 'async-mutex';
|
||||||
|
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const driftEnv = (process.env.ENV || 'devnet') as DriftEnv;
|
const driftEnv = (process.env.ENV || 'devnet') as DriftEnv;
|
||||||
@@ -114,6 +115,13 @@ logger.info(`Commit: ${commitHash}`);
|
|||||||
|
|
||||||
let MARKET_SUBSCRIBERS: SubscriberLookup = {};
|
let MARKET_SUBSCRIBERS: SubscriberLookup = {};
|
||||||
|
|
||||||
|
const lastSlotReceivedMutex = new Mutex();
|
||||||
|
let lastSlotReceived: number;
|
||||||
|
|
||||||
|
export const getSlotHealthCheckInfo = () => {
|
||||||
|
return { lastSlotReceived, lastSlotReceivedMutex };
|
||||||
|
};
|
||||||
|
|
||||||
const initializeAllMarketSubscribers = async (driftClient: DriftClient) => {
|
const initializeAllMarketSubscribers = async (driftClient: DriftClient) => {
|
||||||
const markets: SubscriberLookup = {};
|
const markets: SubscriberLookup = {};
|
||||||
|
|
||||||
@@ -162,6 +170,7 @@ const main = async () => {
|
|||||||
programID: clearingHousePublicKey,
|
programID: clearingHousePublicKey,
|
||||||
accountSubscription: {
|
accountSubscription: {
|
||||||
type: 'websocket',
|
type: 'websocket',
|
||||||
|
resubTimeoutMs: 60000,
|
||||||
},
|
},
|
||||||
env: driftEnv,
|
env: driftEnv,
|
||||||
userStats: true,
|
userStats: true,
|
||||||
@@ -184,6 +193,11 @@ const main = async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await slotSubscriber.subscribe();
|
await slotSubscriber.subscribe();
|
||||||
|
slotSubscriber.eventEmitter.on('newSlot', async (slot: number) => {
|
||||||
|
await lastSlotReceivedMutex.runExclusive(async () => {
|
||||||
|
lastSlotReceived = slot;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const userMap = new UserMap(
|
const userMap = new UserMap(
|
||||||
driftClient,
|
driftClient,
|
||||||
|
|||||||
Reference in New Issue
Block a user