-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtemp.mjs
202 lines (173 loc) · 5.86 KB
/
temp.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import express from "express";
import http from "http";
import cors from "cors";
import { Server } from "socket.io";
import { MongoClient, ServerApiVersion } from "mongodb";
import mongoose from "mongoose";
import { fileURLToPath } from "url";
import { dirname, join } from "path";
import dotenv from "dotenv";
import { createAdapter } from "@socket.io/redis-adapter";
import { createClient } from "redis";
import { Clean_up } from "./Functions/Cleanup.js";
import chatRouter from "./routes/chatRouter.js";
import analyzeRouter from "./routes/analyzeRouter.js";
import handleSocketEvents from "./controllers/socketController.js";
import cookieParser from "cookie-parser";
dotenv.config();
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const buildPath = join(__dirname, "..", "client", "dist");
export default async () => {
const app = express();
const server = http.createServer(app);
// Redis setup
const redisHost = process.env.REDIS_HOST;
const redisPort = process.env.REDIS_PORT;
const redisPassword = process.env.REDIS_PASSWORD;
const io = new Server(server, {
cors: {
origin: ["https://devrooms-manit.netlify.app"],
methods: ["*"],
},
pingTimeout: 60000,
pingInterval: 25000,
});
const createRedisClient = () => {
return createClient({
socket: {
host: redisHost,
port: redisPort,
},
password: redisPassword,
});
};
const pubClient = createRedisClient();
const subClient = createRedisClient();
const handleRedisError = (client, error) => {
console.error(`Redis client error: ${error}`);
client.quit(); // Close the client connection
setTimeout(() => {
const newClient = createRedisClient(); // Create a new client
newClient.on("error", (err) => handleRedisError(newClient, err)); // Handle errors for the new client
newClient.on("connect", () => {
console.log("Successfully reconnected to Redis");
// Update the pubClient and subClient references
pubClient = newClient;
subClient = newClient;
io.adapter(createAdapter(pubClient, subClient)); // Update the adapter with the new clients
});
newClient.connect(); // Connect to Redis
}, 5000); // Retry after 5 seconds
};
const connectRedis = async () => {
try {
pubClient.on("error", (err) => handleRedisError(pubClient, err));
subClient.on("error", (err) => handleRedisError(subClient, err));
await pubClient.connect();
await subClient.connect();
console.log("Successfully connected to Redis");
pubClient.on("reconnecting", () =>
console.log("Pub client reconnecting to Redis...")
);
subClient.on("reconnecting", () =>
console.log("Sub client reconnecting to Redis...")
);
} catch (error) {
console.error("Failed to connect to Redis:", error);
// Implement retry logic here instead of exiting
}
};
await connectRedis();
io.adapter(createAdapter(pubClient, subClient));
// CORS and middleware setup
app.use(
cors({
origin: ["https://devrooms-manit.netlify.app"],
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allowedHeaders: ["Content-Type", "Cookie"],
credentials: true,
})
);
app.use(express.json());
app.use(cookieParser());
// MongoDB setup
const uri = process.env.MONGO_DB_URI;
const mongoClientOptions = {
serverApi: {
version: ServerApiVersion.v1,
strict: true,
deprecationErrors: true,
},
socketTimeoutMS: 45000,
connectTimeoutMS: 45000,
serverSelectionTimeoutMS: 45000,
};
const client = new MongoClient(uri, mongoClientOptions);
const connectToMongo = async () => {
try {
await mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
socketTimeoutMS: 45000,
connectTimeoutMS: 45000,
serverSelectionTimeoutMS: 45000,
});
console.log("Mongoose connected to MongoDB");
await client.connect();
await client.db("admin").command({ ping: 1 });
console.log("Pinged your deployment. MongoClient successfully connected to MongoDB!");
} catch (error) {
console.error("Failed to connect to MongoDB:", error);
setTimeout(connectToMongo, 5000); // Retry after 5 seconds
}
};
await connectToMongo();
// Routes
app.use("/api", chatRouter);
app.use("/analyze-api", analyzeRouter);
app.use(express.static(buildPath));
app.get("*", (req, res) => {
res.sendFile(join(buildPath, "index.html"));
});
// Socket events
//Passing the redis connection instance to the socket Controller to use it in the socket events to store the socketIDs
handleSocketEvents(io,pubClient);
// Cleanup
setInterval(Clean_up, 15 * 60 * 1000);
// Start server
const port = process.env.PORT;
server.listen(port);
// Graceful shutdown
const gracefulShutdown = async (signal) => {
console.log(`${signal} received. Shutting down gracefully...`);
server.close(() => {
console.log("HTTP server closed.");
});
try {
await client.close();
console.log("MongoDB connection closed.");
await mongoose.connection.close();
console.log("Mongoose connection closed.");
await pubClient.quit();
await subClient.quit();
console.log("Redis connections closed.");
process.exit(0);
} catch (err) {
console.error("Error during graceful shutdown:", err);
process.exit(1);
}
};
// Handle various shutdown signals
["SIGINT", "SIGTERM", "SIGQUIT"].forEach((signal) => {
process.on(signal, () => gracefulShutdown(signal));
});
process.on("uncaughtException", (err) => {
console.error("Uncaught Exception:", err);
gracefulShutdown("Uncaught Exception");
});
process.on("unhandledRejection", (reason, promise) => {
console.error("Unhandled Rejection at:", promise, "reason:", reason);
gracefulShutdown("Unhandled Rejection");
});
};