specweave 0.18.1 → 0.20.0
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.md +229 -1817
- package/README.md +68 -0
- package/bin/specweave.js +62 -6
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.d.ts.map +1 -1
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.js +3 -0
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.js.map +1 -1
- package/dist/plugins/specweave/lib/hooks/update-ac-status.d.ts +21 -0
- package/dist/plugins/specweave/lib/hooks/update-ac-status.d.ts.map +1 -0
- package/dist/plugins/specweave/lib/hooks/update-ac-status.js +162 -0
- package/dist/plugins/specweave/lib/hooks/update-ac-status.js.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js +65 -6
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/completion-calculator.d.ts +112 -0
- package/dist/plugins/specweave-github/lib/completion-calculator.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/completion-calculator.js +301 -0
- package/dist/plugins/specweave-github/lib/completion-calculator.js.map +1 -0
- package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts +3 -3
- package/dist/plugins/specweave-github/lib/duplicate-detector.js +3 -3
- package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts +7 -0
- package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/epic-content-builder.js +42 -0
- package/dist/plugins/specweave-github/lib/epic-content-builder.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +14 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +51 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-epic-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/github-epic-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts +87 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.js +412 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +64 -13
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/progress-comment-builder.d.ts +78 -0
- package/dist/plugins/specweave-github/lib/progress-comment-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js +237 -0
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.d.ts +97 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.js +301 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.js.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts +83 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js +386 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts +8 -6
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js +78 -117
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js.map +1 -1
- package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.d.ts +57 -0
- package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.js +248 -0
- package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.js.map +1 -0
- package/dist/plugins/specweave-kafka/lib/cli/types.d.ts +82 -0
- package/dist/plugins/specweave-kafka/lib/cli/types.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/cli/types.js +13 -0
- package/dist/plugins/specweave-kafka/lib/cli/types.js.map +1 -0
- package/dist/plugins/specweave-kafka/lib/mcp/detector.d.ts +49 -0
- package/dist/plugins/specweave-kafka/lib/mcp/detector.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/mcp/detector.js +316 -0
- package/dist/plugins/specweave-kafka/lib/mcp/detector.js.map +1 -0
- package/dist/plugins/specweave-kafka/lib/mcp/types.d.ts +70 -0
- package/dist/plugins/specweave-kafka/lib/mcp/types.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/mcp/types.js +23 -0
- package/dist/plugins/specweave-kafka/lib/mcp/types.js.map +1 -0
- package/dist/plugins/specweave-kafka/lib/utils/partitioning.d.ts +85 -0
- package/dist/plugins/specweave-kafka/lib/utils/partitioning.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/utils/partitioning.js +281 -0
- package/dist/plugins/specweave-kafka/lib/utils/partitioning.js.map +1 -0
- package/dist/plugins/specweave-kafka/lib/utils/sizing.d.ts +75 -0
- package/dist/plugins/specweave-kafka/lib/utils/sizing.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/utils/sizing.js +238 -0
- package/dist/plugins/specweave-kafka/lib/utils/sizing.js.map +1 -0
- package/dist/src/cli/commands/import-docs.js +4 -4
- package/dist/src/cli/commands/import-docs.js.map +1 -1
- package/dist/src/cli/commands/init-multiproject.d.ts.map +1 -1
- package/dist/src/cli/commands/init-multiproject.js +17 -18
- package/dist/src/cli/commands/init-multiproject.js.map +1 -1
- package/dist/src/cli/commands/migrate-to-multiproject.d.ts.map +1 -1
- package/dist/src/cli/commands/migrate-to-multiproject.js +8 -4
- package/dist/src/cli/commands/migrate-to-multiproject.js.map +1 -1
- package/dist/src/cli/commands/switch-project.d.ts.map +1 -1
- package/dist/src/cli/commands/switch-project.js +9 -26
- package/dist/src/cli/commands/switch-project.js.map +1 -1
- package/dist/src/cli/commands/sync-spec-content.js +3 -0
- package/dist/src/cli/commands/sync-spec-content.js.map +1 -1
- package/dist/src/core/deduplication/command-deduplicator.d.ts +166 -0
- package/dist/src/core/deduplication/command-deduplicator.d.ts.map +1 -0
- package/dist/src/core/deduplication/command-deduplicator.js +254 -0
- package/dist/src/core/deduplication/command-deduplicator.js.map +1 -0
- package/dist/src/core/increment/active-increment-manager.d.ts +42 -15
- package/dist/src/core/increment/active-increment-manager.d.ts.map +1 -1
- package/dist/src/core/increment/active-increment-manager.js +113 -46
- package/dist/src/core/increment/active-increment-manager.js.map +1 -1
- package/dist/src/core/increment/conflict-resolver.d.ts +40 -0
- package/dist/src/core/increment/conflict-resolver.d.ts.map +1 -0
- package/dist/src/core/increment/conflict-resolver.js +219 -0
- package/dist/src/core/increment/conflict-resolver.js.map +1 -0
- package/dist/src/core/increment/discipline-checker.d.ts.map +1 -1
- package/dist/src/core/increment/discipline-checker.js +7 -1
- package/dist/src/core/increment/discipline-checker.js.map +1 -1
- package/dist/src/core/increment/duplicate-detector.d.ts +52 -0
- package/dist/src/core/increment/duplicate-detector.d.ts.map +1 -0
- package/dist/src/core/increment/duplicate-detector.js +276 -0
- package/dist/src/core/increment/duplicate-detector.js.map +1 -0
- package/dist/src/core/increment/increment-archiver.d.ts +90 -0
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -0
- package/dist/src/core/increment/increment-archiver.js +368 -0
- package/dist/src/core/increment/increment-archiver.js.map +1 -0
- package/dist/src/core/increment/increment-reopener.d.ts +165 -0
- package/dist/src/core/increment/increment-reopener.d.ts.map +1 -0
- package/dist/src/core/increment/increment-reopener.js +390 -0
- package/dist/src/core/increment/increment-reopener.js.map +1 -0
- package/dist/src/core/increment/metadata-manager.d.ts +26 -1
- package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
- package/dist/src/core/increment/metadata-manager.js +143 -5
- package/dist/src/core/increment/metadata-manager.js.map +1 -1
- package/dist/src/core/increment/recent-work-scanner.d.ts +121 -0
- package/dist/src/core/increment/recent-work-scanner.d.ts.map +1 -0
- package/dist/src/core/increment/recent-work-scanner.js +303 -0
- package/dist/src/core/increment/recent-work-scanner.js.map +1 -0
- package/dist/src/core/increment/types.d.ts +1 -0
- package/dist/src/core/increment/types.d.ts.map +1 -1
- package/dist/src/core/increment-utils.d.ts +112 -0
- package/dist/src/core/increment-utils.d.ts.map +1 -0
- package/dist/src/core/increment-utils.js +210 -0
- package/dist/src/core/increment-utils.js.map +1 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.d.ts +65 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.js +175 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.js.map +1 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts +130 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -0
- package/dist/src/core/living-docs/feature-archiver.js +549 -0
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -0
- package/dist/src/core/living-docs/feature-id-manager.d.ts +81 -0
- package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -0
- package/dist/src/core/living-docs/feature-id-manager.js +339 -0
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -0
- package/dist/src/core/living-docs/hierarchy-mapper.d.ts +144 -83
- package/dist/src/core/living-docs/hierarchy-mapper.d.ts.map +1 -1
- package/dist/src/core/living-docs/hierarchy-mapper.js +488 -270
- package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
- package/dist/src/core/living-docs/index.d.ts +6 -0
- package/dist/src/core/living-docs/index.d.ts.map +1 -1
- package/dist/src/core/living-docs/index.js +6 -0
- package/dist/src/core/living-docs/index.js.map +1 -1
- package/dist/src/core/living-docs/project-detector.d.ts +6 -0
- package/dist/src/core/living-docs/project-detector.d.ts.map +1 -1
- package/dist/src/core/living-docs/project-detector.js +35 -1
- package/dist/src/core/living-docs/project-detector.js.map +1 -1
- package/dist/src/core/living-docs/spec-distributor.d.ts +100 -26
- package/dist/src/core/living-docs/spec-distributor.d.ts.map +1 -1
- package/dist/src/core/living-docs/spec-distributor.js +1275 -258
- package/dist/src/core/living-docs/spec-distributor.js.map +1 -1
- package/dist/src/core/living-docs/task-project-specific-generator.d.ts +109 -0
- package/dist/src/core/living-docs/task-project-specific-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/task-project-specific-generator.js +221 -0
- package/dist/src/core/living-docs/task-project-specific-generator.js.map +1 -0
- package/dist/src/core/living-docs/types.d.ts +143 -0
- package/dist/src/core/living-docs/types.d.ts.map +1 -1
- package/dist/src/core/project-manager.d.ts +2 -17
- package/dist/src/core/project-manager.d.ts.map +1 -1
- package/dist/src/core/project-manager.js +68 -48
- package/dist/src/core/project-manager.js.map +1 -1
- package/dist/src/core/spec-content-sync.d.ts +1 -1
- package/dist/src/core/spec-content-sync.d.ts.map +1 -1
- package/dist/src/core/sync/enhanced-content-builder.d.ts.map +1 -1
- package/dist/src/core/sync/enhanced-content-builder.js +2 -1
- package/dist/src/core/sync/enhanced-content-builder.js.map +1 -1
- package/dist/src/core/sync/performance-optimizer.d.ts +153 -0
- package/dist/src/core/sync/performance-optimizer.d.ts.map +1 -0
- package/dist/src/core/sync/performance-optimizer.js +220 -0
- package/dist/src/core/sync/performance-optimizer.js.map +1 -0
- package/dist/src/core/sync/retry-handler.d.ts +98 -0
- package/dist/src/core/sync/retry-handler.d.ts.map +1 -0
- package/dist/src/core/sync/retry-handler.js +196 -0
- package/dist/src/core/sync/retry-handler.js.map +1 -0
- package/dist/src/core/types/config.d.ts +94 -0
- package/dist/src/core/types/config.d.ts.map +1 -1
- package/dist/src/core/types/config.js +16 -0
- package/dist/src/core/types/config.js.map +1 -1
- package/dist/src/core/types/increment-metadata.d.ts +6 -0
- package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
- package/dist/src/core/types/increment-metadata.js +10 -1
- package/dist/src/core/types/increment-metadata.js.map +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.js +4 -8
- package/dist/src/integrations/jira/jira-incremental-mapper.js.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.js +4 -8
- package/dist/src/integrations/jira/jira-mapper.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/COMMANDS.md +13 -4
- package/plugins/specweave/commands/specweave-abandon.md +22 -20
- package/plugins/specweave/commands/specweave-archive-features.md +121 -0
- package/plugins/specweave/commands/specweave-archive-increments.md +82 -0
- package/plugins/specweave/commands/specweave-archive.md +363 -0
- package/plugins/specweave/commands/specweave-backlog.md +211 -0
- package/plugins/specweave/commands/specweave-fix-duplicates.md +517 -0
- package/plugins/specweave/commands/specweave-increment.md +4 -3
- package/plugins/specweave/commands/specweave-progress.md +176 -27
- package/plugins/specweave/commands/specweave-reopen.md +391 -0
- package/plugins/specweave/commands/specweave-restore-feature.md +90 -0
- package/plugins/specweave/commands/specweave-restore.md +309 -0
- package/plugins/specweave/commands/specweave-resume.md +51 -23
- package/plugins/specweave/commands/specweave-status.md +41 -7
- package/plugins/specweave/commands/specweave-sync-specs.md +425 -0
- package/plugins/specweave/hooks/hooks.json +4 -0
- package/plugins/specweave/hooks/lib/sync-spec-content.sh +2 -2
- package/plugins/specweave/hooks/post-task-completion.sh +39 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh +83 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh +1 -1
- package/plugins/specweave/lib/hooks/sync-living-docs.js +2 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.ts +4 -0
- package/plugins/specweave/lib/hooks/update-ac-status.js +102 -0
- package/plugins/specweave/lib/hooks/update-ac-status.ts +192 -0
- package/plugins/specweave/skills/archive-increments/SKILL.md +198 -0
- package/plugins/specweave/skills/increment-planner/scripts/feature-utils.js +14 -0
- package/plugins/specweave/skills/smart-reopen-detector/SKILL.md +244 -0
- package/plugins/specweave-ado/lib/ado-spec-content-sync.js +49 -5
- package/plugins/specweave-ado/lib/ado-spec-content-sync.ts +72 -6
- package/plugins/specweave-confluent/.claude-plugin/plugin.json +23 -0
- package/plugins/specweave-confluent/README.md +375 -0
- package/plugins/specweave-confluent/agents/confluent-architect/AGENT.md +306 -0
- package/plugins/specweave-confluent/skills/confluent-kafka-connect/SKILL.md +453 -0
- package/plugins/specweave-confluent/skills/confluent-ksqldb/SKILL.md +470 -0
- package/plugins/specweave-confluent/skills/confluent-schema-registry/SKILL.md +316 -0
- package/plugins/specweave-github/agents/github-task-splitter/AGENT.md +2 -2
- package/plugins/specweave-github/agents/user-story-updater/AGENT.md +148 -0
- package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +1 -1
- package/plugins/specweave-github/commands/specweave-github-update-user-story.md +156 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +10 -9
- package/plugins/specweave-github/lib/completion-calculator.js +262 -0
- package/plugins/specweave-github/lib/completion-calculator.ts +434 -0
- package/plugins/specweave-github/lib/duplicate-detector.js +3 -3
- package/plugins/specweave-github/lib/duplicate-detector.ts +4 -4
- package/plugins/specweave-github/lib/epic-content-builder.js +38 -0
- package/plugins/specweave-github/lib/epic-content-builder.ts +59 -0
- package/plugins/specweave-github/lib/github-client-v2.js +49 -0
- package/plugins/specweave-github/lib/github-client-v2.ts +59 -0
- package/plugins/specweave-github/lib/github-epic-sync.ts +1 -1
- package/plugins/specweave-github/lib/github-feature-sync.js +381 -0
- package/plugins/specweave-github/lib/github-feature-sync.ts +568 -0
- package/plugins/specweave-github/lib/github-spec-content-sync.js +40 -10
- package/plugins/specweave-github/lib/github-spec-content-sync.ts +82 -14
- package/plugins/specweave-github/lib/progress-comment-builder.js +229 -0
- package/plugins/specweave-github/lib/progress-comment-builder.ts +324 -0
- package/plugins/specweave-github/lib/user-story-content-builder.js +299 -0
- package/plugins/specweave-github/lib/user-story-content-builder.ts +413 -0
- package/plugins/specweave-github/lib/user-story-issue-builder.js +344 -0
- package/plugins/specweave-github/lib/user-story-issue-builder.ts +543 -0
- package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +189 -0
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
- package/plugins/specweave-jira/lib/{enhanced-jira-sync.ts.disabled → enhanced-jira-sync.ts} +26 -52
- package/plugins/specweave-kafka/.claude-plugin/plugin.json +26 -0
- package/plugins/specweave-kafka/IMPLEMENTATION-COMPLETE.md +483 -0
- package/plugins/specweave-kafka/README.md +242 -0
- package/plugins/specweave-kafka/agents/kafka-architect/AGENT.md +235 -0
- package/plugins/specweave-kafka/agents/kafka-devops/AGENT.md +209 -0
- package/plugins/specweave-kafka/agents/kafka-observability/AGENT.md +266 -0
- package/plugins/specweave-kafka/commands/deploy.md +99 -0
- package/plugins/specweave-kafka/commands/dev-env.md +176 -0
- package/plugins/specweave-kafka/commands/mcp-configure.md +101 -0
- package/plugins/specweave-kafka/commands/monitor-setup.md +96 -0
- package/plugins/specweave-kafka/docker/kafka-local/docker-compose.yml +187 -0
- package/plugins/specweave-kafka/docker/redpanda/docker-compose.yml +199 -0
- package/plugins/specweave-kafka/docker/templates/consumer-nodejs.js +225 -0
- package/plugins/specweave-kafka/docker/templates/consumer-python.py +220 -0
- package/plugins/specweave-kafka/docker/templates/producer-nodejs.js +168 -0
- package/plugins/specweave-kafka/docker/templates/producer-python.py +167 -0
- package/plugins/specweave-kafka/lib/adapters/apache-kafka-adapter.js +438 -0
- package/plugins/specweave-kafka/lib/adapters/apache-kafka-adapter.ts +541 -0
- package/plugins/specweave-kafka/lib/adapters/platform-adapter.js +47 -0
- package/plugins/specweave-kafka/lib/adapters/platform-adapter.ts +343 -0
- package/plugins/specweave-kafka/lib/cli/kcat-wrapper.js +258 -0
- package/plugins/specweave-kafka/lib/cli/kcat-wrapper.ts +298 -0
- package/plugins/specweave-kafka/lib/cli/types.js +10 -0
- package/plugins/specweave-kafka/lib/cli/types.ts +92 -0
- package/plugins/specweave-kafka/lib/connectors/connector-catalog.js +305 -0
- package/plugins/specweave-kafka/lib/connectors/connector-catalog.ts +528 -0
- package/plugins/specweave-kafka/lib/documentation/diagram-generator.js +114 -0
- package/plugins/specweave-kafka/lib/documentation/diagram-generator.ts +195 -0
- package/plugins/specweave-kafka/lib/documentation/exporter.js +210 -0
- package/plugins/specweave-kafka/lib/documentation/exporter.ts +338 -0
- package/plugins/specweave-kafka/lib/documentation/schema-catalog-generator.js +60 -0
- package/plugins/specweave-kafka/lib/documentation/schema-catalog-generator.ts +130 -0
- package/plugins/specweave-kafka/lib/documentation/topology-generator.js +143 -0
- package/plugins/specweave-kafka/lib/documentation/topology-generator.ts +290 -0
- package/plugins/specweave-kafka/lib/mcp/detector.js +298 -0
- package/plugins/specweave-kafka/lib/mcp/detector.ts +352 -0
- package/plugins/specweave-kafka/lib/mcp/types.js +21 -0
- package/plugins/specweave-kafka/lib/mcp/types.ts +77 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-config-manager.js +193 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-config-manager.ts +362 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-switcher.js +188 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-switcher.ts +359 -0
- package/plugins/specweave-kafka/lib/multi-cluster/health-aggregator.js +195 -0
- package/plugins/specweave-kafka/lib/multi-cluster/health-aggregator.ts +380 -0
- package/plugins/specweave-kafka/lib/observability/opentelemetry-kafka.js +209 -0
- package/plugins/specweave-kafka/lib/observability/opentelemetry-kafka.ts +358 -0
- package/plugins/specweave-kafka/lib/patterns/advanced-ksqldb-patterns.js +354 -0
- package/plugins/specweave-kafka/lib/patterns/advanced-ksqldb-patterns.ts +563 -0
- package/plugins/specweave-kafka/lib/patterns/circuit-breaker-resilience.js +259 -0
- package/plugins/specweave-kafka/lib/patterns/circuit-breaker-resilience.ts +516 -0
- package/plugins/specweave-kafka/lib/patterns/dead-letter-queue.js +233 -0
- package/plugins/specweave-kafka/lib/patterns/dead-letter-queue.ts +423 -0
- package/plugins/specweave-kafka/lib/patterns/exactly-once-semantics.js +266 -0
- package/plugins/specweave-kafka/lib/patterns/exactly-once-semantics.ts +445 -0
- package/plugins/specweave-kafka/lib/patterns/flink-kafka-integration.js +312 -0
- package/plugins/specweave-kafka/lib/patterns/flink-kafka-integration.ts +561 -0
- package/plugins/specweave-kafka/lib/patterns/multi-dc-replication.js +289 -0
- package/plugins/specweave-kafka/lib/patterns/multi-dc-replication.ts +607 -0
- package/plugins/specweave-kafka/lib/patterns/rate-limiting-backpressure.js +264 -0
- package/plugins/specweave-kafka/lib/patterns/rate-limiting-backpressure.ts +498 -0
- package/plugins/specweave-kafka/lib/patterns/stream-processing-optimization.js +263 -0
- package/plugins/specweave-kafka/lib/patterns/stream-processing-optimization.ts +549 -0
- package/plugins/specweave-kafka/lib/patterns/tiered-storage-compaction.js +205 -0
- package/plugins/specweave-kafka/lib/patterns/tiered-storage-compaction.ts +399 -0
- package/plugins/specweave-kafka/lib/performance/performance-optimizer.js +249 -0
- package/plugins/specweave-kafka/lib/performance/performance-optimizer.ts +427 -0
- package/plugins/specweave-kafka/lib/security/kafka-security.js +252 -0
- package/plugins/specweave-kafka/lib/security/kafka-security.ts +494 -0
- package/plugins/specweave-kafka/lib/utils/capacity-planner.js +203 -0
- package/plugins/specweave-kafka/lib/utils/capacity-planner.ts +469 -0
- package/plugins/specweave-kafka/lib/utils/config-validator.js +419 -0
- package/plugins/specweave-kafka/lib/utils/config-validator.ts +564 -0
- package/plugins/specweave-kafka/lib/utils/partitioning.js +329 -0
- package/plugins/specweave-kafka/lib/utils/partitioning.ts +473 -0
- package/plugins/specweave-kafka/lib/utils/sizing.js +221 -0
- package/plugins/specweave-kafka/lib/utils/sizing.ts +374 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-broker-metrics.json +628 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-cluster-overview.json +564 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-consumer-lag.json +509 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-jvm-metrics.json +674 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-topic-metrics.json +578 -0
- package/plugins/specweave-kafka/monitoring/grafana/provisioning/dashboards/kafka.yml +17 -0
- package/plugins/specweave-kafka/monitoring/grafana/provisioning/datasources/prometheus.yml +17 -0
- package/plugins/specweave-kafka/monitoring/prometheus/kafka-alerts.yml +415 -0
- package/plugins/specweave-kafka/monitoring/prometheus/kafka-jmx-exporter.yml +256 -0
- package/plugins/specweave-kafka/package.json +41 -0
- package/plugins/specweave-kafka/skills/kafka-architecture/SKILL.md +647 -0
- package/plugins/specweave-kafka/skills/kafka-cli-tools/SKILL.md +433 -0
- package/plugins/specweave-kafka/skills/kafka-iac-deployment/SKILL.md +449 -0
- package/plugins/specweave-kafka/skills/kafka-kubernetes/SKILL.md +667 -0
- package/plugins/specweave-kafka/skills/kafka-mcp-integration/SKILL.md +273 -0
- package/plugins/specweave-kafka/skills/kafka-observability/SKILL.md +576 -0
- package/plugins/specweave-kafka/templates/config/broker-production.properties +254 -0
- package/plugins/specweave-kafka/templates/config/consumer-low-latency.properties +112 -0
- package/plugins/specweave-kafka/templates/config/producer-high-throughput.properties +120 -0
- package/plugins/specweave-kafka/templates/migration/mirrormaker2-config.properties +234 -0
- package/plugins/specweave-kafka/templates/monitoring/grafana/multi-cluster-dashboard.json +686 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/main.tf +347 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/outputs.tf +107 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/templates/kafka-broker-init.sh.tpl +216 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/variables.tf +156 -0
- package/plugins/specweave-kafka/terraform/aws-msk/main.tf +362 -0
- package/plugins/specweave-kafka/terraform/aws-msk/outputs.tf +93 -0
- package/plugins/specweave-kafka/terraform/aws-msk/templates/server.properties.tpl +32 -0
- package/plugins/specweave-kafka/terraform/aws-msk/variables.tf +235 -0
- package/plugins/specweave-kafka/terraform/azure-event-hubs/main.tf +281 -0
- package/plugins/specweave-kafka/terraform/azure-event-hubs/outputs.tf +118 -0
- package/plugins/specweave-kafka/terraform/azure-event-hubs/variables.tf +148 -0
- package/plugins/specweave-kafka/tsconfig.json +21 -0
- package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +23 -0
- package/plugins/specweave-kafka-streams/README.md +310 -0
- package/plugins/specweave-kafka-streams/skills/kafka-streams-topology/SKILL.md +539 -0
- package/plugins/specweave-n8n/.claude-plugin/plugin.json +22 -0
- package/plugins/specweave-n8n/README.md +354 -0
- package/plugins/specweave-n8n/skills/n8n-kafka-workflows/SKILL.md +504 -0
- package/plugins/specweave-release/commands/specweave-release-platform.md +1 -1
- package/plugins/specweave-release/hooks/post-task-completion.sh +2 -2
- package/src/templates/AGENTS.md.template +601 -7
- package/src/templates/CLAUDE.md.template +188 -88
- package/plugins/specweave-ado/commands/specweave-ado-sync-spec.md +0 -255
- package/plugins/specweave-github/commands/specweave-github-sync-epic.md +0 -248
- package/plugins/specweave-github/commands/specweave-github-sync-from.md +0 -147
- package/plugins/specweave-github/commands/specweave-github-sync-spec.md +0 -208
- package/plugins/specweave-github/commands/specweave-github-sync-tasks.md +0 -530
- package/plugins/specweave-jira/commands/specweave-jira-sync-epic.md +0 -267
- package/plugins/specweave-jira/commands/specweave-jira-sync-spec.md +0 -240
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kafka Streams Performance Optimization
|
|
3
|
+
*
|
|
4
|
+
* RocksDB tuning, topology optimization, thread configuration, and state store performance
|
|
5
|
+
*
|
|
6
|
+
* @module stream-processing-optimization
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* RocksDB Configuration
|
|
11
|
+
*/
|
|
12
|
+
export interface RocksDBConfig {
|
|
13
|
+
/** Block cache size in MB (default: 50) */
|
|
14
|
+
blockCacheSizeMB?: number;
|
|
15
|
+
/** Write buffer size in MB (default: 32) */
|
|
16
|
+
writeBufferSizeMB?: number;
|
|
17
|
+
/** Max write buffers (default: 3) */
|
|
18
|
+
maxWriteBuffers?: number;
|
|
19
|
+
/** Enable bloom filters (default: true) */
|
|
20
|
+
bloomFilters?: boolean;
|
|
21
|
+
/** Block size in KB (default: 4) */
|
|
22
|
+
blockSizeKB?: number;
|
|
23
|
+
/** Compression type */
|
|
24
|
+
compressionType?: 'none' | 'snappy' | 'lz4' | 'zstd';
|
|
25
|
+
/** Max open files (default: -1 for unlimited) */
|
|
26
|
+
maxOpenFiles?: number;
|
|
27
|
+
/** Enable statistics (default: false) */
|
|
28
|
+
enableStatistics?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Streams Application Configuration
|
|
33
|
+
*/
|
|
34
|
+
export interface StreamsOptimizationConfig {
|
|
35
|
+
/** Application ID */
|
|
36
|
+
applicationId: string;
|
|
37
|
+
/** Bootstrap servers */
|
|
38
|
+
bootstrapServers: string[];
|
|
39
|
+
/** Number of stream threads (default: 1) */
|
|
40
|
+
numStreamThreads?: number;
|
|
41
|
+
/** Cache size per thread in MB (default: 10) */
|
|
42
|
+
cacheSizeMB?: number;
|
|
43
|
+
/** Commit interval in ms (default: 30000) */
|
|
44
|
+
commitIntervalMs?: number;
|
|
45
|
+
/** Poll interval in ms (default: 100) */
|
|
46
|
+
pollMs?: number;
|
|
47
|
+
/** Processing guarantee */
|
|
48
|
+
processingGuarantee?: 'at_least_once' | 'exactly_once' | 'exactly_once_v2';
|
|
49
|
+
/** RocksDB configuration */
|
|
50
|
+
rocksdb?: RocksDBConfig;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* State Store Metrics
|
|
55
|
+
*/
|
|
56
|
+
export interface StateStoreMetrics {
|
|
57
|
+
/** Store name */
|
|
58
|
+
storeName: string;
|
|
59
|
+
/** Store type (rocksdb, in-memory) */
|
|
60
|
+
storeType: string;
|
|
61
|
+
/** Estimated size in bytes */
|
|
62
|
+
estimatedSizeBytes: number;
|
|
63
|
+
/** Number of entries (approximate) */
|
|
64
|
+
entryCount: number;
|
|
65
|
+
/** Read operations per second */
|
|
66
|
+
readOpsPerSec: number;
|
|
67
|
+
/** Write operations per second */
|
|
68
|
+
writeOpsPerSec: number;
|
|
69
|
+
/** Average read latency in ms */
|
|
70
|
+
avgReadLatencyMs: number;
|
|
71
|
+
/** Average write latency in ms */
|
|
72
|
+
avgWriteLatencyMs: number;
|
|
73
|
+
/** Cache hit ratio (0-1) */
|
|
74
|
+
cacheHitRatio: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Topology Optimization Recommendations
|
|
79
|
+
*/
|
|
80
|
+
export interface TopologyOptimization {
|
|
81
|
+
/** Recommended optimizations */
|
|
82
|
+
recommendations: string[];
|
|
83
|
+
/** Detected anti-patterns */
|
|
84
|
+
antiPatterns: string[];
|
|
85
|
+
/** Performance score (0-100) */
|
|
86
|
+
performanceScore: number;
|
|
87
|
+
/** Estimated throughput impact */
|
|
88
|
+
throughputImpact: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Stream Processing Optimizer
|
|
93
|
+
*
|
|
94
|
+
* Performance tuning for Kafka Streams applications
|
|
95
|
+
*/
|
|
96
|
+
export class StreamProcessingOptimizer {
|
|
97
|
+
/**
|
|
98
|
+
* Generate optimized RocksDB configuration
|
|
99
|
+
*/
|
|
100
|
+
static generateRocksDBConfig(
|
|
101
|
+
storeType: 'small' | 'medium' | 'large' | 'xlarge'
|
|
102
|
+
): RocksDBConfig {
|
|
103
|
+
const configs = {
|
|
104
|
+
small: {
|
|
105
|
+
blockCacheSizeMB: 50,
|
|
106
|
+
writeBufferSizeMB: 32,
|
|
107
|
+
maxWriteBuffers: 3,
|
|
108
|
+
bloomFilters: true,
|
|
109
|
+
blockSizeKB: 4,
|
|
110
|
+
compressionType: 'snappy' as const,
|
|
111
|
+
maxOpenFiles: 1000,
|
|
112
|
+
enableStatistics: false,
|
|
113
|
+
},
|
|
114
|
+
medium: {
|
|
115
|
+
blockCacheSizeMB: 256,
|
|
116
|
+
writeBufferSizeMB: 64,
|
|
117
|
+
maxWriteBuffers: 4,
|
|
118
|
+
bloomFilters: true,
|
|
119
|
+
blockSizeKB: 8,
|
|
120
|
+
compressionType: 'lz4' as const,
|
|
121
|
+
maxOpenFiles: 5000,
|
|
122
|
+
enableStatistics: true,
|
|
123
|
+
},
|
|
124
|
+
large: {
|
|
125
|
+
blockCacheSizeMB: 1024,
|
|
126
|
+
writeBufferSizeMB: 128,
|
|
127
|
+
maxWriteBuffers: 6,
|
|
128
|
+
bloomFilters: true,
|
|
129
|
+
blockSizeKB: 16,
|
|
130
|
+
compressionType: 'lz4' as const,
|
|
131
|
+
maxOpenFiles: 10000,
|
|
132
|
+
enableStatistics: true,
|
|
133
|
+
},
|
|
134
|
+
xlarge: {
|
|
135
|
+
blockCacheSizeMB: 4096,
|
|
136
|
+
writeBufferSizeMB: 256,
|
|
137
|
+
maxWriteBuffers: 8,
|
|
138
|
+
bloomFilters: true,
|
|
139
|
+
blockSizeKB: 32,
|
|
140
|
+
compressionType: 'zstd' as const,
|
|
141
|
+
maxOpenFiles: -1, // Unlimited
|
|
142
|
+
enableStatistics: true,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
return configs[storeType];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Calculate optimal thread count
|
|
151
|
+
*/
|
|
152
|
+
static calculateOptimalThreadCount(
|
|
153
|
+
partitionCount: number,
|
|
154
|
+
cpuCores: number,
|
|
155
|
+
workloadType: 'cpu-intensive' | 'io-intensive' | 'balanced'
|
|
156
|
+
): number {
|
|
157
|
+
let threads: number;
|
|
158
|
+
|
|
159
|
+
if (workloadType === 'cpu-intensive') {
|
|
160
|
+
// CPU-bound: 1 thread per core
|
|
161
|
+
threads = Math.min(partitionCount, cpuCores);
|
|
162
|
+
} else if (workloadType === 'io-intensive') {
|
|
163
|
+
// I/O-bound: 2x cores (better CPU utilization during I/O wait)
|
|
164
|
+
threads = Math.min(partitionCount, cpuCores * 2);
|
|
165
|
+
} else {
|
|
166
|
+
// Balanced: 1.5x cores
|
|
167
|
+
threads = Math.min(partitionCount, Math.ceil(cpuCores * 1.5));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Never exceed partition count (diminishing returns)
|
|
171
|
+
return Math.max(1, Math.min(threads, partitionCount));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Calculate optimal cache size per thread
|
|
176
|
+
*/
|
|
177
|
+
static calculateCacheSize(
|
|
178
|
+
availableMemoryMB: number,
|
|
179
|
+
numThreads: number,
|
|
180
|
+
storeCount: number
|
|
181
|
+
): number {
|
|
182
|
+
// Reserve 50% of memory for RocksDB block cache and OS
|
|
183
|
+
const cachableMB = availableMemoryMB * 0.5;
|
|
184
|
+
|
|
185
|
+
// Distribute remaining memory across threads
|
|
186
|
+
const cachePerThreadMB = cachableMB / numThreads;
|
|
187
|
+
|
|
188
|
+
// Minimum 10MB per thread
|
|
189
|
+
return Math.max(10, Math.floor(cachePerThreadMB));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Analyze topology for optimization opportunities
|
|
194
|
+
*/
|
|
195
|
+
static analyzeTopology(topologyDescription: string): TopologyOptimization {
|
|
196
|
+
const recommendations: string[] = [];
|
|
197
|
+
const antiPatterns: string[] = [];
|
|
198
|
+
let performanceScore = 100;
|
|
199
|
+
|
|
200
|
+
// Check for repartitioning
|
|
201
|
+
if (topologyDescription.includes('repartition')) {
|
|
202
|
+
const repartitionCount = (topologyDescription.match(/repartition/g) || []).length;
|
|
203
|
+
if (repartitionCount > 2) {
|
|
204
|
+
antiPatterns.push(
|
|
205
|
+
`Multiple repartitioning operations (${repartitionCount}) - consider co-partitioning`
|
|
206
|
+
);
|
|
207
|
+
performanceScore -= 20;
|
|
208
|
+
recommendations.push('Use co-partitioning to avoid repartition topics');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Check for state stores
|
|
213
|
+
if (topologyDescription.includes('StateStore')) {
|
|
214
|
+
const storeCount = (topologyDescription.match(/StateStore/g) || []).length;
|
|
215
|
+
if (storeCount > 5) {
|
|
216
|
+
recommendations.push(
|
|
217
|
+
`Many state stores (${storeCount}) detected - consider RocksDB tuning`
|
|
218
|
+
);
|
|
219
|
+
performanceScore -= 10;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Check for joins
|
|
224
|
+
if (topologyDescription.includes('Join')) {
|
|
225
|
+
const joinCount = (topologyDescription.match(/Join/g) || []).length;
|
|
226
|
+
if (joinCount > 3) {
|
|
227
|
+
recommendations.push(
|
|
228
|
+
`Multiple joins (${joinCount}) detected - ensure input topics are co-partitioned`
|
|
229
|
+
);
|
|
230
|
+
performanceScore -= 10;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Check for global tables
|
|
235
|
+
if (topologyDescription.includes('GlobalKTable')) {
|
|
236
|
+
const globalTableCount = (topologyDescription.match(/GlobalKTable/g) || []).length;
|
|
237
|
+
if (globalTableCount > 2) {
|
|
238
|
+
antiPatterns.push(
|
|
239
|
+
`Multiple GlobalKTables (${globalTableCount}) - high memory usage, consider regular KTables`
|
|
240
|
+
);
|
|
241
|
+
performanceScore -= 15;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Check for unnecessary groupBy operations
|
|
246
|
+
if (topologyDescription.match(/groupBy.*groupBy/)) {
|
|
247
|
+
antiPatterns.push('Consecutive groupBy operations detected - combine into single groupBy');
|
|
248
|
+
performanceScore -= 15;
|
|
249
|
+
recommendations.push('Merge consecutive groupBy operations to reduce overhead');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// General recommendations
|
|
253
|
+
if (!antiPatterns.length && !recommendations.length) {
|
|
254
|
+
recommendations.push('Topology looks well-optimized!');
|
|
255
|
+
} else {
|
|
256
|
+
if (topologyDescription.includes('aggregate') || topologyDescription.includes('reduce')) {
|
|
257
|
+
recommendations.push('For stateful operations, tune RocksDB cache and write buffers');
|
|
258
|
+
}
|
|
259
|
+
recommendations.push('Monitor state store metrics (size, read/write latency)');
|
|
260
|
+
recommendations.push('Consider enabling exactly-once semantics v2 for better performance');
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const throughputImpact = performanceScore >= 90
|
|
264
|
+
? 'Minimal impact'
|
|
265
|
+
: performanceScore >= 70
|
|
266
|
+
? 'Moderate impact (10-30% improvement possible)'
|
|
267
|
+
: 'Significant impact (30-50% improvement possible)';
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
recommendations,
|
|
271
|
+
antiPatterns,
|
|
272
|
+
performanceScore,
|
|
273
|
+
throughputImpact,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Generate Kafka Streams properties
|
|
279
|
+
*/
|
|
280
|
+
static generateStreamsProperties(config: StreamsOptimizationConfig): Record<string, any> {
|
|
281
|
+
const props: Record<string, any> = {
|
|
282
|
+
'application.id': config.applicationId,
|
|
283
|
+
'bootstrap.servers': config.bootstrapServers.join(','),
|
|
284
|
+
'num.stream.threads': config.numStreamThreads || 1,
|
|
285
|
+
'cache.max.bytes.buffering': (config.cacheSizeMB || 10) * 1024 * 1024,
|
|
286
|
+
'commit.interval.ms': config.commitIntervalMs || 30000,
|
|
287
|
+
'poll.ms': config.pollMs || 100,
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
// Processing guarantee
|
|
291
|
+
if (config.processingGuarantee === 'exactly_once_v2') {
|
|
292
|
+
props['processing.guarantee'] = 'exactly_once_v2';
|
|
293
|
+
props['replication.factor'] = 3;
|
|
294
|
+
props['min.insync.replicas'] = 2;
|
|
295
|
+
} else if (config.processingGuarantee === 'exactly_once') {
|
|
296
|
+
props['processing.guarantee'] = 'exactly_once';
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// RocksDB configuration
|
|
300
|
+
if (config.rocksdb) {
|
|
301
|
+
const rocksdb = config.rocksdb;
|
|
302
|
+
|
|
303
|
+
if (rocksdb.blockCacheSizeMB) {
|
|
304
|
+
props['rocksdb.config.setter'] = 'RocksDBConfigSetter';
|
|
305
|
+
props['rocksdb.block.cache.size'] = rocksdb.blockCacheSizeMB * 1024 * 1024;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (rocksdb.writeBufferSizeMB) {
|
|
309
|
+
props['rocksdb.write.buffer.size'] = rocksdb.writeBufferSizeMB * 1024 * 1024;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (rocksdb.maxWriteBuffers) {
|
|
313
|
+
props['rocksdb.max.write.buffers'] = rocksdb.maxWriteBuffers;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (rocksdb.compressionType) {
|
|
317
|
+
props['rocksdb.compression.type'] = rocksdb.compressionType;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (rocksdb.bloomFilters !== false) {
|
|
321
|
+
props['rocksdb.bloom.filter'] = true;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (rocksdb.maxOpenFiles) {
|
|
325
|
+
props['rocksdb.max.open.files'] = rocksdb.maxOpenFiles;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (rocksdb.enableStatistics) {
|
|
329
|
+
props['rocksdb.statistics.enable'] = true;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return props;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Estimate state store size
|
|
338
|
+
*/
|
|
339
|
+
static estimateStateStoreSize(
|
|
340
|
+
recordsPerSec: number,
|
|
341
|
+
avgRecordSizeBytes: number,
|
|
342
|
+
windowSizeMs?: number
|
|
343
|
+
): number {
|
|
344
|
+
if (windowSizeMs) {
|
|
345
|
+
// Windowed store: size = records * avg_size * window_duration
|
|
346
|
+
const windowDurationSec = windowSizeMs / 1000;
|
|
347
|
+
const recordsInWindow = recordsPerSec * windowDurationSec;
|
|
348
|
+
return recordsInWindow * avgRecordSizeBytes;
|
|
349
|
+
} else {
|
|
350
|
+
// Key-value store: assume 1 hour retention for size estimation
|
|
351
|
+
const retentionSec = 3600;
|
|
352
|
+
const totalRecords = recordsPerSec * retentionSec;
|
|
353
|
+
return totalRecords * avgRecordSizeBytes;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* State Store Monitor
|
|
360
|
+
*
|
|
361
|
+
* Monitors state store performance metrics
|
|
362
|
+
*/
|
|
363
|
+
export class StateStoreMonitor {
|
|
364
|
+
/**
|
|
365
|
+
* Check if state store needs optimization
|
|
366
|
+
*/
|
|
367
|
+
static needsOptimization(metrics: StateStoreMetrics): boolean {
|
|
368
|
+
// High latency (> 10ms)
|
|
369
|
+
if (metrics.avgReadLatencyMs > 10 || metrics.avgWriteLatencyMs > 10) {
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Low cache hit ratio (< 70%)
|
|
374
|
+
if (metrics.cacheHitRatio < 0.7) {
|
|
375
|
+
return true;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// High throughput (> 1000 ops/sec) with low cache hit ratio
|
|
379
|
+
if (
|
|
380
|
+
(metrics.readOpsPerSec > 1000 || metrics.writeOpsPerSec > 1000) &&
|
|
381
|
+
metrics.cacheHitRatio < 0.8
|
|
382
|
+
) {
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Get optimization recommendations
|
|
391
|
+
*/
|
|
392
|
+
static getOptimizationRecommendations(metrics: StateStoreMetrics): string[] {
|
|
393
|
+
const recommendations: string[] = [];
|
|
394
|
+
|
|
395
|
+
// Latency recommendations
|
|
396
|
+
if (metrics.avgReadLatencyMs > 10) {
|
|
397
|
+
recommendations.push(
|
|
398
|
+
`High read latency (${metrics.avgReadLatencyMs.toFixed(2)}ms) - increase RocksDB block cache size`
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (metrics.avgWriteLatencyMs > 10) {
|
|
403
|
+
recommendations.push(
|
|
404
|
+
`High write latency (${metrics.avgWriteLatencyMs.toFixed(2)}ms) - increase write buffer size`
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Cache recommendations
|
|
409
|
+
if (metrics.cacheHitRatio < 0.7) {
|
|
410
|
+
recommendations.push(
|
|
411
|
+
`Low cache hit ratio (${(metrics.cacheHitRatio * 100).toFixed(1)}%) - increase block cache size or reduce state store size`
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Throughput recommendations
|
|
416
|
+
if (metrics.readOpsPerSec > 5000) {
|
|
417
|
+
recommendations.push(
|
|
418
|
+
`Very high read throughput (${metrics.readOpsPerSec} ops/sec) - consider sharding or in-memory cache`
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (metrics.writeOpsPerSec > 2000) {
|
|
423
|
+
recommendations.push(
|
|
424
|
+
`High write throughput (${metrics.writeOpsPerSec} ops/sec) - increase write buffer count`
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Size recommendations
|
|
429
|
+
const sizeGB = metrics.estimatedSizeBytes / 1024 / 1024 / 1024;
|
|
430
|
+
if (sizeGB > 50) {
|
|
431
|
+
recommendations.push(
|
|
432
|
+
`Large state store (${sizeGB.toFixed(1)} GB) - consider partitioning or time-based windowing`
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
return recommendations;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Example Usage: Basic Optimization
|
|
442
|
+
*
|
|
443
|
+
* ```typescript
|
|
444
|
+
* const config: StreamsOptimizationConfig = {
|
|
445
|
+
* applicationId: 'order-processing-app',
|
|
446
|
+
* bootstrapServers: ['localhost:9092'],
|
|
447
|
+
* numStreamThreads: StreamProcessingOptimizer.calculateOptimalThreadCount(
|
|
448
|
+
* 32, // partition count
|
|
449
|
+
* 8, // CPU cores
|
|
450
|
+
* 'balanced'
|
|
451
|
+
* ),
|
|
452
|
+
* cacheSizeMB: StreamProcessingOptimizer.calculateCacheSize(
|
|
453
|
+
* 16384, // 16GB available memory
|
|
454
|
+
* 8, // thread count
|
|
455
|
+
* 5 // state store count
|
|
456
|
+
* ),
|
|
457
|
+
* processingGuarantee: 'exactly_once_v2',
|
|
458
|
+
* rocksdb: StreamProcessingOptimizer.generateRocksDBConfig('large'),
|
|
459
|
+
* };
|
|
460
|
+
*
|
|
461
|
+
* const props = StreamProcessingOptimizer.generateStreamsProperties(config);
|
|
462
|
+
* console.log('Streams config:', props);
|
|
463
|
+
* ```
|
|
464
|
+
*/
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Example Usage: Topology Analysis
|
|
468
|
+
*
|
|
469
|
+
* ```typescript
|
|
470
|
+
* const topologyDescription = streams.describe().toString();
|
|
471
|
+
* const analysis = StreamProcessingOptimizer.analyzeTopology(topologyDescription);
|
|
472
|
+
*
|
|
473
|
+
* console.log('Performance Score:', analysis.performanceScore);
|
|
474
|
+
* console.log('Recommendations:', analysis.recommendations);
|
|
475
|
+
* if (analysis.antiPatterns.length > 0) {
|
|
476
|
+
* console.warn('Anti-patterns detected:', analysis.antiPatterns);
|
|
477
|
+
* }
|
|
478
|
+
* ```
|
|
479
|
+
*/
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Example Usage: State Store Monitoring
|
|
483
|
+
*
|
|
484
|
+
* ```typescript
|
|
485
|
+
* const metrics: StateStoreMetrics = {
|
|
486
|
+
* storeName: 'order-aggregates',
|
|
487
|
+
* storeType: 'rocksdb',
|
|
488
|
+
* estimatedSizeBytes: 5 * 1024 * 1024 * 1024, // 5GB
|
|
489
|
+
* entryCount: 10_000_000,
|
|
490
|
+
* readOpsPerSec: 2000,
|
|
491
|
+
* writeOpsPerSec: 500,
|
|
492
|
+
* avgReadLatencyMs: 12.5,
|
|
493
|
+
* avgWriteLatencyMs: 8.3,
|
|
494
|
+
* cacheHitRatio: 0.65,
|
|
495
|
+
* };
|
|
496
|
+
*
|
|
497
|
+
* if (StateStoreMonitor.needsOptimization(metrics)) {
|
|
498
|
+
* const recommendations = StateStoreMonitor.getOptimizationRecommendations(metrics);
|
|
499
|
+
* console.log('Optimization needed:', recommendations);
|
|
500
|
+
* }
|
|
501
|
+
* ```
|
|
502
|
+
*/
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Stream Processing Optimization Best Practices:
|
|
506
|
+
*
|
|
507
|
+
* **Thread Configuration**:
|
|
508
|
+
* - CPU-intensive: 1 thread per core
|
|
509
|
+
* - I/O-intensive: 2x cores
|
|
510
|
+
* - Balanced workload: 1.5x cores
|
|
511
|
+
* - Never exceed partition count
|
|
512
|
+
*
|
|
513
|
+
* **Cache Sizing**:
|
|
514
|
+
* - Allocate 50% of memory for caching
|
|
515
|
+
* - Minimum 10MB per thread
|
|
516
|
+
* - Monitor cache hit ratio (target: > 80%)
|
|
517
|
+
*
|
|
518
|
+
* **RocksDB Tuning**:
|
|
519
|
+
* - Block cache: 256MB-4GB (depends on state size)
|
|
520
|
+
* - Write buffer: 64MB-256MB (depends on write rate)
|
|
521
|
+
* - Enable bloom filters (reduces disk I/O)
|
|
522
|
+
* - Use LZ4/Zstandard compression
|
|
523
|
+
*
|
|
524
|
+
* **State Store Size**:
|
|
525
|
+
* - Target: < 10GB per partition (fast recovery)
|
|
526
|
+
* - Use windowed stores for time-series data
|
|
527
|
+
* - Consider changelog compaction for key-value stores
|
|
528
|
+
*
|
|
529
|
+
* **Topology Optimization**:
|
|
530
|
+
* - Minimize repartitioning (use co-partitioning)
|
|
531
|
+
* - Avoid consecutive groupBy operations
|
|
532
|
+
* - Use GlobalKTable sparingly (high memory)
|
|
533
|
+
* - Prefer stream-stream joins over stream-table joins
|
|
534
|
+
*
|
|
535
|
+
* **Processing Guarantee**:
|
|
536
|
+
* - Use exactly-once-v2 (best performance)
|
|
537
|
+
* - Avoid exactly-once-beta (deprecated)
|
|
538
|
+
* - At-least-once OK for idempotent operations
|
|
539
|
+
*
|
|
540
|
+
* **Commit Interval**:
|
|
541
|
+
* - Lower interval: Lower latency, higher overhead
|
|
542
|
+
* - Higher interval: Higher throughput, higher latency
|
|
543
|
+
* - Recommended: 30-60 seconds for batch, 1-5 seconds for real-time
|
|
544
|
+
*/
|
|
545
|
+
|
|
546
|
+
export default {
|
|
547
|
+
StreamProcessingOptimizer,
|
|
548
|
+
StateStoreMonitor,
|
|
549
|
+
};
|