@heliyos/heliyos-api-core 1.0.15 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mongoose.js +140 -79
- package/package.json +1 -1
package/dist/mongoose.js
CHANGED
|
@@ -36,114 +36,147 @@ __exportStar(require("mongoose"), exports);
|
|
|
36
36
|
let cachedConnection;
|
|
37
37
|
let cachedReplicaConnection;
|
|
38
38
|
const connectionOptions = {
|
|
39
|
-
//
|
|
39
|
+
// Timeouts
|
|
40
40
|
serverSelectionTimeoutMS: 60000,
|
|
41
41
|
connectTimeoutMS: 60000,
|
|
42
42
|
socketTimeoutMS: 360000,
|
|
43
|
-
// Connection pool
|
|
44
|
-
maxPoolSize:
|
|
45
|
-
minPoolSize:
|
|
46
|
-
//
|
|
43
|
+
// Connection pool settings
|
|
44
|
+
maxPoolSize: 10,
|
|
45
|
+
minPoolSize: 1,
|
|
46
|
+
// Heartbeat monitoring
|
|
47
|
+
heartbeatFrequencyMS: 10000,
|
|
48
|
+
// Modern reliability settings
|
|
47
49
|
retryWrites: true,
|
|
48
50
|
retryReads: true,
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
monitorCommands: true,
|
|
51
|
+
// Required for newer MongoDB versions
|
|
52
|
+
useNewUrlParser: true,
|
|
53
|
+
useUnifiedTopology: true,
|
|
53
54
|
};
|
|
54
|
-
const MAX_RETRY_ATTEMPTS = 5
|
|
55
|
-
const INITIAL_RETRY_DELAY =
|
|
55
|
+
const MAX_RETRY_ATTEMPTS = 10; // Increased from 5
|
|
56
|
+
const INITIAL_RETRY_DELAY = 2000; // Increased from 1000
|
|
56
57
|
const connectWithRetry = (mongoUrl, attempt = 1) => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
58
|
try {
|
|
58
59
|
logger_1.logger.info(`Attempting to connect to MongoDB (attempt ${attempt}/${MAX_RETRY_ATTEMPTS})`);
|
|
60
|
+
// Create connection with event handlers
|
|
59
61
|
const connection = mongoose_1.default.createConnection(mongoUrl, connectionOptions);
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
// Set up event handlers before attempting connection
|
|
63
|
+
connection.on("error", (err) => {
|
|
64
|
+
logger_1.logger.error("MongoDB connection error:", err);
|
|
65
|
+
// Attempt reconnection after delay
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
if (connection.readyState !== mongoose_1.default.ConnectionStates.connected) {
|
|
68
|
+
logger_1.logger.info("Attempting to reconnect after error...");
|
|
69
|
+
connection.openUri(mongoUrl, connectionOptions);
|
|
70
|
+
}
|
|
71
|
+
}, 5000);
|
|
72
|
+
});
|
|
73
|
+
connection.on("disconnected", () => {
|
|
74
|
+
logger_1.logger.warn("MongoDB disconnected, attempting to reconnect...");
|
|
64
75
|
});
|
|
76
|
+
connection.on("reconnected", () => {
|
|
77
|
+
logger_1.logger.info("MongoDB reconnected successfully");
|
|
78
|
+
});
|
|
79
|
+
// Wait for initial connection with timeout
|
|
80
|
+
yield Promise.race([
|
|
81
|
+
new Promise((resolve, reject) => {
|
|
82
|
+
connection.once("connected", () => resolve());
|
|
83
|
+
connection.once("error", (err) => reject(err));
|
|
84
|
+
}),
|
|
85
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("Connection timeout")), connectionOptions.connectTimeoutMS)),
|
|
86
|
+
]);
|
|
65
87
|
return connection;
|
|
66
88
|
}
|
|
67
89
|
catch (error) {
|
|
68
90
|
if (attempt >= MAX_RETRY_ATTEMPTS) {
|
|
69
|
-
logger_1.logger.error("Max retry attempts reached. Failed to connect to MongoDB");
|
|
91
|
+
logger_1.logger.error("Max retry attempts reached. Failed to connect to MongoDB:", error);
|
|
70
92
|
return null;
|
|
71
93
|
}
|
|
72
94
|
const delay = INITIAL_RETRY_DELAY * Math.pow(2, attempt - 1);
|
|
73
|
-
logger_1.logger.warn(`Connection attempt ${attempt} failed. Retrying in ${delay}ms
|
|
95
|
+
logger_1.logger.warn(`Connection attempt ${attempt} failed. Retrying in ${delay}ms... Error: ${error.message}`);
|
|
74
96
|
yield new Promise((resolve) => setTimeout(resolve, delay));
|
|
75
97
|
return connectWithRetry(mongoUrl, attempt + 1);
|
|
76
98
|
}
|
|
77
99
|
});
|
|
78
100
|
const mongooseConnected = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
mongoose_1.default.ConnectionStates.connected) {
|
|
83
|
-
logger_1.logger.info("Using cached MongoDB Connection");
|
|
84
|
-
return cachedConnection;
|
|
85
|
-
}
|
|
86
|
-
// Try to reconnect using existing connection
|
|
87
|
-
try {
|
|
88
|
-
yield cachedConnection.openUri(process.env.MONGO_DATABASE_URL, connectionOptions);
|
|
101
|
+
try {
|
|
102
|
+
if (cachedConnection) {
|
|
103
|
+
// Use type assertion to check connection state
|
|
89
104
|
if (cachedConnection.readyState ===
|
|
90
105
|
mongoose_1.default.ConnectionStates.connected) {
|
|
91
|
-
logger_1.logger.info("
|
|
106
|
+
logger_1.logger.info("Using cached MongoDB Connection");
|
|
92
107
|
return cachedConnection;
|
|
93
108
|
}
|
|
109
|
+
// Try to reconnect using existing connection
|
|
110
|
+
try {
|
|
111
|
+
yield cachedConnection.openUri(process.env.MONGO_DATABASE_URL, connectionOptions);
|
|
112
|
+
if (cachedConnection.readyState ===
|
|
113
|
+
mongoose_1.default.ConnectionStates.connected) {
|
|
114
|
+
logger_1.logger.info("Successfully reconnected using cached connection");
|
|
115
|
+
return cachedConnection;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
logger_1.logger.warn("Failed to reconnect using cached connection, will create new one");
|
|
120
|
+
}
|
|
94
121
|
}
|
|
95
|
-
|
|
96
|
-
|
|
122
|
+
let mongoUrl;
|
|
123
|
+
const nodeEnv = process.env.NODE_ENV;
|
|
124
|
+
if (nodeEnv === "local") {
|
|
125
|
+
mongoUrl = process.env.MONGO_DATABASE_URL || "";
|
|
126
|
+
// Add logging to debug URL
|
|
97
127
|
}
|
|
128
|
+
else if (["development", "production"].includes(nodeEnv)) {
|
|
129
|
+
const secrets = yield (0, ssm_1.getSecretsManagerSecret)(process.env.ENV_SECRET_NAME);
|
|
130
|
+
mongoUrl = secrets.MONGO_DATABASE_URL;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
logger_1.logger.error(`Invalid NODE_ENV: ${nodeEnv}`);
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
if (nodeEnv === "development") {
|
|
137
|
+
logger_1.logger.info(`Connecting to MongoDB URL: ${mongoUrl === null || mongoUrl === void 0 ? void 0 : mongoUrl.replace(/\/\/[^@]*@/, "//****:****@")}`);
|
|
138
|
+
}
|
|
139
|
+
if (!mongoUrl) {
|
|
140
|
+
logger_1.logger.error("MONGO_DATABASE_URL not set");
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
logger_1.logger.info("Creating new MongoDB Connection");
|
|
144
|
+
const connection = yield connectWithRetry(mongoUrl).catch((error) => {
|
|
145
|
+
logger_1.logger.error("Failed to connect to MongoDB:", error);
|
|
146
|
+
return null;
|
|
147
|
+
});
|
|
148
|
+
if (!connection) {
|
|
149
|
+
logger_1.logger.error("Failed to establish MongoDB connection after retries");
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
// Enhanced error handling
|
|
153
|
+
connection.on("error", (err) => {
|
|
154
|
+
logger_1.logger.error("MongoDB connection error:", err);
|
|
155
|
+
// Attempt to reconnect after a delay
|
|
156
|
+
setTimeout(() => {
|
|
157
|
+
if (connection.readyState !== mongoose_1.default.ConnectionStates.connected) {
|
|
158
|
+
logger_1.logger.info("Attempting to reconnect...");
|
|
159
|
+
connection.openUri(mongoUrl, connectionOptions);
|
|
160
|
+
}
|
|
161
|
+
}, 5000);
|
|
162
|
+
});
|
|
163
|
+
// Add connection monitoring
|
|
164
|
+
connection.on("disconnected", () => {
|
|
165
|
+
logger_1.logger.warn("MongoDB disconnected. Attempting to reconnect...");
|
|
166
|
+
});
|
|
167
|
+
connection.on("reconnected", () => {
|
|
168
|
+
logger_1.logger.info("MongoDB reconnected successfully");
|
|
169
|
+
});
|
|
170
|
+
connection.on("connected", () => {
|
|
171
|
+
logger_1.logger.info("MongoDB connected successfully");
|
|
172
|
+
});
|
|
173
|
+
cachedConnection = connection;
|
|
174
|
+
return connection;
|
|
98
175
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (nodeEnv === "local" || nodeEnv === "development") {
|
|
102
|
-
mongoUrl = process.env.MONGO_DATABASE_URL;
|
|
103
|
-
// Add logging to debug URL
|
|
104
|
-
logger_1.logger.info(`Connecting to MongoDB URL: ${mongoUrl.replace(/\/\/[^@]*@/, "//****:****@")}`);
|
|
105
|
-
}
|
|
106
|
-
else if (["development", "production"].includes(nodeEnv)) {
|
|
107
|
-
const secrets = yield (0, ssm_1.getSecretsManagerSecret)(process.env.ENV_SECRET_NAME);
|
|
108
|
-
mongoUrl = secrets.MONGO_DATABASE_URL;
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
logger_1.logger.error(`Invalid NODE_ENV: ${nodeEnv}`);
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
if (!mongoUrl) {
|
|
115
|
-
logger_1.logger.error("MONGO_DATABASE_URL not set");
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
logger_1.logger.info("Creating new MongoDB Connection");
|
|
119
|
-
const connection = yield connectWithRetry(mongoUrl);
|
|
120
|
-
if (!connection) {
|
|
121
|
-
logger_1.logger.error("Failed to establish MongoDB connection after retries");
|
|
176
|
+
catch (error) {
|
|
177
|
+
logger_1.logger.error("Unexpected error in mongooseConnected:", error);
|
|
122
178
|
return null;
|
|
123
179
|
}
|
|
124
|
-
// Enhanced error handling
|
|
125
|
-
connection.on("error", (err) => {
|
|
126
|
-
logger_1.logger.error("MongoDB connection error:", err);
|
|
127
|
-
// Attempt to reconnect after a delay
|
|
128
|
-
setTimeout(() => {
|
|
129
|
-
if (connection.readyState !== mongoose_1.default.ConnectionStates.connected) {
|
|
130
|
-
logger_1.logger.info("Attempting to reconnect...");
|
|
131
|
-
connection.openUri(mongoUrl, connectionOptions);
|
|
132
|
-
}
|
|
133
|
-
}, 5000);
|
|
134
|
-
});
|
|
135
|
-
// Add connection monitoring
|
|
136
|
-
connection.on("disconnected", () => {
|
|
137
|
-
logger_1.logger.warn("MongoDB disconnected. Attempting to reconnect...");
|
|
138
|
-
});
|
|
139
|
-
connection.on("reconnected", () => {
|
|
140
|
-
logger_1.logger.info("MongoDB reconnected successfully");
|
|
141
|
-
});
|
|
142
|
-
connection.on("connected", () => {
|
|
143
|
-
logger_1.logger.info("MongoDB connected successfully");
|
|
144
|
-
});
|
|
145
|
-
cachedConnection = connection;
|
|
146
|
-
return connection;
|
|
147
180
|
});
|
|
148
181
|
const replicaMongooseConnected = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
149
182
|
if (cachedReplicaConnection) {
|
|
@@ -307,10 +340,11 @@ const closeConnections = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
307
340
|
}
|
|
308
341
|
});
|
|
309
342
|
exports.closeConnections = closeConnections;
|
|
310
|
-
//
|
|
343
|
+
// Update the startConnectionMonitoring function to be more resilient
|
|
311
344
|
const startConnectionMonitoring = (checkInterval = 30000) => {
|
|
312
345
|
let isReconnecting = false;
|
|
313
|
-
|
|
346
|
+
let monitoringInterval;
|
|
347
|
+
const monitor = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
314
348
|
try {
|
|
315
349
|
if (isReconnecting)
|
|
316
350
|
return;
|
|
@@ -336,7 +370,34 @@ const startConnectionMonitoring = (checkInterval = 30000) => {
|
|
|
336
370
|
isReconnecting = false;
|
|
337
371
|
logger_1.logger.error("Connection monitoring error:", error);
|
|
338
372
|
}
|
|
339
|
-
})
|
|
373
|
+
});
|
|
374
|
+
// Wrap the interval in a try-catch
|
|
375
|
+
try {
|
|
376
|
+
monitoringInterval = setInterval(monitor, checkInterval);
|
|
377
|
+
}
|
|
378
|
+
catch (error) {
|
|
379
|
+
logger_1.logger.error("Failed to start connection monitoring:", error);
|
|
380
|
+
}
|
|
381
|
+
// Return cleanup function
|
|
382
|
+
return () => {
|
|
383
|
+
try {
|
|
384
|
+
if (monitoringInterval) {
|
|
385
|
+
clearInterval(monitoringInterval);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
catch (error) {
|
|
389
|
+
logger_1.logger.error("Error cleaning up monitoring interval:", error);
|
|
390
|
+
}
|
|
391
|
+
};
|
|
340
392
|
};
|
|
341
393
|
// Call this when your application starts
|
|
342
394
|
startConnectionMonitoring();
|
|
395
|
+
// Add process-level error handling
|
|
396
|
+
process.on("unhandledRejection", (reason, promise) => {
|
|
397
|
+
logger_1.logger.error("Unhandled Rejection at:", promise, "reason:", reason);
|
|
398
|
+
// Don't exit the process, just log the error
|
|
399
|
+
});
|
|
400
|
+
process.on("uncaughtException", (error) => {
|
|
401
|
+
logger_1.logger.error("Uncaught Exception:", error);
|
|
402
|
+
// Don't exit the process, just log the error
|
|
403
|
+
});
|