mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-22 15:24:55 +00:00
fa2282b48f
***Update GConstructor type in Mixins*** ***Update ReflectionMetadataType in Reflection*** ***Update connectToDatabase function in Redis*** ***Update MockRouterForMethodFunction in Helpers*** ***Update DefaultValidateFunction type in BasicForm*** ***Update result type in BaseAPI.test*** ***Update startUserNotificationRuleExecution function in OnCallDutyPolicyEscalationRuleService*** ***Update getTableColumn and getTableColumns functions in TableColumn*** ***Update getColumnBillingAccessControl and getColumnBillingAccessControlForAllColumns functions in ColumnBillingAccessControl
126 lines
3.8 KiB
TypeScript
126 lines
3.8 KiB
TypeScript
import Sleep from 'Common/Types/Sleep';
|
|
import { Redis as RedisClient, RedisOptions } from 'ioredis';
|
|
import {
|
|
RedisHostname,
|
|
RedisPort,
|
|
RedisUsername,
|
|
RedisPassword,
|
|
RedisDb,
|
|
RedisTlsCa,
|
|
RedisTlsSentinelMode,
|
|
ShouldRedisTlsEnable,
|
|
} from '../EnvironmentConfig';
|
|
import logger from '../Utils/Logger';
|
|
|
|
export type ClientType = RedisClient;
|
|
|
|
export default abstract class Redis {
|
|
private static client: RedisClient | null = null;
|
|
|
|
public static isConnected(): boolean {
|
|
if (!this.client) {
|
|
return false;
|
|
}
|
|
|
|
return this.client.status === 'ready';
|
|
}
|
|
|
|
public static getClient(): RedisClient | null {
|
|
return this.client;
|
|
}
|
|
|
|
public static async connect(): Promise<RedisClient> {
|
|
let retry: number = 0;
|
|
|
|
try {
|
|
const redisOptions: RedisOptions = {
|
|
host: RedisHostname,
|
|
port: RedisPort.toNumber(),
|
|
username: RedisUsername,
|
|
password: RedisPassword,
|
|
db: RedisDb,
|
|
enableTLSForSentinelMode: RedisTlsSentinelMode,
|
|
lazyConnect: true,
|
|
};
|
|
|
|
if (ShouldRedisTlsEnable) {
|
|
redisOptions.tls = { ca: RedisTlsCa };
|
|
}
|
|
|
|
this.client = new RedisClient(redisOptions);
|
|
|
|
// Listen to 'error' events to the Redis connection
|
|
this.client.on('error', (error: Error) => {
|
|
if ((error as any).code === 'ECONNRESET') {
|
|
logger.error(
|
|
'Connection to Redis Session Store timed out.'
|
|
);
|
|
} else if ((error as any).code === 'ECONNREFUSED') {
|
|
logger.error('Connection to Redis Session Store refused!');
|
|
} else {
|
|
logger.error(error);
|
|
}
|
|
});
|
|
|
|
// Listen to 'reconnecting' event to Redis
|
|
this.client.on('reconnecting', () => {
|
|
if (this.client?.status === 'reconnecting') {
|
|
logger.error('Reconnecting to Redis Session Store...');
|
|
} else {
|
|
logger.error('Error reconnecting to Redis Session Store.');
|
|
}
|
|
});
|
|
|
|
// Listen to the 'connect' event to Redis
|
|
this.client.on('connect', (err: Error) => {
|
|
if (!err) {
|
|
logger.info('Connected to Redis Session Store!');
|
|
}
|
|
});
|
|
|
|
type ConnectToDatabaseFunction = (
|
|
client: RedisClient
|
|
) => Promise<void>;
|
|
|
|
const connectToDatabase: ConnectToDatabaseFunction = async (
|
|
client: RedisClient
|
|
): Promise<void> => {
|
|
try {
|
|
await client.connect();
|
|
} catch (err) {
|
|
if (retry < 3) {
|
|
logger.info(
|
|
'Cannot connect to Redis. Retrying again in 5 seconds'
|
|
);
|
|
// sleep for 5 seconds.
|
|
|
|
await Sleep.sleep(5000);
|
|
|
|
retry++;
|
|
return await connectToDatabase(client);
|
|
}
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
await connectToDatabase(this.client);
|
|
|
|
logger.info(
|
|
`Redis connected on ${RedisHostname}:${RedisPort.toNumber()}`
|
|
);
|
|
return this.client;
|
|
} catch (err) {
|
|
logger.error('Redis Connection Failed');
|
|
logger.error(err);
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
public static disconnect(): void {
|
|
if (this.isConnected()) {
|
|
this.client?.disconnect();
|
|
this.client = null;
|
|
}
|
|
}
|
|
}
|