mirror of
https://gitlab.com/foxixus/neomovies-api.git
synced 2025-10-28 01:48:51 +05:00
improve db code
This commit is contained in:
108
src/db.js
108
src/db.js
@@ -12,12 +12,18 @@ let clientPromise;
|
|||||||
const clientOptions = {
|
const clientOptions = {
|
||||||
maxPoolSize: 10,
|
maxPoolSize: 10,
|
||||||
minPoolSize: 0,
|
minPoolSize: 0,
|
||||||
serverSelectionTimeoutMS: 30000,
|
// Увеличиваем таймауты для медленных соединений
|
||||||
socketTimeoutMS: 45000,
|
serverSelectionTimeoutMS: 60000, // 60 секунд
|
||||||
connectTimeoutMS: 30000,
|
socketTimeoutMS: 0, // Убираем таймаут сокета
|
||||||
|
connectTimeoutMS: 60000, // 60 секунд
|
||||||
retryWrites: true,
|
retryWrites: true,
|
||||||
w: 'majority',
|
w: 'majority',
|
||||||
|
|
||||||
|
// Добавляем настройки для лучшей стабильности
|
||||||
|
maxIdleTimeMS: 30000,
|
||||||
|
waitQueueTimeoutMS: 5000,
|
||||||
|
heartbeatFrequencyMS: 10000,
|
||||||
|
|
||||||
serverApi: {
|
serverApi: {
|
||||||
version: '1',
|
version: '1',
|
||||||
strict: true,
|
strict: true,
|
||||||
@@ -25,50 +31,110 @@ const clientOptions = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Функция для создания подключения с retry логикой
|
||||||
|
async function createConnection() {
|
||||||
|
let attempts = 0;
|
||||||
|
const maxAttempts = 3;
|
||||||
|
|
||||||
|
while (attempts < maxAttempts) {
|
||||||
|
try {
|
||||||
|
console.log(`Attempting to connect to MongoDB (attempt ${attempts + 1}/${maxAttempts})...`);
|
||||||
|
const client = new MongoClient(uri, clientOptions);
|
||||||
|
await client.connect();
|
||||||
|
|
||||||
|
// Проверяем подключение
|
||||||
|
await client.db().admin().ping();
|
||||||
|
console.log('MongoDB connection successful');
|
||||||
|
return client;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
attempts++;
|
||||||
|
console.error(`Connection attempt ${attempts} failed:`, error.message);
|
||||||
|
|
||||||
|
if (attempts >= maxAttempts) {
|
||||||
|
throw new Error(`Failed to connect to MongoDB after ${maxAttempts} attempts: ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ждем перед следующей попыткой
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Connection management
|
// Connection management
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
// In development mode, use a global variable so that the value
|
// В режиме разработки используем глобальную переменную
|
||||||
// is preserved across module reloads caused by HMR (Hot Module Replacement).
|
|
||||||
if (!global._mongoClientPromise) {
|
if (!global._mongoClientPromise) {
|
||||||
client = new MongoClient(uri, clientOptions);
|
global._mongoClientPromise = createConnection();
|
||||||
global._mongoClientPromise = client.connect();
|
|
||||||
console.log('MongoDB connection initialized in development');
|
console.log('MongoDB connection initialized in development');
|
||||||
}
|
}
|
||||||
clientPromise = global._mongoClientPromise;
|
clientPromise = global._mongoClientPromise;
|
||||||
} else {
|
} else {
|
||||||
// In production mode, it's best to not use a global variable.
|
// В продакшене создаем новое подключение
|
||||||
client = new MongoClient(uri, clientOptions);
|
clientPromise = createConnection();
|
||||||
clientPromise = client.connect();
|
|
||||||
console.log('MongoDB connection initialized in production');
|
console.log('MongoDB connection initialized in production');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function getDb() {
|
async function getDb() {
|
||||||
try {
|
try {
|
||||||
const mongoClient = await clientPromise;
|
const mongoClient = await clientPromise;
|
||||||
|
|
||||||
|
// Проверяем, что подключение все еще активно
|
||||||
|
if (!mongoClient || mongoClient.topology.isDestroyed()) {
|
||||||
|
throw new Error('MongoDB connection is not available');
|
||||||
|
}
|
||||||
|
|
||||||
return mongoClient.db();
|
return mongoClient.db();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting MongoDB database:', error);
|
console.error('Error getting MongoDB database:', error);
|
||||||
throw error;
|
|
||||||
|
// Пытаемся переподключиться
|
||||||
|
console.log('Attempting to reconnect...');
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
global._mongoClientPromise = createConnection();
|
||||||
|
clientPromise = global._mongoClientPromise;
|
||||||
|
} else {
|
||||||
|
clientPromise = createConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
const mongoClient = await clientPromise;
|
||||||
|
return mongoClient.db();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function closeConnection() {
|
async function closeConnection() {
|
||||||
if (client) {
|
try {
|
||||||
try {
|
const mongoClient = await clientPromise;
|
||||||
await client.close(true);
|
if (mongoClient) {
|
||||||
client = null;
|
await mongoClient.close(true);
|
||||||
global._mongoClientPromise = null;
|
|
||||||
console.log('MongoDB connection closed');
|
console.log('MongoDB connection closed');
|
||||||
} catch (error) {
|
|
||||||
console.error('Error closing MongoDB connection:', error);
|
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error closing MongoDB connection:', error);
|
||||||
|
} finally {
|
||||||
|
client = null;
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
global._mongoClientPromise = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция для проверки подключения
|
||||||
|
async function checkConnection() {
|
||||||
|
try {
|
||||||
|
const db = await getDb();
|
||||||
|
await db.admin().ping();
|
||||||
|
console.log('MongoDB connection is healthy');
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('MongoDB connection check failed:', error.message);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up handlers
|
// Clean up handlers
|
||||||
const cleanup = async () => {
|
const cleanup = async () => {
|
||||||
|
console.log('Cleaning up MongoDB connection...');
|
||||||
await closeConnection();
|
await closeConnection();
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
};
|
};
|
||||||
@@ -88,4 +154,4 @@ process.on('unhandledRejection', async (reason) => {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = { getDb, closeConnection };
|
module.exports = { getDb, closeConnection, checkConnection };
|
||||||
Reference in New Issue
Block a user