Skip to content

Commit

Permalink
feat: add improvements for handling redis errors
Browse files Browse the repository at this point in the history
  • Loading branch information
fruneen committed Dec 13, 2023
1 parent 4a65e8e commit cef3ccd
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 19 deletions.
16 changes: 12 additions & 4 deletions template/apps/api/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { socketService } from 'services';
import config from 'config';
import logger from 'logger';
import routes from 'routes';

import { redisErrorHandler } from 'redis-client';
import ioEmitter from 'io-emitter';

const initKoa = () => {
Expand Down Expand Up @@ -49,10 +51,16 @@ const app = initKoa();
(async () => {
const server = http.createServer(app.callback());

await Promise.all([
ioEmitter.initClient(),
socketService(server),
]);
if (config.REDIS_URI) {
try {
await Promise.all([
ioEmitter.initClient(),
socketService(server),
]);
} catch (e) {
if (e instanceof Error) redisErrorHandler(e);
}
}

server.listen(config.PORT, () => {
logger.info(`API server is listening on ${config.PORT}, in ${config.APP_ENV} environment`);
Expand Down
16 changes: 7 additions & 9 deletions template/apps/api/src/io-emitter.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { Emitter } from '@socket.io/redis-emitter';

import redisClient from 'redis-client';
import redisClient, { redisErrorHandler } from 'redis-client';
import logger from 'logger';

import config from './config';

let emitter: Emitter | null = null;

const publish = (roomId: string | string[], eventName: string, data: unknown) => {
if (emitter === null) {
if (config.REDIS_ERRORS_POLICY === 'throw') {
throw new Error('ioEmitter is not initialized.');
} else {
logger.debug('ioEmitter is not initialized.');
return;
}
redisErrorHandler(new Error('ioEmitter is not initialized.'));

return;
}

logger.debug(`published io event [${eventName}] to ${roomId}, the data is: ${JSON.stringify(data)}`);
Expand All @@ -24,6 +19,9 @@ const publish = (roomId: string | string[], eventName: string, data: unknown) =>

const initClient = async () => {
const subClient = redisClient.duplicate();

subClient.on('error', redisErrorHandler);

await subClient.connect();

emitter = new Emitter(subClient);
Expand Down
12 changes: 7 additions & 5 deletions template/apps/api/src/redis-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,23 @@ const client = createClient({
connectTimeout: 30_000,
reconnectStrategy: (retries) => {
const maxDelay = 5_000;
const baseDelay = 50;
const baseDelay = 1_000;

return Math.min(baseDelay * Math.pow(2, retries), maxDelay);
},
},
});

client.on('error', err => {
const errorMessage = `redisClient => Redis error: ${err.stack || err}`;
export const redisErrorHandler = (error: Error) => {
const errorMessage = `[Redis Client] ${error.stack || error}`;

if (config.REDIS_ERRORS_POLICY === 'throw') {
throw Error(errorMessage);
throw new Error(errorMessage);
} else {
logger.error(errorMessage);
}
});
};

client.on('error', redisErrorHandler);

export default client;
4 changes: 3 additions & 1 deletion template/apps/api/src/services/socket/socket.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { COOKIES } from 'app-constants';

import { tokenService } from 'resources/token';

import pubClient from 'redis-client';
import pubClient, { redisErrorHandler } from 'redis-client';
import logger from 'logger';

import socketHelper from './socket.helper';
Expand All @@ -16,6 +16,8 @@ export default async (server: http.Server) => {

const subClient = pubClient.duplicate();

subClient.on('error', redisErrorHandler);

await Promise.all([pubClient.connect(), subClient.connect()]);
logger.info('Socket.io server has been connected.');

Expand Down

0 comments on commit cef3ccd

Please sign in to comment.