docker-redis - local refactors
Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
116
server.js
116
server.js
@@ -1,27 +1,30 @@
|
||||
const express = require("express");
|
||||
const cors = require("cors");
|
||||
const bodyParser = require("body-parser");
|
||||
const path = require("path");
|
||||
const http = require("http");
|
||||
const Redis = require("ioredis");
|
||||
const express = require("express");
|
||||
const bodyParser = require("body-parser");
|
||||
const compression = require("compression");
|
||||
const cookieParser = require("cookie-parser");
|
||||
const http = require("http");
|
||||
const { Server } = require("socket.io");
|
||||
// const { createClient } = require("redis");
|
||||
const Redis = require("ioredis");
|
||||
const { createAdapter } = require("@socket.io/redis-adapter");
|
||||
const logger = require("./server/utils/logger");
|
||||
const { redisSocketEvents } = require("./server/web-sockets/redisSocketEvents");
|
||||
const { instrument, RedisStore } = require("@socket.io/admin-ui");
|
||||
|
||||
const { instrument } = require("@socket.io/admin-ui");
|
||||
const { isString, isEmpty } = require("lodash");
|
||||
|
||||
const logger = require("./server/utils/logger");
|
||||
const applyRedisHelpers = require("./server/utils/redisHelpers");
|
||||
const applyIOHelpers = require("./server/utils/ioHelpers");
|
||||
const { redisSocketEvents } = require("./server/web-sockets/redisSocketEvents");
|
||||
|
||||
// Load environment variables
|
||||
require("dotenv").config({
|
||||
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
|
||||
});
|
||||
|
||||
const CLUSTER_RETRY_BASE_DELAY = 100;
|
||||
const CLUSTER_RETRY_MAX_DELAY = 5000;
|
||||
const CLUSTER_RETRY_JITTER = 100;
|
||||
|
||||
/**
|
||||
* CORS Origin for Socket.IO
|
||||
* @type {string[][]}
|
||||
@@ -50,11 +53,11 @@ const SOCKETIO_CORS_ORIGIN = [
|
||||
"https://old.imex.online",
|
||||
"https://www.old.imex.online",
|
||||
"https://wsadmin.imex.online",
|
||||
"https://www.wsadmin.imex.online",
|
||||
"http://localhost:3333",
|
||||
"https://localhost:3333"
|
||||
"https://www.wsadmin.imex.online"
|
||||
];
|
||||
|
||||
const SOCKETIO_CORS_ORIGIN_DEV = ["http://localhost:3333", "https://localhost:3333"];
|
||||
|
||||
/**
|
||||
* Middleware for Express app
|
||||
* @param app
|
||||
@@ -103,29 +106,52 @@ const applyRoutes = (app) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Connect to Redis Cluster
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
const connectToRedisCluster = () => {
|
||||
const redisCluster = new Redis.Cluster(
|
||||
process.env.REDIS_URL
|
||||
? JSON.parse(process.env.REDIS_URL)
|
||||
: [
|
||||
{
|
||||
host: "localhost",
|
||||
port: 6379
|
||||
}
|
||||
],
|
||||
{
|
||||
clusterRetryStrategy: function (times) {
|
||||
const delay = Math.min(100 + times * 50, 2000);
|
||||
logger.log(
|
||||
`[${process.env.NODE_ENV}] Redis cluster not yet ready. Retrying in ${delay}ms`,
|
||||
"ERROR",
|
||||
"redis",
|
||||
"api"
|
||||
);
|
||||
return delay;
|
||||
}
|
||||
if (isEmpty(process.env?.REDIS_URL) || !isString(process.env?.REDIS_URL)) {
|
||||
logger.log(`[${process.env.NODE_ENV}] No or Malformed REDIS_URL present.`, "ERROR", "redis", "api");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let redisServers;
|
||||
|
||||
try {
|
||||
redisServers = JSON.parse(process.env.REDIS_URL);
|
||||
} catch (error) {
|
||||
logger.log(
|
||||
`[${process.env.NODE_ENV}] Failed to parse REDIS_URL: ${error.message}. Exiting...`,
|
||||
"ERROR",
|
||||
"redis",
|
||||
"api"
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const clusterRetryStrategy = (times) => {
|
||||
const delay =
|
||||
Math.min(CLUSTER_RETRY_BASE_DELAY + times * 50, CLUSTER_RETRY_MAX_DELAY) + Math.random() * CLUSTER_RETRY_JITTER;
|
||||
logger.log(
|
||||
`[${process.env.NODE_ENV}] Redis cluster not yet ready. Retrying in ${delay.toFixed(2)}ms`,
|
||||
"ERROR",
|
||||
"redis",
|
||||
"api"
|
||||
);
|
||||
return delay;
|
||||
};
|
||||
|
||||
const redisCluster = new Redis.Cluster(redisServers, {
|
||||
clusterRetryStrategy,
|
||||
enableAutoPipelining: true,
|
||||
enableReadyCheck: true,
|
||||
redisOptions: {
|
||||
// connectTimeout: 10000, // Timeout for connecting in ms
|
||||
// idleTimeoutMillis: 30000, // Close idle connections after 30s
|
||||
// maxRetriesPerRequest: 5 // Retry a maximum of 5 times per request
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
redisCluster.on("ready", () => {
|
||||
@@ -171,9 +197,11 @@ const applySocketIO = async (server, app) => {
|
||||
const ioRedis = new Server(server, {
|
||||
path: "/wss",
|
||||
adapter: createAdapter(pubClient, subClient),
|
||||
store: new RedisStore(pubClient, subClient),
|
||||
cors: {
|
||||
origin: SOCKETIO_CORS_ORIGIN,
|
||||
origin:
|
||||
process.env?.NODE_ENV === "development"
|
||||
? [...SOCKETIO_CORS_ORIGIN, ...SOCKETIO_CORS_ORIGIN_DEV]
|
||||
: SOCKETIO_CORS_ORIGIN,
|
||||
methods: ["GET", "POST"],
|
||||
credentials: true,
|
||||
exposedHeaders: ["set-cookie"]
|
||||
@@ -188,6 +216,7 @@ const applySocketIO = async (server, app) => {
|
||||
username: "admin",
|
||||
password: process.env.REDIS_ADMIN_PASS
|
||||
},
|
||||
|
||||
mode: process.env.REDIS_ADMIN_MODE || "development"
|
||||
});
|
||||
}
|
||||
@@ -202,19 +231,22 @@ const applySocketIO = async (server, app) => {
|
||||
}
|
||||
});
|
||||
|
||||
const api = {
|
||||
pubClient,
|
||||
io,
|
||||
ioRedis,
|
||||
redisCluster
|
||||
};
|
||||
|
||||
app.use((req, res, next) => {
|
||||
Object.assign(req, {
|
||||
pubClient,
|
||||
io,
|
||||
ioRedis
|
||||
});
|
||||
Object.assign(req, api);
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
Object.assign(module.exports, { io, pubClient, ioRedis });
|
||||
Object.assign(module.exports, api);
|
||||
|
||||
return { pubClient, io, ioRedis };
|
||||
return api;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user