CI / build + unit (pull_request) Failing after 39s
Second production zombie slipped past v0.21.1's watchdog: text+telemetry RX dead for >1 h while TX worked and the watchdog never fired. Root cause proven at runtime via /proc/net/snmp — InSegs delta = 2 segments per 30 s (OutSegs 0): the bridge peer keeps dribbling small NON-frame bytes (~every 15 s, keepalive noise or a desynced stream) and v0.21.1 updated lastPacketAt on EVERY socket chunk, so 'no traffic for MESH_IDLE_TIMEOUT_MS' was never true even though zero valid Meshtastic frames decoded. - The 'data' handler no longer updates lastPacketAt per chunk; it is updated only when extractFrames yields >=1 valid packet (the reset in the 'connect' handler is unchanged), so a stream that decodes nothing trips the watchdog after MESH_IDLE_TIMEOUT_MS even while raw bytes keep arriving. - Buffer-overflow backstop: if the undecoded frame buffer exceeds MESH_MAX_FRAME_BUFFER (new env, default 256000) — e.g. one data event of a desynced stream that never forms frames — log ERROR and destroy the socket; the existing close -> scheduleReconnect loop self-heals it. The undecoded buffer is also reset on every (re)connect so leftover garbage from a dead session can't re-trigger the backstop or corrupt the first frames of a healthy new stream. Tests: 169 -> 171 — raw non-frame bytes do NOT keep the watchdog alive (garbage-only stream forces disconnect + reconnect, today's incident shape), and an undecoded chunk over MESH_MAX_FRAME_BUFFER triggers destroy + a fresh session that decodes normally (cap env-overridden to 100 since Node delivers socket data in ~64 KB events, far below the 256_000 default).
55 lines
1.6 KiB
JSON
55 lines
1.6 KiB
JSON
{
|
|
"name": "mesh-bot",
|
|
"version": "0.21.2",
|
|
"description": "",
|
|
"author": "",
|
|
"private": true,
|
|
"license": "UNLICENSED",
|
|
"scripts": {
|
|
"build": "nest build",
|
|
"deploy": "nest deploy",
|
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
"start": "nest start",
|
|
"start:dev": "nest start --watch",
|
|
"start:debug": "nest start --debug --watch",
|
|
"start:prod": "node dist/main",
|
|
"lint": "oxlint src/ test/",
|
|
"test": "vitest run",
|
|
"test:watch": "vitest",
|
|
"test:cov": "vitest run --coverage",
|
|
"test:debug": "vitest --inspect-brk --no-file-parallelism",
|
|
"test:e2e": "vitest run --config ./vitest.config.e2e.ts"
|
|
},
|
|
"dependencies": {
|
|
"@bufbuild/protobuf": "^2.15.0",
|
|
"@meshtastic/protobufs": "^2.8.0",
|
|
"@modelcontextprotocol/sdk": "^1.30.1",
|
|
"@nestjs/common": "^12.0.1",
|
|
"@nestjs/core": "^12.0.1",
|
|
"@nestjs/platform-express": "^12.0.1",
|
|
"@nestjs/schedule": "^12.0.2",
|
|
"@nestjs/swagger": "^12.0.2",
|
|
"@scalar/nestjs-api-reference": "^1.2.21",
|
|
"fast-xml-parser": "^5.11.1",
|
|
"reflect-metadata": "^0.2.2",
|
|
"rxjs": "^7.8.1"
|
|
},
|
|
"devDependencies": {
|
|
"@nestjs/cli": "^12.0.0",
|
|
"@nestjs/mau": "^0.2.6",
|
|
"@nestjs/schematics": "^12.0.0",
|
|
"@nestjs/testing": "^12.0.1",
|
|
"@types/express": "^5.0.0",
|
|
"@types/node": "^24.0.0",
|
|
"@types/supertest": "^7.0.0",
|
|
"@vitest/coverage-v8": "^4.1.2",
|
|
"oxlint": "^1.58.0",
|
|
"prettier": "^3.4.2",
|
|
"source-map-support": "^0.5.21",
|
|
"supertest": "^7.0.0",
|
|
"typescript": "^6.0.2",
|
|
"vite-tsconfig-paths": "^5.1.4",
|
|
"vitest": "^4.1.2"
|
|
}
|
|
}
|