-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Implement distributed locking in build worker #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
… var - Add getGitHubToken() function to retrieve PAT from common environment - GitHub PAT stored at /laco/cmn/github/pat/cloud-apps (cross-environment) - Support local development with GITHUB_PAT_CLOUD_APPS env var - Remove TODO comments and temporary GITHUB_TOKEN workaround This fixes the SSM parameter access issue where the build worker couldn't access the GitHub PAT needed for repository_dispatch API. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
## Changes ### New Shared Modules - build-lock.ts: BuildLockManager with DynamoDB-based distributed locking - acquireLock(): Conditional write to acquire lock - releaseLock(): Mark as COMPLETED/FAILED - getLock(): Get current lock status - isLocked(): Check if operation in progress - command-config.ts: Centralized command configuration - Define lock requirements per command - /build: requiresLock=true, TTL=10min - /deploy: requiresLock=true, TTL=30min - /status, /echo: requiresLock=false ### Updated Build Worker - Import buildLockManager - Acquire lock before processing - If locked: notify user (ephemeral), skip processing - If acquired: proceed with build - Release lock on success/failure ## User Experience Lock acquired: "🔨 Building router..." (visible to channel) Lock held by another user: "⚠️ Build already in progress Started by: alice Started: 30s ago Please wait for the current build to complete." (ephemeral) ## Problem Solved Prevents duplicate GitHub Actions triggers when multiple users request the same build simultaneously. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
| private tableName: string; | ||
|
|
||
| constructor() { | ||
| const config = getConfig(); |
Check failure
Code scanning / CodeQL
Invocation of non-function Error
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 15 days ago
In general, to fix “invocation of non‑function” errors, you either (1) ensure the imported/assigned value is actually a function, or (2) guard before calling it and handle the error path explicitly. Since we are constrained to changes within this file and cannot alter the ./config module or change existing imports, the appropriate approach is to validate getConfig at the call site and avoid calling it if it is not a function.
Concretely, in applications/chatops/slack-bot/src/shared/build-lock.ts, update the BuildLockManager constructor to:
- Check that
getConfigis a function before invoking it. - If it is not a function, throw a descriptive error (or log and throw) instead of calling it, preventing a cryptic “is not a function” crash.
- Optionally give a type-safe fallback (e.g.,
neverafter throwing) so TypeScript remains happy, but that is not strictly necessary if we just throw and then use the result.
The minimal change is to replace:
constructor() {
const config = getConfig();
this.tableName = `${config.orgPrefix}-${config.environment}-chatbot-build-locks`;
}with a constructor that:
- Validates
typeof getConfig === 'function'. - Throws an
Errorif the validation fails. - Calls
getConfig()only in the safe branch and uses the returnedconfigas before.
No new imports are required; we can use the built‑in Error and existing logger if desired (but using Error alone is sufficient and keeps changes minimal).
-
Copy modified lines R41-R43
| @@ -38,6 +38,9 @@ | ||
| private tableName: string; | ||
|
|
||
| constructor() { | ||
| if (typeof getConfig !== 'function') { | ||
| throw new Error('getConfig is not a function. Ensure ./config exports a callable getConfig.'); | ||
| } | ||
| const config = getConfig(); | ||
| this.tableName = `${config.orgPrefix}-${config.environment}-chatbot-build-locks`; | ||
| } |
Replace command-specific workers with unified quadrant workers for better scalability and maintainability. **Workers (routing layer):** - Remove: echo, build, deploy, status workers (command-specific) - Add: SR (short-read) and LW (long-write) unified workers - SR worker handles: /echo and future fast read commands - LW worker handles: /build, /deploy and future write commands **Handlers (business logic layer):** - Extract command logic into reusable handlers - handlers/echo.ts - Echo command logic - handlers/build.ts - Build command logic - Workers route to handlers based on command registry 1. **Extensibility**: New commands just need handler registration 2. **DRY**: Shared worker infrastructure for similar command types 3. **Performance**: Optimized timeouts and concurrency per quadrant 4. **Maintainability**: Clear separation of routing vs business logic - Build system: package.sh, Makefile, component-config.sh - CI/CD: slack-build.yml workflow - Local dev: LocalStack setup, .env.local.example - Documentation: CONFIGURATION.md, LOCAL-TESTING.md Aligns with cloud-sandbox PR #14 which provisions: - laco-plt-chatbot-command-sr-sqs queue - laco-plt-chatbot-command-lw-sqs queue - laco-plt-chatbot-command-sr-worker Lambda - laco-plt-chatbot-command-lw-worker Lambda
Replace command-specific workers with unified quadrant workers for better scalability and maintainability. **Workers (routing layer):** - Remove: echo, build, deploy, status workers (command-specific) - Add: SR (short-read) and LW (long-write) unified workers - SR worker handles: /echo and future fast read commands - LW worker handles: /build, /deploy and future write commands **Handlers (business logic layer):** - Extract command logic into reusable handlers - handlers/echo.ts - Echo command logic - handlers/build.ts - Build command logic - Workers route to handlers based on command registry 1. **Extensibility**: New commands just need handler registration 2. **DRY**: Shared worker infrastructure for similar command types 3. **Performance**: Optimized timeouts and concurrency per quadrant 4. **Maintainability**: Clear separation of routing vs business logic - Build system: package.sh, Makefile, component-config.sh - CI/CD: slack-build.yml workflow - Local dev: LocalStack setup, .env.local.example - Documentation: CONFIGURATION.md, LOCAL-TESTING.md Aligns with cloud-sandbox PR #14 which provisions: - laco-plt-chatbot-command-sr-sqs queue - laco-plt-chatbot-command-lw-sqs queue - laco-plt-chatbot-command-sr-worker Lambda - laco-plt-chatbot-command-lw-worker Lambda
Replace command-specific workers with unified quadrant workers for better scalability and maintainability. **Workers (routing layer):** - Remove: echo, build, deploy, status workers (command-specific) - Add: SR (short-read) and LW (long-write) unified workers - SR worker handles: /echo and future fast read commands - LW worker handles: /build, /deploy and future write commands **Handlers (business logic layer):** - Extract command logic into reusable handlers - handlers/echo.ts - Echo command logic - handlers/build.ts - Build command logic - Workers route to handlers based on command registry 1. **Extensibility**: New commands just need handler registration 2. **DRY**: Shared worker infrastructure for similar command types 3. **Performance**: Optimized timeouts and concurrency per quadrant 4. **Maintainability**: Clear separation of routing vs business logic - Build system: package.sh, Makefile, component-config.sh - CI/CD: slack-build.yml workflow - Local dev: LocalStack setup, .env.local.example - Documentation: CONFIGURATION.md, LOCAL-TESTING.md Aligns with cloud-sandbox PR #14 which provisions: - laco-plt-chatbot-command-sr-sqs queue - laco-plt-chatbot-command-lw-sqs queue - laco-plt-chatbot-command-sr-worker Lambda - laco-plt-chatbot-command-lw-worker Lambda
Summary
Key Changes
Implementation Details
{command}-{component}-{environment}(e.g.,build-router-plt)Test Plan
🤖 Generated with Claude Code