With DataBaseREdis

This commit is contained in:
2026-01-28 00:49:37 +03:00
parent 4b01c2d4de
commit af62de5569
10 changed files with 1309 additions and 24 deletions

224
redis-client.js Normal file
View File

@ -0,0 +1,224 @@
/**
* Redis Client - опциональное подключение
* Если Redis недоступен, работает без БД
*/
let redisClient = null;
let redisAvailable = false;
let redisClientInstance = null; // Для connect-redis
async function initRedis() {
// Проверяем, нужно ли использовать Redis
const useRedis = process.env.USE_REDIS === 'true' || process.env.REDIS_URL;
if (!useRedis) {
console.log('📦 Redis отключен (USE_REDIS=false или REDIS_URL не установлен)');
return;
}
try {
const redis = require('redis');
const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379';
redisClient = redis.createClient({
url: redisUrl,
socket: {
reconnectStrategy: (retries) => {
if (retries > 10) {
console.log('⚠️ Redis: слишком много попыток переподключения, отключаемся');
redisAvailable = false;
return false; // Остановить переподключение
}
return Math.min(retries * 100, 3000);
}
}
});
redisClient.on('error', (err) => {
console.error('❌ Redis ошибка:', err.message);
redisAvailable = false;
});
redisClient.on('connect', () => {
console.log('🔌 Redis: подключение установлено');
redisAvailable = true;
});
redisClient.on('ready', () => {
console.log('✅ Redis: готов к работе');
redisAvailable = true;
});
redisClient.on('end', () => {
console.log('🔌 Redis: соединение закрыто');
redisAvailable = false;
});
await redisClient.connect();
redisClientInstance = redisClient; // Сохраняем для connect-redis
redisAvailable = true;
console.log('✅ Redis подключен успешно');
// Экспортируем клиент для connect-redis
module.exports.redisClientInstance = redisClient;
} catch (error) {
console.warn('⚠️ Redis недоступен, работаем без БД:', error.message);
redisAvailable = false;
redisClient = null;
}
}
async function closeRedis() {
if (redisClient && redisAvailable) {
try {
await redisClient.quit();
console.log('🔌 Redis: соединение закрыто');
} catch (error) {
console.error('Ошибка при закрытии Redis:', error);
}
}
}
// Проверка доступности Redis
function isRedisAvailable() {
return redisAvailable && redisClient !== null;
}
// Получить значение
async function get(key) {
if (!isRedisAvailable()) return null;
try {
return await redisClient.get(key);
} catch (error) {
console.error('Redis get error:', error);
return null;
}
}
// Установить значение
async function set(key, value, expireSeconds = null) {
if (!isRedisAvailable()) return false;
try {
if (expireSeconds) {
await redisClient.setEx(key, expireSeconds, value);
} else {
await redisClient.set(key, value);
}
return true;
} catch (error) {
console.error('Redis set error:', error);
return false;
}
}
// Удалить ключ
async function del(key) {
if (!isRedisAvailable()) return false;
try {
await redisClient.del(key);
return true;
} catch (error) {
console.error('Redis del error:', error);
return false;
}
}
// Получить все ключи по паттерну
async function keys(pattern) {
if (!isRedisAvailable()) return [];
try {
return await redisClient.keys(pattern);
} catch (error) {
console.error('Redis keys error:', error);
return [];
}
}
// Получить хеш
async function hGet(key, field) {
if (!isRedisAvailable()) return null;
try {
return await redisClient.hGet(key, field);
} catch (error) {
console.error('Redis hGet error:', error);
return null;
}
}
// Установить поле в хеше
async function hSet(key, field, value) {
if (!isRedisAvailable()) return false;
try {
await redisClient.hSet(key, field, value);
return true;
} catch (error) {
console.error('Redis hSet error:', error);
return false;
}
}
// Получить все поля хеша
async function hGetAll(key) {
if (!isRedisAvailable()) return {};
try {
return await redisClient.hGetAll(key);
} catch (error) {
console.error('Redis hGetAll error:', error);
return {};
}
}
// Увеличить значение
async function incr(key) {
if (!isRedisAvailable()) return 0;
try {
return await redisClient.incr(key);
} catch (error) {
console.error('Redis incr error:', error);
return 0;
}
}
// Получить список (добавить в конец)
async function rPush(key, ...values) {
if (!isRedisAvailable()) return 0;
try {
return await redisClient.rPush(key, values);
} catch (error) {
console.error('Redis rPush error:', error);
return 0;
}
}
// Получить элементы списка
async function lRange(key, start, stop) {
if (!isRedisAvailable()) return [];
try {
return await redisClient.lRange(key, start, stop);
} catch (error) {
console.error('Redis lRange error:', error);
return [];
}
}
// Получить клиент Redis для connect-redis
function getRedisClient() {
return redisClientInstance;
}
module.exports = {
initRedis,
closeRedis,
isRedisAvailable,
getRedisClient,
get,
set,
del,
keys,
hGet,
hSet,
hGetAll,
incr,
rPush,
lRange
};