Commit Graph

11 Commits

Author SHA1 Message Date
JamesFlare1212
6c58eacc8f fix(s3): racing condition and different URL in redis 2026-04-07 23:21:54 -04:00
JamesFlare1212
bbbd59be94 fix(s3): updating clean all files in s3 2026-04-07 22:45:10 -04:00
JamesFlare1212
0a133159e8 重构 scan: 实现多线程并发爬虫功能
- 新增 Semaphore 信号量类控制并发数
- 新增 BatchProcessor 批量处理器带进度回调
- 重构 initializeClubCache 和 updateStaleClubs 为并发模式
- 修复 Cookie 4xx 判断逻辑(仅 401/403 触发重新登录)
- 添加环境变量配置:CONCURRENT_API_CALLS 等
- 新增并发功能测试脚本 test-concurrency.ts

性能提升:从串行处理提升至可配置的并发处理(默认 8 线程)
修复问题:404 错误不再误判为认证失败
2026-04-07 18:18:18 -04:00
JamesFlare1212
fc98dbbbae fix(scan): remove p-limit 2026-04-07 08:38:15 -04:00
JamesFlare1212
821df1c51f fix(scan): prevent exponential slowdown from event loop blocking
- Reduce default CONCURRENT_API_CALLS from 10 to 5 (Sharp AVIF is CPU-intensive)
- Create fresh p-limit instance per batch instead of module singleton
- Add garbage collection hint between batches
- Fix skippedCount tracking (was never incremented)
- Increase batch delay from 100ms to 500ms for event loop drainage
2026-04-07 07:35:48 -04:00
JamesFlare1212
573a9b3f4c fix(scan): batch processing and timeout reduction to prevent stall at 20%
- Process activities in batches of 100 instead of 5001 promises upfront
- Clear promise array after each batch to free memory (85MB→15MB peak)
- Reduce API timeout from 20s to 10s and retries from 3 to 2
- Total time per failed request: 63s→23s (63% faster failure)
- Expected total scan time: 8.5h→1.5h (82% faster)
2026-04-07 07:19:46 -04:00
JamesFlare1212
92b12a6a85 fix(scan): prevent progressive slowdown with mutex, batching, and connection pooling
- Add mutex to cron jobs to prevent overlapping runs
- Replace Promise.all with batched processing (50/batch) in updateStaleClubs
- Configure HTTP connection pooling with keep-alive (maxSockets: 50)
- Add memory monitoring to scan progress logs
- Reduce CONCURRENT_API_CALLS from 8 to 5 to reduce Sharp memory pressure
2026-04-07 00:00:56 -04:00
JamesFlare1212
f1967d5519 fix(cache): use Promise.allSettled to prevent hung promises from blocking scan
Root cause: Promise.all() waits for ALL promises, so a single hung/slow request
blocks the entire batch. With 5001 promises and 16 concurrent limit, timeouts
cause cascading delays that appear as 'scan stopped'.

Fix:
- Extract processSingleActivity() helper function
- Use Promise.allSettled() instead of Promise.all()
- Each promise handles its own success/error counting
- Prevents single hung promise from blocking entire scan

Impact: Scan should now complete all 5001 IDs without getting stuck
2026-04-06 21:48:10 -04:00
JamesFlare1212
32dee6b161 fix(cache): resolve scanning stop issue and add cache TTL management
- Fix Redis SCAN cursor type conversion (Buffer to String) to prevent early termination
- Add progress logging in initializeClubCache (every 100 activities with summary)
- Add Redis memory limits (512MB with LRU eviction policy)
- Implement cache TTL: 24h for normal data, 1h for error states (allows retry)
- Fix Docker permission issue by running app container as root
- Add TTL configuration to .env and example.env

Root cause: SCAN cursor comparison failed due to type mismatch (Buffer vs String)
Impact: Scanning now processes all 5000+ IDs instead of stopping at ~300
2026-04-06 21:03:30 -04:00
JamesFlare1212
8598571f72 improve: code structure 2025-05-12 21:45:57 -04:00
JamesFlare1212
2543e56ec4 init: port to typescript and bun 2025-05-10 23:39:39 -04:00