77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
|
|
import NodeCache from 'node-cache';
|
|
import { MongoClient } from 'mongodb';
|
|
import crypto from 'crypto';
|
|
import dotenv from 'dotenv';
|
|
|
|
dotenv.config();
|
|
|
|
const cache = new NodeCache({ stdTTL: parseInt(process.env.STD_TTL || '3600') });
|
|
const mongoClient = new MongoClient(process.env.MONGODB_URI || 'mongodb://localhost:27017');
|
|
const dbName = 'pageCache';
|
|
const collectionName = 'pages';
|
|
|
|
const connectToMongo = async () => {
|
|
await mongoClient.connect();
|
|
return mongoClient.db(dbName);
|
|
};
|
|
|
|
const createTTLIndex = async () => {
|
|
try {
|
|
const db = await connectToMongo();
|
|
await db.collection(collectionName).createIndex({ "updatedAt": 1 }, { expireAfterSeconds: parseInt(process.env.EXPIRE_AFTER_SECONDS || '9000') });
|
|
console.log("TTL index created successfully");
|
|
} catch (error) {
|
|
console.error("Error creating TTL index:", error);
|
|
}
|
|
};
|
|
|
|
const getPageHash = (content: string) => {
|
|
return crypto.createHash('md5').update(content).digest('hex');
|
|
};
|
|
|
|
export const getCachedPage = async (url: string) => {
|
|
const cachedPage = cache.get(url);
|
|
if (cachedPage) return cachedPage;
|
|
|
|
try {
|
|
const db = await connectToMongo();
|
|
const page = await db.collection(collectionName).findOne({ url });
|
|
if (page) cache.set(url, page);
|
|
return page;
|
|
} catch (error) {
|
|
console.error('Error getting cached page:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
const savePageToCache = async (url: string, content: string) => {
|
|
const hash = getPageHash(content);
|
|
const page = { url, content, hash, updatedAt: new Date() };
|
|
|
|
cache.set(url, page); // 更新内存缓存
|
|
|
|
try {
|
|
const db = await connectToMongo();
|
|
await db.collection(collectionName).updateOne(
|
|
{ url },
|
|
{ $set: page },
|
|
{ upsert: true }
|
|
); // 更新持久化缓存
|
|
} catch (error) {
|
|
console.error('Error saving page to cache:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
export const updateCacheAsync = async (url: string, content: string) => {
|
|
await savePageToCache(url, content);
|
|
};
|
|
|
|
process.on('SIGINT', async () => {
|
|
await mongoClient.close();
|
|
process.exit(0);
|
|
});
|
|
|
|
// 在应用启动时创建 TTL 索引
|
|
createTTLIndex(); |