better health check

This commit is contained in:
Nour Alharithi
2023-10-27 11:39:05 -07:00
parent 63d85ddc67
commit b623777067
3 changed files with 46 additions and 6 deletions

2
.gitignore vendored
View File

@@ -142,4 +142,4 @@ src/**.js.map
lib lib
src/playground.ts src/playground.ts
dump.rdb *dump.rdb

View File

@@ -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;
} }

View File

@@ -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,