Asynchronous Task Handling
Relevant source files
The following files were used as context for generating this wiki page:
- PHASE1_IMPLEMENTATION.md
- internal/server-plugins/deployment/domain/deployment_tracker.go
- internal/server-plugins/deployment/domain/deployment_poller.go
- internal/server-plugins/deployment/infrastructure/deployment_status_checker.go
- internal/server-plugins/deployment/infrastructure/deployment_infrastructure.go
- internal/dokku-api/client.go
The Asynchronous Task Handling system in Dokku MCP provides a robust mechanism for managing long-running operations, specifically application deployments. It replaces a previous "fire-and-forget" approach, where SSH commands were issued without tracking their actual completion status. The new system immediately returns a unique deployment ID to the user, while a background process polls the Dokku instance to determine the true outcome of the deployment. This ensures accurate status reporting, captures build logs, and provides a reliable way to query the state of ongoing and completed deployments.
This system is primarily composed of three core components: the DeploymentTracker, the DeploymentPoller, and the DeploymentStatusChecker. Together, they provide a complete lifecycle management solution for asynchronous deployments, enhancing the reliability and observability of the platform.
Sources: PHASE1_IMPLEMENTATION.md
Architecture Overview
The asynchronous deployment process is initiated when a user requests a deployment. The system immediately creates a deployment record, starts a background poller, and returns control to the user. The poller then periodically uses a status checker to query the actual state of the application on the Dokku host until a terminal state (succeeded or failed) is reached.
The following diagram illustrates the high-level data flow for initiating and tracking a deployment.
This diagram shows the separation between the immediate, synchronous response to the user and the long-running asynchronous tracking process.
Sources: PHASE1_IMPLEMENTATION.md, internal/server-plugins/deployment/infrastructure/deployment_infrastructure.go:88-91
Key Components
| Component | Responsibility | Source File |
|---|---|---|
DeploymentTracker | A thread-safe, in-memory store for the state of all active and recently completed deployments. | deployment_tracker.go |
DeploymentPoller | A background worker that periodically checks the status of active deployments. | deployment_poller.go |
DeploymentStatusChecker | An infrastructure component that queries Dokku to determine the real status of an application. | deployment_status_checker.go |
deploymentInfrastructure | The infrastructure layer responsible for executing Dokku commands and orchestrating the async process. | deployment_infrastructure.go |
Sources: PHASE1_IMPLEMENTATION.md
Deployment Tracker
The DeploymentTracker is the central, in-memory state manager for all deployments. It uses a sync.Map to ensure thread-safe concurrent access, which is critical as updates may come from both the main application thread and the background poller.
Sources: internal/server-plugins/deployment/domain/deployment_tracker.go:19-23
Core Structure
The tracker manages a map of TrackedDeployment objects, which hold the state, logs, and metadata for each deployment.
This diagram shows the main methods of the DeploymentTracker and its relationship with the internal TrackedDeployment struct.
Sources: internal/server-plugins/deployment/domain/deployment_tracker.go:19-30
Deployment Status Lifecycle
Deployments transition through a defined set of states. The DeploymentTracker is responsible for applying these state changes.
| Status | Description |
|---|---|
pending | The initial state of a deployment after it has been created but before polling has started. |
running | The deployment is actively being processed by Dokku. |
succeeded | The deployment completed successfully, and the application's processes are running. |
failed | The deployment failed due to a build error, timeout, or other issue. |
The following state diagram visualizes the lifecycle of a deployment status.
Automatic Cleanup
To prevent unbounded memory growth, the DeploymentTracker includes a mechanism to automatically clean up completed (succeeded or failed) deployments after a configurable Time-To-Live (TTL), which is set to 5 minutes.
Sources: PHASE1_IMPLEMENTATION.md, internal/server-plugins/deployment/domain/deployment_tracker.go:21,123-140
Deployment Poller
The DeploymentPoller is a background service that drives the status-checking process for all active deployments. When a deployment is initiated, the infrastructure layer calls StartPolling. The poller then creates a dedicated goroutine for that deployment, which periodically queries the DeploymentStatusChecker.
Sources: internal/server-plugins/deployment/domain/deployment_poller.go:42-43
Configuration
The poller's behavior is defined by several key configuration parameters.
| Parameter | Default Value | Description |
|---|---|---|
pollInterval | 10 seconds | The interval at which to check the deployment status. |
maxPollTime | 30 minutes | The maximum duration to poll before marking the deployment as failed. |
maxConsecutiveErrors | 5 | The number of consecutive errors from the status checker before failing the deployment. |
Sources: PHASE1_IMPLEMENTATION.md
Polling Process
The sequence diagram below details the interaction between the infrastructure, the poller, the status checker, and the tracker during the background polling loop.
This diagram shows how the poller orchestrates status checks and updates the tracker until a final state is reached.
Sources: internal/server-plugins/deployment/domain/deployment_poller.go:42-99, PHASE1_IMPLEMENTATION.md
Deployment Status Checker
The deploymentStatusChecker is the component that directly interacts with the Dokku instance to ascertain the real state of a deployment. It does not hold any state itself but relies on executing Dokku CLI commands.
Sources: internal/server-plugins/deployment/infrastructure/deployment_status_checker.go:16-22
Status Detection Logic
The checker uses a sequence of commands to determine the status:
apps:report <appName>: It first checks the application report. If the app is not marked asdeployed: true, it's consideredpending. If the app doesn't exist, the deployment is marked asfailed.ps:report <appName>: If the app is deployed, it checks the process report. If it finds "Processes running" and the count is greater than 0, the deployment is consideredsucceeded.- Log Analysis: If no processes are running, it may analyze logs for error patterns to confirm a failure.
This logic is designed to be resilient to the intermediate states that occur during a Dokku build and deployment process.
Sources: internal/server-plugins/deployment/infrastructure/deployment_status_checker.go:25-78
Infrastructure Integration
The deploymentInfrastructure component is the bridge between the deployment service and the asynchronous tracking system. Its PerformGitDeploy method is responsible for initiating the entire async workflow.
A key aspect of the design is how it handles the ps:rebuild command. This command can take a long time and often causes the SSH connection to time out. The system is designed to handle this gracefully.
- The
git:synccommand is executed synchronously. - The
DeploymentPolleris started immediately aftergit:syncsucceeds. - The
ps:rebuildcommand is executed in a separate goroutine. An SSH timeout for this command is expected and ignored, as the poller is now responsible for tracking the final outcome. Any other error, however, will immediately mark the deployment as failed.
Sources: internal/server-plugins/deployment/infrastructure/deployment_infrastructure.go:88-149, internal/dokku-api/client.go:203-217
Conclusion
The asynchronous task handling system for deployments marks a significant architectural improvement. By decoupling the deployment trigger from the status verification, it provides a correct, observable, and reliable deployment experience. The system correctly identifies the final state of deployments, captures essential build logs, and prevents false success reports caused by SSH timeouts. This foundation enables a better user experience and provides a clear pattern for handling other long-running tasks within Dokku MCP.
Sources: PHASE1_IMPLEMENTATION.md