feat: implement session activity tracking for time-based cleanup

Implements full tracking of session activity (message send/receive) to enable
cleanup of inactive sessions based on configurable time thresholds.

**What's new:**
1. **SessionActivityTracker** (src/Signal/session-activity-tracker.ts)
   - In-memory cache for activity timestamps (fast, <0.1ms overhead)
   - Periodic flush to disk (every 60s, configurable)
   - Batch writes for efficiency

2. **Activity Recording**
   - Records activity on message send (messages-send.ts)
   - Records activity on message receive (messages-recv.ts)
   - Tracks both group and individual conversations

3. **Enhanced Cleanup Logic** (session-cleanup.ts)
   - Uses real activity timestamps for decisions
   - Implements 3 cleanup rules:
     * LID orphans: inactive > 24h (configurable)
     * Secondary devices: inactive > 15 days (configurable)
     * Primary devices: inactive > 30 days (configurable)

**Configuration:**
- BAILEYS_SESSION_ACTIVITY_ENABLED=true (default)
- BAILEYS_SESSION_ACTIVITY_FLUSH_MS=60000 (1 minute)
- BAILEYS_SESSION_SECONDARY_INACTIVE_DAYS=15
- BAILEYS_SESSION_PRIMARY_INACTIVE_DAYS=30
- BAILEYS_SESSION_LID_ORPHAN_HOURS=24

**Performance:**
- Overhead per message: <0.1ms (just Map.set() in memory)
- Disk I/O: Batched every 60s (minimal impact)
- Memory: ~100KB per 1000 active sessions in cache

**Safety:**
- Does NOT affect connections or message delivery
- Signal Protocol auto-recreates deleted sessions
- Runs in low-traffic hours (3am default)
- Graceful degradation if tracker unavailable

https://claude.ai/code/session_01SoNUGBEWbJwWWws3F2fuzh
This commit is contained in:
Claude
2026-02-10 04:08:34 +00:00
parent a4a0272ccc
commit 0232a805ae
5 changed files with 371 additions and 22 deletions
+12
View File
@@ -14,6 +14,7 @@ import {
UPLOAD_TIMEOUT
} from '../Defaults'
import { makeSessionCleanup } from '../Signal/session-cleanup'
import { makeSessionActivityTracker } from '../Signal/session-activity-tracker'
import type { ConnectionState, LIDMapping, SocketConfig } from '../Types'
import { DisconnectReason } from '../Types'
import {
@@ -501,10 +502,14 @@ export const makeSocket = (config: SocketConfig) => {
const keys = addTransactionCapability(authState.keys, logger, transactionOpts)
const signalRepository = makeSignalRepository({ creds, keys }, logger, pnFromLIDUSync)
// Session activity tracker - tracks last activity for cleanup (must be created first)
const sessionActivityTracker = makeSessionActivityTracker(keys, logger)
// Session cleanup manager - removes inactive/orphaned sessions
const sessionCleanup = makeSessionCleanup(
keys,
signalRepository.lidMapping,
sessionActivityTracker,
logger,
DEFAULT_SESSION_CLEANUP_CONFIG
)
@@ -1092,6 +1097,9 @@ export const makeSocket = (config: SocketConfig) => {
// Stop session cleanup scheduler
sessionCleanup.stop()
// Stop session activity tracker and flush pending data
await sessionActivityTracker.stop()
// Clean up unified session manager
unifiedSessionManager?.destroy()
@@ -1464,6 +1472,9 @@ export const makeSocket = (config: SocketConfig) => {
// Start session cleanup scheduler
sessionCleanup.start()
// Start session activity tracker
sessionActivityTracker.start()
// Update server time offset from success node
const serverTime = extractServerTime(node)
if (serverTime) {
@@ -1589,6 +1600,7 @@ export const makeSocket = (config: SocketConfig) => {
authState: { creds, keys },
signalRepository,
sessionCleanup,
sessionActivityTracker,
get user() {
return authState.creds.me
},