claude-flow-novice 1.6.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/cfn-loop/product-owner.md +54 -4
- package/.claude/commands/cfn-claude-sync.md +303 -0
- package/.claude/commands/cfn-loop-epic.md +290 -0
- package/.claude/commands/cfn-loop-single.md +168 -0
- package/.claude/commands/cfn-loop-sprints.md +384 -0
- package/.claude/commands/cfn-loop.md +180 -0
- package/.claude/commands/metrics-summary.md +58 -0
- package/.claude/commands/parse-epic.md +357 -0
- package/.claude/settings.json +4 -4
- package/.claude/settings.local.json +9 -2
- package/.claude-flow-novice/.claude/agents/cfn-loop/product-owner.md +792 -0
- package/.claude-flow-novice/dist/mcp/server.js +21 -2
- package/.claude-flow-novice/dist/src/api/claude-client.js +138 -3
- package/.claude-flow-novice/dist/src/api/claude-client.js.map +1 -1
- package/.claude-flow-novice/dist/src/cfn-loop/phase-orchestrator-example.js +1 -1
- package/.claude-flow-novice/dist/src/cfn-loop/scope-control.js +247 -0
- package/.claude-flow-novice/dist/src/cfn-loop/scope-control.js.map +1 -0
- package/.claude-flow-novice/dist/src/cli/commands/swarm.js +32 -15
- package/.claude-flow-novice/dist/src/cli/commands/swarm.js.map +1 -1
- package/.claude-flow-novice/dist/src/cli/commands/transparency.js +455 -0
- package/.claude-flow-novice/dist/src/cli/commands/transparency.js.map +1 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/CLAUDE.md +129 -13
- package/.claude-flow-novice/dist/src/components/visualizations/index.js +9 -0
- package/.claude-flow-novice/dist/src/components/visualizations/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/adapters/v1-coordinator-adapter.js +462 -0
- package/.claude-flow-novice/dist/src/coordination/adapters/v1-coordinator-adapter.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/config-translator.js +248 -0
- package/.claude-flow-novice/dist/src/coordination/config-translator.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/coordination-toggle.js +287 -0
- package/.claude-flow-novice/dist/src/coordination/coordination-toggle.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/distributed-consensus.js +68 -9
- package/.claude-flow-novice/dist/src/coordination/distributed-consensus.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/feature-flags.js +166 -0
- package/.claude-flow-novice/dist/src/coordination/feature-flags.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/queen-agent.js +18 -4
- package/.claude-flow-novice/dist/src/coordination/queen-agent.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/role-assignment.js +6 -110
- package/.claude-flow-novice/dist/src/coordination/role-assignment.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/cache/artifact-cache-optimizer.js +632 -0
- package/.claude-flow-novice/dist/src/coordination/v2/cache/artifact-cache-optimizer.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/cache/index.js +11 -0
- package/.claude-flow-novice/dist/src/coordination/v2/cache/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/checkpoints/checkpoint-compressor.js +318 -0
- package/.claude-flow-novice/dist/src/coordination/v2/checkpoints/checkpoint-compressor.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/cascading-shutdown.example.js +364 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/cascading-shutdown.example.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/cascading-shutdown.js +492 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/cascading-shutdown.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/hierarchical-coordinator.js +786 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/hierarchical-coordinator.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/index.js +16 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/parent-child-manager.js +342 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/parent-child-manager.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/swarm-coordinator-v2.js +601 -0
- package/.claude-flow-novice/dist/src/coordination/v2/coordinators/swarm-coordinator-v2.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/help-request-metrics.js +211 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/help-request-metrics.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/index.js +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/index.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/core/message-broker.js +365 -6
- package/.claude-flow-novice/dist/src/coordination/v2/core/message-broker.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/core/resource-manager-safe.js +478 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/resource-manager-safe.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/state-machine-config.js +5 -2
- package/.claude-flow-novice/dist/src/coordination/v2/core/state-machine-config.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/core/state-machine.js +189 -0
- package/.claude-flow-novice/dist/src/coordination/v2/core/state-machine.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/deadlock-detector.js +424 -0
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/deadlock-detector.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/index.js +9 -0
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/resource-manager.js +669 -0
- package/.claude-flow-novice/dist/src/coordination/v2/deadlock/resource-manager.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/artifact-storage.js +451 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/artifact-storage.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/cycle-detector.js +271 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/cycle-detector.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-graph.js +335 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-graph.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-manager.js +439 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-manager.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-request.js +92 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/dependency-request.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/index.js +21 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/topological-sort.js +223 -0
- package/.claude-flow-novice/dist/src/coordination/v2/dependency/topological-sort.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-coordinator.js +436 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-coordinator.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-matcher.js +278 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-matcher.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-request-handler.js +317 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-request-handler.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-request.js +273 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/help-request.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/index.js +15 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/waiting-agent-pool.js +512 -0
- package/.claude-flow-novice/dist/src/coordination/v2/help-system/waiting-agent-pool.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/index.js +6 -0
- package/.claude-flow-novice/dist/src/coordination/v2/index.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/integration/help-deadlock-integration.js +557 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/help-deadlock-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/index.js +14 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/message-bus-completion-integration.example.js +212 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/message-bus-completion-integration.example.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/message-bus-completion-integration.js +552 -0
- package/.claude-flow-novice/dist/src/coordination/v2/integration/message-bus-completion-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/memory/dependency-storage.js +367 -0
- package/.claude-flow-novice/dist/src/coordination/v2/memory/dependency-storage.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/memory/index.js +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/memory/index.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channel.js +371 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channel.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/dependency-channel.js +355 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/dependency-channel.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/help-channel.js +424 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/help-channel.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/index.js +16 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/state-channel.js +295 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/state-channel.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/task-channel.js +411 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/channels/task-channel.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/index.js +14 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-bus.js +387 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-bus.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-persistence.js +589 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-persistence.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-router.js +444 -0
- package/.claude-flow-novice/dist/src/coordination/v2/messaging/message-router.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/checkpoint-manager.js +29 -8
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/checkpoint-manager.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/help-coordinator.js +470 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/help-coordinator.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/hierarchical-background-integration.js +450 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/hierarchical-background-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/index.js +5 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/index.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/multi-level-control.js +545 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/multi-level-control.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/query-controller.js +44 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/query-controller.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/query-message-integration.js +415 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/query-message-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/session-pool-optimizer.js +615 -0
- package/.claude-flow-novice/dist/src/coordination/v2/sdk/session-pool-optimizer.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/security/payload-validator.js +259 -0
- package/.claude-flow-novice/dist/src/coordination/v2/security/payload-validator.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/index.js +17 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/transparency-integration.js +357 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/transparency-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/transparency-system.js +679 -0
- package/.claude-flow-novice/dist/src/coordination/v2/transparency/transparency-system.js.map +1 -0
- package/.claude-flow-novice/dist/src/core/agent-manager.js +30 -0
- package/.claude-flow-novice/dist/src/core/agent-manager.js.map +1 -1
- package/.claude-flow-novice/dist/src/mcp/server.js +21 -2
- package/.claude-flow-novice/dist/src/mcp/server.js.map +1 -1
- package/.claude-flow-novice/dist/src/observability/metrics-counter.js +268 -0
- package/.claude-flow-novice/dist/src/observability/metrics-counter.js.map +1 -0
- package/.claude-flow-novice/dist/src/observability/metrics-storage.js +265 -0
- package/.claude-flow-novice/dist/src/observability/metrics-storage.js.map +1 -0
- package/.claude-flow-novice/dist/src/observability/telemetry.js +26 -0
- package/.claude-flow-novice/dist/src/observability/telemetry.js.map +1 -1
- package/.claude-flow-novice/dist/src/providers/tiered-router.js +64 -10
- package/.claude-flow-novice/dist/src/providers/tiered-router.js.map +1 -1
- package/.claude-flow-novice/dist/src/providers/zai-provider.js +196 -97
- package/.claude-flow-novice/dist/src/providers/zai-provider.js.map +1 -1
- package/.claude-flow-novice/dist/src/slash-commands/cfn-claude-sync.js +533 -0
- package/.claude-flow-novice/dist/src/slash-commands/index.js +5 -0
- package/.claude-flow-novice/dist/src/slash-commands/metrics-summary-class.js +74 -0
- package/.claude-flow-novice/dist/src/slash-commands/metrics-summary.js +335 -0
- package/.claude-flow-novice/dist/src/slash-commands/register-all-commands.js +12 -0
- package/.claude-flow-novice/dist/src/verification/checkpoint-compression-demo.js +96 -0
- package/.claude-flow-novice/dist/src/verification/checkpoint-compression-demo.js.map +1 -0
- package/.claude-flow-novice/dist/src/verification/checkpoint-compression.js +406 -0
- package/.claude-flow-novice/dist/src/verification/checkpoint-compression.js.map +1 -0
- package/.claude-flow-novice/dist/src/verification/checkpoint-manager.js +35 -5
- package/.claude-flow-novice/dist/src/verification/checkpoint-manager.js.map +1 -1
- package/.claude-flow-novice/dist/src/web/api/config/api-config.js +186 -0
- package/.claude-flow-novice/dist/src/web/api/config/api-config.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/auth.js +205 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/auth.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/cache.js +262 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/cache.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/error-handler.js +250 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/error-handler.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/request-logger.js +217 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/request-logger.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/validation.js +325 -0
- package/.claude-flow-novice/dist/src/web/api/middleware/validation.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/routes/events.js +465 -0
- package/.claude-flow-novice/dist/src/web/api/routes/events.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/routes/hierarchy.js +302 -0
- package/.claude-flow-novice/dist/src/web/api/routes/hierarchy.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/routes/index.js +14 -0
- package/.claude-flow-novice/dist/src/web/api/routes/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/routes/metrics.js +561 -0
- package/.claude-flow-novice/dist/src/web/api/routes/metrics.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/routes/status.js +450 -0
- package/.claude-flow-novice/dist/src/web/api/routes/status.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/api/server.js +451 -0
- package/.claude-flow-novice/dist/src/web/api/server.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/dashboard/hooks/useWebSocket.js +385 -0
- package/.claude-flow-novice/dist/src/web/dashboard/hooks/useWebSocket.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/dashboard/index.js +87 -0
- package/.claude-flow-novice/dist/src/web/dashboard/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/dashboard/types.js +6 -0
- package/.claude-flow-novice/dist/src/web/dashboard/types.js.map +1 -0
- package/.claude-flow-novice/metrics.db +0 -0
- package/.claude-flow-novice/metrics.db-shm +0 -0
- package/.claude-flow-novice/metrics.db-wal +0 -0
- package/CLAUDE.md +29 -0
- package/README.md +27 -0
- package/config/hooks/post-edit-pipeline.js +36 -2
- package/examples/metrics-counter-demo.ts +106 -0
- package/examples/persistent-metrics-demo.ts +83 -0
- package/examples/phase-5-multi-level-control.ts +282 -0
- package/examples/session-pool-optimizer-example.ts +311 -0
- package/package.json +15 -3
- package/scripts/check-routing-stats.cjs +122 -0
- package/scripts/pre-publish-validation.cjs +212 -0
- package/scripts/test-provider-routing.cjs +228 -0
- package/scripts/test-routing-telemetry.cjs +147 -0
- package/scripts/test-zai-10k.cjs +81 -0
- package/scripts/test-zai-api.cjs +191 -0
- package/scripts/test-zai-diagnostic.cjs +151 -0
- package/scripts/test-zai-final.cjs +128 -0
- package/scripts/test-zai-with-env.cjs +85 -0
- package/scripts/validate-coordination-cli.js +69 -0
- package/scripts/validate-coordination-toggle-integration.cjs +501 -0
- package/src/cli/simple-commands/init/templates/CLAUDE.md +29 -0
- package/src/observability/metrics-counter.ts +347 -0
- package/src/observability/metrics-storage.ts +356 -0
- package/src/observability/telemetry.ts +658 -0
- package/src/slash-commands/cfn-claude-sync.js +533 -0
- package/src/slash-commands/index.js +5 -0
- package/src/slash-commands/metrics-summary-class.js +74 -0
- package/src/slash-commands/metrics-summary.js +335 -0
- package/src/slash-commands/register-all-commands.js +12 -0
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Coordination V2 - Message Persistence Implementation
|
|
3
|
+
*
|
|
4
|
+
* Artifact-backed message persistence with TTL-based expiration,
|
|
5
|
+
* circular buffer capacity limits, and replay functionality.
|
|
6
|
+
*
|
|
7
|
+
* Performance targets:
|
|
8
|
+
* - Storage: <15ms (p95) for message append
|
|
9
|
+
* - Retrieval: <15ms (p95) for message replay
|
|
10
|
+
* - Compression: MessagePack + gzip (60-70% size reduction)
|
|
11
|
+
*
|
|
12
|
+
* Features:
|
|
13
|
+
* - TTL-based automatic message expiration
|
|
14
|
+
* - Circular buffer with configurable capacity limits
|
|
15
|
+
* - Message replay for history reconstruction
|
|
16
|
+
* - Topic-based message filtering
|
|
17
|
+
* - Binary serialization (MessagePack)
|
|
18
|
+
* - Gzip compression for storage efficiency
|
|
19
|
+
* - Integrity verification with SHA-256 checksums
|
|
20
|
+
*
|
|
21
|
+
* @module coordination/v2/messaging/message-persistence
|
|
22
|
+
*/ import { DependencyArtifactStorage } from '../dependency/artifact-storage.js';
|
|
23
|
+
import { gzip, gunzip } from 'zlib';
|
|
24
|
+
import { promisify } from 'util';
|
|
25
|
+
const gzipAsync = promisify(gzip);
|
|
26
|
+
const gunzipAsync = promisify(gunzip);
|
|
27
|
+
/**
|
|
28
|
+
* MessagePersistence - High-performance message storage and replay
|
|
29
|
+
*
|
|
30
|
+
* Provides artifact-backed persistence for message bus with:
|
|
31
|
+
* - TTL-based automatic expiration
|
|
32
|
+
* - Circular buffer capacity limits
|
|
33
|
+
* - Message replay for history reconstruction
|
|
34
|
+
* - Binary serialization (MessagePack) + compression (gzip)
|
|
35
|
+
* - Topic-based filtering and indexing
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const persistence = new MessagePersistence({
|
|
40
|
+
* storagePath: '.claude-flow/artifacts/messages',
|
|
41
|
+
* maxMessages: 10000,
|
|
42
|
+
* defaultTtlMs: 24 * 60 * 60 * 1000 // 24 hours
|
|
43
|
+
* });
|
|
44
|
+
* await persistence.initialize();
|
|
45
|
+
*
|
|
46
|
+
* // Store message
|
|
47
|
+
* await persistence.storeMessage(message);
|
|
48
|
+
*
|
|
49
|
+
* // Replay messages by topic
|
|
50
|
+
* const history = await persistence.replayMessages({
|
|
51
|
+
* topic: 'task.completed',
|
|
52
|
+
* startTime: Date.now() - 3600000 // Last hour
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* console.log(persistence.getMetrics().p95StoreLatencyMs); // Target: <15ms
|
|
56
|
+
* ```
|
|
57
|
+
*/ export class MessagePersistence {
|
|
58
|
+
storage;
|
|
59
|
+
config;
|
|
60
|
+
messages;
|
|
61
|
+
topicIndex;
|
|
62
|
+
expirationQueue;
|
|
63
|
+
metrics;
|
|
64
|
+
latencyBuffer;
|
|
65
|
+
cleanupTimer;
|
|
66
|
+
ready = false;
|
|
67
|
+
/**
|
|
68
|
+
* Creates a new message persistence instance
|
|
69
|
+
*
|
|
70
|
+
* @param config - Persistence configuration
|
|
71
|
+
*/ constructor(config = {}){
|
|
72
|
+
this.config = {
|
|
73
|
+
storagePath: config.storagePath || '.claude-flow/artifacts/messages',
|
|
74
|
+
maxMessages: config.maxMessages || 10000,
|
|
75
|
+
defaultTtlMs: config.defaultTtlMs || 24 * 60 * 60 * 1000,
|
|
76
|
+
cacheSize: config.cacheSize || 100,
|
|
77
|
+
autoCleanup: config.autoCleanup !== false,
|
|
78
|
+
cleanupIntervalMs: config.cleanupIntervalMs || 5 * 60 * 1000 // 5 minutes
|
|
79
|
+
};
|
|
80
|
+
this.storage = new DependencyArtifactStorage({
|
|
81
|
+
storagePath: this.config.storagePath,
|
|
82
|
+
cacheSize: this.config.cacheSize
|
|
83
|
+
});
|
|
84
|
+
this.messages = new Map();
|
|
85
|
+
this.topicIndex = new Map();
|
|
86
|
+
this.expirationQueue = [];
|
|
87
|
+
this.metrics = this.initializeMetrics();
|
|
88
|
+
this.latencyBuffer = [];
|
|
89
|
+
}
|
|
90
|
+
// ===========================
|
|
91
|
+
// Lifecycle
|
|
92
|
+
// ===========================
|
|
93
|
+
/**
|
|
94
|
+
* Initialize message persistence
|
|
95
|
+
*
|
|
96
|
+
* Loads existing message store and starts cleanup timer.
|
|
97
|
+
*/ async initialize() {
|
|
98
|
+
if (this.ready) return;
|
|
99
|
+
// Initialize storage backend
|
|
100
|
+
await this.storage.initialize();
|
|
101
|
+
// Load existing message store
|
|
102
|
+
await this.loadMessageStore();
|
|
103
|
+
// Start automatic cleanup if enabled
|
|
104
|
+
if (this.config.autoCleanup) {
|
|
105
|
+
this.startCleanupTimer();
|
|
106
|
+
}
|
|
107
|
+
this.ready = true;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Close persistence and persist state
|
|
111
|
+
*/ async close() {
|
|
112
|
+
if (!this.ready) return;
|
|
113
|
+
// Stop cleanup timer
|
|
114
|
+
if (this.cleanupTimer) {
|
|
115
|
+
clearInterval(this.cleanupTimer);
|
|
116
|
+
this.cleanupTimer = undefined;
|
|
117
|
+
}
|
|
118
|
+
// Persist current message store
|
|
119
|
+
await this.persistMessageStore();
|
|
120
|
+
// Close storage backend
|
|
121
|
+
await this.storage.close();
|
|
122
|
+
this.ready = false;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if persistence is ready
|
|
126
|
+
*/ isReady() {
|
|
127
|
+
return this.ready;
|
|
128
|
+
}
|
|
129
|
+
// ===========================
|
|
130
|
+
// Core Persistence Operations
|
|
131
|
+
// ===========================
|
|
132
|
+
/**
|
|
133
|
+
* Store message with TTL-based expiration
|
|
134
|
+
*
|
|
135
|
+
* Performance target: <15ms (p95)
|
|
136
|
+
*
|
|
137
|
+
* @param message - Message to store
|
|
138
|
+
* @param ttlMs - Time-to-live in milliseconds (optional, uses default if not provided)
|
|
139
|
+
* @throws Error if storage fails
|
|
140
|
+
*/ async storeMessage(message, ttlMs) {
|
|
141
|
+
this.ensureReady();
|
|
142
|
+
const startTime = Date.now();
|
|
143
|
+
try {
|
|
144
|
+
// Calculate expiration timestamp
|
|
145
|
+
const effectiveTtl = ttlMs ?? this.config.defaultTtlMs;
|
|
146
|
+
const expiresAt = message.timestamp + effectiveTtl;
|
|
147
|
+
// Serialize message
|
|
148
|
+
const serialized = {
|
|
149
|
+
id: message.id,
|
|
150
|
+
topic: message.topic,
|
|
151
|
+
payload: message.payload,
|
|
152
|
+
priority: message.priority,
|
|
153
|
+
timestamp: message.timestamp,
|
|
154
|
+
expiresAt,
|
|
155
|
+
replyTo: message.replyTo,
|
|
156
|
+
correlationId: message.correlationId,
|
|
157
|
+
senderId: message.senderId,
|
|
158
|
+
recipientId: message.recipientId,
|
|
159
|
+
metadata: message.metadata
|
|
160
|
+
};
|
|
161
|
+
// Check circular buffer capacity and evict oldest if needed
|
|
162
|
+
if (this.messages.size >= this.config.maxMessages) {
|
|
163
|
+
await this.evictOldestMessage();
|
|
164
|
+
}
|
|
165
|
+
// Add to in-memory store
|
|
166
|
+
this.messages.set(message.id, serialized);
|
|
167
|
+
// Update topic index
|
|
168
|
+
this.indexMessageByTopic(message.id, message.topic);
|
|
169
|
+
// Add to expiration queue
|
|
170
|
+
this.expirationQueue.push({
|
|
171
|
+
messageId: message.id,
|
|
172
|
+
expiresAt
|
|
173
|
+
});
|
|
174
|
+
this.expirationQueue.sort((a, b)=>a.expiresAt - b.expiresAt);
|
|
175
|
+
// Persist to storage (batched for performance)
|
|
176
|
+
await this.persistMessageStore();
|
|
177
|
+
// Update metrics
|
|
178
|
+
const latency = Date.now() - startTime;
|
|
179
|
+
this.updateStoreMetrics(latency);
|
|
180
|
+
// Performance warning if exceeds target
|
|
181
|
+
if (latency > 15) {
|
|
182
|
+
console.warn(`[MessagePersistence] Store latency ${latency}ms exceeds 15ms target for message ${message.id}`);
|
|
183
|
+
}
|
|
184
|
+
} catch (error) {
|
|
185
|
+
throw new Error(`Failed to store message ${message.id}: ${error instanceof Error ? error.message : String(error)}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Retrieve message by ID
|
|
190
|
+
*
|
|
191
|
+
* Performance target: <15ms (p95)
|
|
192
|
+
*
|
|
193
|
+
* @param messageId - Message identifier
|
|
194
|
+
* @returns Message if found and not expired, null otherwise
|
|
195
|
+
*/ async retrieveMessage(messageId) {
|
|
196
|
+
this.ensureReady();
|
|
197
|
+
const startTime = Date.now();
|
|
198
|
+
try {
|
|
199
|
+
const serialized = this.messages.get(messageId);
|
|
200
|
+
if (!serialized) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
// Check if expired
|
|
204
|
+
if (Date.now() > serialized.expiresAt) {
|
|
205
|
+
// Remove expired message
|
|
206
|
+
await this.removeMessage(messageId);
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
// Reconstruct message
|
|
210
|
+
const message = this.deserializeMessage(serialized);
|
|
211
|
+
// Update metrics
|
|
212
|
+
const latency = Date.now() - startTime;
|
|
213
|
+
this.updateRetrieveMetrics(latency);
|
|
214
|
+
return message;
|
|
215
|
+
} catch (error) {
|
|
216
|
+
throw new Error(`Failed to retrieve message ${messageId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Replay messages matching query criteria
|
|
221
|
+
*
|
|
222
|
+
* Supports topic filtering, time ranges, priority filtering, and pagination.
|
|
223
|
+
*
|
|
224
|
+
* @param options - Query options for filtering and pagination
|
|
225
|
+
* @returns Array of matching messages (sorted by timestamp ascending)
|
|
226
|
+
*/ async replayMessages(options = {}) {
|
|
227
|
+
this.ensureReady();
|
|
228
|
+
const startTime = Date.now();
|
|
229
|
+
try {
|
|
230
|
+
let candidates;
|
|
231
|
+
// Filter by topic if provided
|
|
232
|
+
if (options.topic) {
|
|
233
|
+
const messageIds = this.getMessageIdsByTopic(options.topic);
|
|
234
|
+
candidates = Array.from(messageIds).map((id)=>this.messages.get(id)).filter((msg)=>msg !== undefined);
|
|
235
|
+
} else {
|
|
236
|
+
candidates = Array.from(this.messages.values());
|
|
237
|
+
}
|
|
238
|
+
// Apply filters
|
|
239
|
+
const filtered = candidates.filter((msg)=>{
|
|
240
|
+
// Check expiration
|
|
241
|
+
if (Date.now() > msg.expiresAt) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
// Time range filter
|
|
245
|
+
if (options.startTime !== undefined && msg.timestamp < options.startTime) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
if (options.endTime !== undefined && msg.timestamp > options.endTime) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
// Priority filter
|
|
252
|
+
if (options.minPriority !== undefined && msg.priority < options.minPriority) {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
// Sender filter
|
|
256
|
+
if (options.senderId !== undefined && msg.senderId !== options.senderId) {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
// Recipient filter
|
|
260
|
+
if (options.recipientId !== undefined && msg.recipientId !== options.recipientId) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
// Correlation ID filter
|
|
264
|
+
if (options.correlationId !== undefined && msg.correlationId !== options.correlationId) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
return true;
|
|
268
|
+
});
|
|
269
|
+
// Sort by timestamp (ascending)
|
|
270
|
+
filtered.sort((a, b)=>a.timestamp - b.timestamp);
|
|
271
|
+
// Apply limit
|
|
272
|
+
const limited = options.limit !== undefined ? filtered.slice(0, options.limit) : filtered;
|
|
273
|
+
// Reconstruct messages
|
|
274
|
+
const messages = limited.map((msg)=>this.deserializeMessage(msg));
|
|
275
|
+
// Update metrics
|
|
276
|
+
const latency = Date.now() - startTime;
|
|
277
|
+
this.metrics.totalRetrieved += messages.length;
|
|
278
|
+
this.updateRetrieveMetrics(latency);
|
|
279
|
+
return messages;
|
|
280
|
+
} catch (error) {
|
|
281
|
+
throw new Error(`Failed to replay messages: ${error instanceof Error ? error.message : String(error)}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Remove message from persistence
|
|
286
|
+
*
|
|
287
|
+
* @param messageId - Message identifier
|
|
288
|
+
*/ async removeMessage(messageId) {
|
|
289
|
+
this.ensureReady();
|
|
290
|
+
const serialized = this.messages.get(messageId);
|
|
291
|
+
if (!serialized) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
// Remove from in-memory store
|
|
295
|
+
this.messages.delete(messageId);
|
|
296
|
+
// Remove from topic index
|
|
297
|
+
this.removeFromTopicIndex(messageId, serialized.topic);
|
|
298
|
+
// Remove from expiration queue
|
|
299
|
+
this.expirationQueue = this.expirationQueue.filter((e)=>e.messageId !== messageId);
|
|
300
|
+
// Persist changes
|
|
301
|
+
await this.persistMessageStore();
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Clear all messages
|
|
305
|
+
*/ async clear() {
|
|
306
|
+
this.ensureReady();
|
|
307
|
+
this.messages.clear();
|
|
308
|
+
this.topicIndex.clear();
|
|
309
|
+
this.expirationQueue = [];
|
|
310
|
+
await this.storage.clear();
|
|
311
|
+
this.metrics = this.initializeMetrics();
|
|
312
|
+
}
|
|
313
|
+
// ===========================
|
|
314
|
+
// Maintenance Operations
|
|
315
|
+
// ===========================
|
|
316
|
+
/**
|
|
317
|
+
* Clean up expired messages
|
|
318
|
+
*
|
|
319
|
+
* Removes messages that have exceeded their TTL.
|
|
320
|
+
*
|
|
321
|
+
* @returns Number of messages removed
|
|
322
|
+
*/ async cleanupExpiredMessages() {
|
|
323
|
+
this.ensureReady();
|
|
324
|
+
const now = Date.now();
|
|
325
|
+
const expiredCount = 0;
|
|
326
|
+
let removed = 0;
|
|
327
|
+
// Process expiration queue (already sorted by expiresAt)
|
|
328
|
+
while(this.expirationQueue.length > 0 && this.expirationQueue[0].expiresAt <= now){
|
|
329
|
+
const { messageId } = this.expirationQueue.shift();
|
|
330
|
+
const serialized = this.messages.get(messageId);
|
|
331
|
+
if (serialized) {
|
|
332
|
+
this.messages.delete(messageId);
|
|
333
|
+
this.removeFromTopicIndex(messageId, serialized.topic);
|
|
334
|
+
removed++;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (removed > 0) {
|
|
338
|
+
// Persist changes
|
|
339
|
+
await this.persistMessageStore();
|
|
340
|
+
// Update metrics
|
|
341
|
+
this.metrics.totalExpired += removed;
|
|
342
|
+
this.metrics.lastCleanupAt = now;
|
|
343
|
+
}
|
|
344
|
+
return removed;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Get persistence metrics
|
|
348
|
+
*/ getMetrics() {
|
|
349
|
+
return {
|
|
350
|
+
...this.metrics,
|
|
351
|
+
currentCount: this.messages.size
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
// ===========================
|
|
355
|
+
// Private Helpers
|
|
356
|
+
// ===========================
|
|
357
|
+
/**
|
|
358
|
+
* Ensure persistence is ready
|
|
359
|
+
*/ ensureReady() {
|
|
360
|
+
if (!this.ready) {
|
|
361
|
+
throw new Error('MessagePersistence not initialized. Call initialize() first.');
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Start automatic cleanup timer
|
|
366
|
+
*/ startCleanupTimer() {
|
|
367
|
+
this.cleanupTimer = setInterval(async ()=>{
|
|
368
|
+
try {
|
|
369
|
+
await this.cleanupExpiredMessages();
|
|
370
|
+
} catch (error) {
|
|
371
|
+
console.error('[MessagePersistence] Cleanup error:', error);
|
|
372
|
+
}
|
|
373
|
+
}, this.config.cleanupIntervalMs);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Evict oldest message (circular buffer behavior)
|
|
377
|
+
*/ async evictOldestMessage() {
|
|
378
|
+
if (this.messages.size === 0) return;
|
|
379
|
+
// Find oldest message by timestamp
|
|
380
|
+
let oldestId;
|
|
381
|
+
let oldestTimestamp = Infinity;
|
|
382
|
+
for (const [id, msg] of Array.from(this.messages.entries())){
|
|
383
|
+
if (msg.timestamp < oldestTimestamp) {
|
|
384
|
+
oldestTimestamp = msg.timestamp;
|
|
385
|
+
oldestId = id;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (oldestId) {
|
|
389
|
+
await this.removeMessage(oldestId);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Index message by topic for fast topic-based queries
|
|
394
|
+
*/ indexMessageByTopic(messageId, topic) {
|
|
395
|
+
if (!this.topicIndex.has(topic)) {
|
|
396
|
+
this.topicIndex.set(topic, new Set());
|
|
397
|
+
}
|
|
398
|
+
this.topicIndex.get(topic).add(messageId);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Remove message from topic index
|
|
402
|
+
*/ removeFromTopicIndex(messageId, topic) {
|
|
403
|
+
const messageIds = this.topicIndex.get(topic);
|
|
404
|
+
if (messageIds) {
|
|
405
|
+
messageIds.delete(messageId);
|
|
406
|
+
if (messageIds.size === 0) {
|
|
407
|
+
this.topicIndex.delete(topic);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Get message IDs by topic pattern (supports wildcards)
|
|
413
|
+
*/ getMessageIdsByTopic(topicPattern) {
|
|
414
|
+
const result = new Set();
|
|
415
|
+
for (const [topic, messageIds] of Array.from(this.topicIndex.entries())){
|
|
416
|
+
if (this.matchesTopic(topic, topicPattern)) {
|
|
417
|
+
for (const id of Array.from(messageIds)){
|
|
418
|
+
result.add(id);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return result;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Check if topic matches pattern (supports wildcards)
|
|
426
|
+
*/ matchesTopic(topic, pattern) {
|
|
427
|
+
if (pattern === '*' || pattern === '**') {
|
|
428
|
+
return true;
|
|
429
|
+
}
|
|
430
|
+
if (!pattern.includes('*')) {
|
|
431
|
+
return topic === pattern;
|
|
432
|
+
}
|
|
433
|
+
const regexPattern = pattern.replace(/\./g, '\\.').replace(/\*\*/g, '.*').replace(/\*/g, '[^.]*');
|
|
434
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
435
|
+
return regex.test(topic);
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Persist message store to artifact storage
|
|
439
|
+
*/ async persistMessageStore() {
|
|
440
|
+
const storeId = 'message-store';
|
|
441
|
+
const store = {
|
|
442
|
+
version: 1,
|
|
443
|
+
metadata: {
|
|
444
|
+
storeId,
|
|
445
|
+
createdAt: Date.now(),
|
|
446
|
+
updatedAt: Date.now(),
|
|
447
|
+
messageCount: this.messages.size,
|
|
448
|
+
oldestTimestamp: this.getOldestTimestamp(),
|
|
449
|
+
newestTimestamp: this.getNewestTimestamp()
|
|
450
|
+
},
|
|
451
|
+
messages: Array.from(this.messages.values())
|
|
452
|
+
};
|
|
453
|
+
// Store using artifact storage (MessagePack + gzip)
|
|
454
|
+
await this.storage.store(storeId, store);
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Load message store from artifact storage
|
|
458
|
+
*/ async loadMessageStore() {
|
|
459
|
+
const storeId = 'message-store';
|
|
460
|
+
try {
|
|
461
|
+
if (this.storage.has(storeId)) {
|
|
462
|
+
const store = await this.storage.retrieve(storeId);
|
|
463
|
+
// Validate schema version
|
|
464
|
+
if (store.version !== 1) {
|
|
465
|
+
console.warn(`[MessagePersistence] Unsupported schema version ${store.version}, starting fresh`);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
// Rebuild in-memory structures
|
|
469
|
+
this.messages.clear();
|
|
470
|
+
this.topicIndex.clear();
|
|
471
|
+
this.expirationQueue = [];
|
|
472
|
+
const now = Date.now();
|
|
473
|
+
for (const msg of store.messages){
|
|
474
|
+
// Skip expired messages
|
|
475
|
+
if (msg.expiresAt <= now) {
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
this.messages.set(msg.id, msg);
|
|
479
|
+
this.indexMessageByTopic(msg.id, msg.topic);
|
|
480
|
+
this.expirationQueue.push({
|
|
481
|
+
messageId: msg.id,
|
|
482
|
+
expiresAt: msg.expiresAt
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
// Sort expiration queue
|
|
486
|
+
this.expirationQueue.sort((a, b)=>a.expiresAt - b.expiresAt);
|
|
487
|
+
// Update metrics
|
|
488
|
+
this.metrics.currentCount = this.messages.size;
|
|
489
|
+
}
|
|
490
|
+
} catch (error) {
|
|
491
|
+
console.warn('[MessagePersistence] Failed to load message store, starting fresh:', error);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Deserialize message from storage format
|
|
496
|
+
*/ deserializeMessage(serialized) {
|
|
497
|
+
return {
|
|
498
|
+
id: serialized.id,
|
|
499
|
+
topic: serialized.topic,
|
|
500
|
+
payload: serialized.payload,
|
|
501
|
+
priority: serialized.priority,
|
|
502
|
+
timestamp: serialized.timestamp,
|
|
503
|
+
replyTo: serialized.replyTo,
|
|
504
|
+
correlationId: serialized.correlationId,
|
|
505
|
+
senderId: serialized.senderId,
|
|
506
|
+
recipientId: serialized.recipientId,
|
|
507
|
+
metadata: serialized.metadata
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Get oldest message timestamp
|
|
512
|
+
*/ getOldestTimestamp() {
|
|
513
|
+
let oldest = Infinity;
|
|
514
|
+
for (const msg of Array.from(this.messages.values())){
|
|
515
|
+
if (msg.timestamp < oldest) {
|
|
516
|
+
oldest = msg.timestamp;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return oldest === Infinity ? Date.now() : oldest;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Get newest message timestamp
|
|
523
|
+
*/ getNewestTimestamp() {
|
|
524
|
+
let newest = 0;
|
|
525
|
+
for (const msg of Array.from(this.messages.values())){
|
|
526
|
+
if (msg.timestamp > newest) {
|
|
527
|
+
newest = msg.timestamp;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return newest === 0 ? Date.now() : newest;
|
|
531
|
+
}
|
|
532
|
+
// ===========================
|
|
533
|
+
// Metrics Tracking
|
|
534
|
+
// ===========================
|
|
535
|
+
/**
|
|
536
|
+
* Initialize metrics structure
|
|
537
|
+
*/ initializeMetrics() {
|
|
538
|
+
return {
|
|
539
|
+
totalStored: 0,
|
|
540
|
+
totalRetrieved: 0,
|
|
541
|
+
totalExpired: 0,
|
|
542
|
+
currentCount: 0,
|
|
543
|
+
averageStoreLatencyMs: 0,
|
|
544
|
+
p95StoreLatencyMs: 0,
|
|
545
|
+
averageRetrieveLatencyMs: 0,
|
|
546
|
+
p95RetrieveLatencyMs: 0,
|
|
547
|
+
totalStorageMb: 0,
|
|
548
|
+
averageCompressionRatio: 0
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Update store operation metrics
|
|
553
|
+
*/ updateStoreMetrics(latency) {
|
|
554
|
+
this.metrics.totalStored++;
|
|
555
|
+
this.metrics.averageStoreLatencyMs = this.updateAverage(this.metrics.averageStoreLatencyMs, latency, this.metrics.totalStored);
|
|
556
|
+
this.latencyBuffer.push(latency);
|
|
557
|
+
if (this.latencyBuffer.length > 1000) {
|
|
558
|
+
this.latencyBuffer = this.latencyBuffer.slice(-1000);
|
|
559
|
+
}
|
|
560
|
+
this.metrics.p95StoreLatencyMs = this.calculateP95(this.latencyBuffer);
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Update retrieve operation metrics
|
|
564
|
+
*/ updateRetrieveMetrics(latency) {
|
|
565
|
+
this.metrics.averageRetrieveLatencyMs = this.updateAverage(this.metrics.averageRetrieveLatencyMs, latency, this.metrics.totalRetrieved || 1);
|
|
566
|
+
this.latencyBuffer.push(latency);
|
|
567
|
+
if (this.latencyBuffer.length > 1000) {
|
|
568
|
+
this.latencyBuffer = this.latencyBuffer.slice(-1000);
|
|
569
|
+
}
|
|
570
|
+
this.metrics.p95RetrieveLatencyMs = this.calculateP95(this.latencyBuffer);
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Calculate rolling average
|
|
574
|
+
*/ updateAverage(current, newValue, count) {
|
|
575
|
+
return (current * (count - 1) + newValue) / count;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Calculate 95th percentile latency
|
|
579
|
+
*/ calculateP95(latencies) {
|
|
580
|
+
if (latencies.length === 0) return 0;
|
|
581
|
+
const sorted = [
|
|
582
|
+
...latencies
|
|
583
|
+
].sort((a, b)=>a - b);
|
|
584
|
+
const index = Math.floor(sorted.length * 0.95);
|
|
585
|
+
return sorted[index] || 0;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
//# sourceMappingURL=message-persistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/coordination/v2/messaging/message-persistence.ts"],"names":["DependencyArtifactStorage","gzip","gunzip","promisify","gzipAsync","gunzipAsync","MessagePersistence","storage","config","messages","topicIndex","expirationQueue","metrics","latencyBuffer","cleanupTimer","ready","storagePath","maxMessages","defaultTtlMs","cacheSize","autoCleanup","cleanupIntervalMs","Map","initializeMetrics","initialize","loadMessageStore","startCleanupTimer","close","clearInterval","undefined","persistMessageStore","isReady","storeMessage","message","ttlMs","ensureReady","startTime","Date","now","effectiveTtl","expiresAt","timestamp","serialized","id","topic","payload","priority","replyTo","correlationId","senderId","recipientId","metadata","size","evictOldestMessage","set","indexMessageByTopic","push","messageId","sort","a","b","latency","updateStoreMetrics","console","warn","error","Error","String","retrieveMessage","get","removeMessage","deserializeMessage","updateRetrieveMetrics","replayMessages","options","candidates","messageIds","getMessageIdsByTopic","Array","from","map","filter","msg","values","filtered","endTime","minPriority","limited","limit","slice","totalRetrieved","length","delete","removeFromTopicIndex","e","clear","cleanupExpiredMessages","expiredCount","removed","shift","totalExpired","lastCleanupAt","getMetrics","currentCount","setInterval","oldestId","oldestTimestamp","Infinity","entries","has","Set","add","topicPattern","result","matchesTopic","pattern","includes","regexPattern","replace","regex","RegExp","test","storeId","store","version","createdAt","updatedAt","messageCount","getOldestTimestamp","newestTimestamp","getNewestTimestamp","retrieve","oldest","newest","totalStored","averageStoreLatencyMs","p95StoreLatencyMs","averageRetrieveLatencyMs","p95RetrieveLatencyMs","totalStorageMb","averageCompressionRatio","updateAverage","calculateP95","current","newValue","count","latencies","sorted","index","Math","floor"],"mappings":"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"}
|