Major Changes: - Implement Platform-Only architecture pattern (unified task management) - Add PostgresCacheAdapter for unified caching (platform_schema.app_cache) - Add PgBossQueue for job queue management (platform_schema.job) - Implement CheckpointService using job.data (generic for all modules) - Add intelligent threshold-based dual-mode processing (THRESHOLD=50) - Add task splitting mechanism (auto chunk size recommendation) - Refactor ASL screening service with smart mode selection - Refactor DC extraction service with smart mode selection - Register workers for ASL and DC modules Technical Highlights: - All task management data stored in platform_schema.job.data (JSONB) - Business tables remain clean (no task management fields) - CheckpointService is generic (shared by all modules) - Zero code duplication (DRY principle) - Follows 3-layer architecture principle - Zero additional cost (no Redis needed, save 8400 CNY/year) Code Statistics: - New code: ~1750 lines - Modified code: ~500 lines - Test code: ~1800 lines - Documentation: ~3000 lines Testing: - Unit tests: 8/8 passed - Integration tests: 2/2 passed - Architecture validation: passed - Linter errors: 0 Files: - Platform layer: PostgresCacheAdapter, PgBossQueue, CheckpointService, utils - ASL module: screeningService, screeningWorker - DC module: ExtractionController, extractionWorker - Tests: 11 test files - Docs: Updated 4 key documents Status: Phase 1-7 completed, Phase 8-9 pending
117 lines
4.1 KiB
TypeScript
117 lines
4.1 KiB
TypeScript
/**
|
||
* 测试 PostgresCacheAdapter
|
||
*
|
||
* 运行方式:
|
||
* npx ts-node src/tests/test-postgres-cache.ts
|
||
*/
|
||
|
||
import { PostgresCacheAdapter } from '../common/cache/PostgresCacheAdapter.js';
|
||
import { PrismaClient } from '@prisma/client';
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
async function testPostgresCache() {
|
||
console.log('🚀 开始测试 PostgresCacheAdapter...\n');
|
||
|
||
const cache = new PostgresCacheAdapter(prisma);
|
||
|
||
try {
|
||
// ========== 测试 1: 基本读写 ==========
|
||
console.log('📝 测试 1: 基本读写');
|
||
await cache.set('test:key1', { name: 'Alice', age: 25 }, 3600);
|
||
const value1 = await cache.get('test:key1');
|
||
console.log(' ✅ 写入并读取:', value1);
|
||
console.assert(value1?.name === 'Alice', '❌ 读取失败');
|
||
|
||
// ========== 测试 2: 过期机制 ==========
|
||
console.log('\n⏰ 测试 2: 过期机制');
|
||
await cache.set('test:expire', { data: 'temp' }, 2); // 2秒后过期
|
||
console.log(' 写入缓存,2秒后过期...');
|
||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||
const expiredValue = await cache.get('test:expire');
|
||
console.log(' ✅ 3秒后读取:', expiredValue);
|
||
console.assert(expiredValue === null, '❌ 过期机制失败');
|
||
|
||
// ========== 测试 3: 批量操作 ==========
|
||
console.log('\n📦 测试 3: 批量操作');
|
||
await cache.mset([
|
||
{ key: 'test:batch1', value: { id: 1 } },
|
||
{ key: 'test:batch2', value: { id: 2 } },
|
||
{ key: 'test:batch3', value: { id: 3 } },
|
||
], 3600);
|
||
const batchValues = await cache.mget(['test:batch1', 'test:batch2', 'test:batch3']);
|
||
console.log(' ✅ 批量写入并读取:', batchValues);
|
||
console.assert(batchValues.length === 3, '❌ 批量操作失败');
|
||
|
||
// ========== 测试 4: 删除操作 ==========
|
||
console.log('\n🗑️ 测试 4: 删除操作');
|
||
await cache.set('test:delete', { data: 'will be deleted' }, 3600);
|
||
await cache.delete('test:delete');
|
||
const deletedValue = await cache.get('test:delete');
|
||
console.log(' ✅ 删除后读取:', deletedValue);
|
||
console.assert(deletedValue === null, '❌ 删除失败');
|
||
|
||
// ========== 测试 5: has() 方法 ==========
|
||
console.log('\n🔍 测试 5: has() 方法');
|
||
await cache.set('test:exists', { data: 'exists' }, 3600);
|
||
const keyExists = await cache.has('test:exists');
|
||
const keyNotExists = await cache.has('test:not-exists');
|
||
console.log(' ✅ 存在的key:', keyExists);
|
||
console.log(' ✅ 不存在的key:', keyNotExists);
|
||
console.assert(keyExists === true && keyNotExists === false, '❌ has()失败');
|
||
|
||
// ========== 测试 6: 缓存清理 ==========
|
||
console.log('\n🧹 测试 6: 过期缓存自动删除');
|
||
// 创建一个已过期的缓存(expiresAt在过去)
|
||
await prisma.appCache.create({
|
||
data: {
|
||
key: 'test:expired1',
|
||
value: { data: 'old' },
|
||
expiresAt: new Date(Date.now() - 10000) // 10秒前过期
|
||
}
|
||
});
|
||
|
||
console.log(' 创建了一个已过期的缓存...');
|
||
|
||
// 尝试读取(应该触发懒删除)
|
||
const expiredData = await cache.get('test:expired1');
|
||
console.log(' 尝试读取过期数据:', expiredData);
|
||
console.assert(expiredData === null, '❌ 过期数据应返回null');
|
||
|
||
// 验证已被删除
|
||
const recordExists = await prisma.appCache.findUnique({
|
||
where: { key: 'test:expired1' }
|
||
});
|
||
console.log(` ✅ 过期数据已自动删除: ${recordExists === null ? '是' : '否'}`);
|
||
|
||
// ========== 清理测试数据 ==========
|
||
console.log('\n🧹 清理测试数据...');
|
||
await prisma.appCache.deleteMany({
|
||
where: {
|
||
key: { startsWith: 'test:' }
|
||
}
|
||
});
|
||
console.log(' ✅ 清理完成');
|
||
|
||
console.log('\n🎉 所有测试通过!\n');
|
||
|
||
} catch (error) {
|
||
console.error('❌ 测试失败:', error);
|
||
throw error;
|
||
} finally {
|
||
await prisma.$disconnect();
|
||
}
|
||
}
|
||
|
||
// 运行测试
|
||
testPostgresCache()
|
||
.then(() => {
|
||
console.log('✅ PostgresCacheAdapter 测试完成');
|
||
process.exit(0);
|
||
})
|
||
.catch((error) => {
|
||
console.error('❌ 测试失败:', error);
|
||
process.exit(1);
|
||
});
|
||
|