Skip to main content
Glama
CONCURRENCY.md6.24 kB
# Concurrency Protection The dbt-core-mcp server includes built-in concurrency protection to prevent conflicts when multiple DBT processes attempt to run simultaneously. ## Why Concurrency Protection? DBT doesn't implement file-based locking to prevent concurrent executions. This can lead to several issues: 1. **Database Lock Conflicts**: File-based databases like DuckDB lock the database file during operations 2. **Manifest Corruption**: Multiple processes writing to `target/manifest.json` simultaneously 3. **State Inconsistency**: Race conditions between parsing and execution phases 4. **Resource Contention**: Competing for the same database connections or warehouse resources ## How It Works The server uses process detection to identify running DBT commands: ```python from dbt_core_mcp.utils.process_check import is_dbt_running, wait_for_dbt_completion # Check if DBT is running if is_dbt_running(project_dir): # Wait up to 30 seconds for completion wait_for_dbt_completion(project_dir, timeout=30.0) ``` ### Detection Strategy The `is_dbt_running()` function identifies DBT processes by: 1. **Command Detection**: Looks for actual `dbt` CLI commands: - `dbt run`, `dbt parse`, `dbt test`, etc. - `python -m dbt.cli.main` invocations - Standalone `dbt` or `dbt.exe` executables 2. **Filtering**: Excludes non-DBT processes: - MCP server itself (`dbt-core-mcp`) - Python processes that merely import dbt libraries - Unrelated processes with "dbt" in their names 3. **Project Matching**: Verifies the DBT process is working in the same project: - Compares process working directory with project directory - Checks for project path in command-line arguments ### Wait Behavior The `wait_for_dbt_completion()` function: - **Polls**: Checks every 0.2 seconds (5 times per second) - **Timeout**: Default 10 seconds (configurable) - **Returns**: `True` if DBT finished, `False` if timeout ## Scenarios ### Scenario 1: User Running DBT Manually **Situation**: User runs `dbt run` in terminal while MCP server tries to execute `dbt parse` **Behavior**: 1. MCP server detects running `dbt run` process 2. Logs: "DBT process detected, waiting for completion..." 3. Polls 5 times per second for up to 10 seconds 4. Once `dbt run` completes, MCP server executes `dbt parse` ### Scenario 2: Concurrent MCP Tool Calls **Situation**: Multiple MCP tools called simultaneously **Behavior**: 1. First tool starts executing DBT command 2. Second tool detects the process and waits 3. Sequential execution prevents conflicts ### Scenario 3: Timeout **Situation**: User's DBT command takes longer than 10 seconds **Behavior**: 1. MCP server waits for 10 seconds 2. Returns error: "DBT is already running in this project. Please wait for it to complete." 3. User can retry the MCP operation after their DBT command finishes ## Configuration Currently, concurrency protection is enabled by default with these settings: - **Timeout**: 10 seconds - **Poll Interval**: 0.2 seconds (5 checks per second) These are hardcoded in `BridgeRunner.invoke()` but can be made configurable in future versions. ### Why These Values? - **Fast Polling (0.2s)**: Process checking is very cheap - just reading OS process info. Frequent polling provides responsive feedback without performance impact. - **Short Timeout (10s)**: Most DBT parse/compile operations complete in seconds. Longer operations (like `dbt run`) typically indicate the user should wait anyway. ## Limitations ### What's Protected ✅ **Protected**: - MCP server operations won't conflict with manual `dbt` CLI usage - Multiple MCP tool calls are serialized - Database lock conflicts are prevented - Manifest corruption is avoided ### What's NOT Protected ❌ **Not Protected**: - Multiple MCP server instances (different processes) - DBT commands run via other tools (e.g., orchestrators like Airflow) - Direct database access outside of DBT ### Known Edge Cases 1. **Process Detection Failure**: If `psutil` is not installed, process detection is disabled (assumes safe to proceed) 2. **Permission Denied**: Some processes may not be accessible due to OS permissions (skipped) 3. **Fast Commands**: Very short DBT commands might complete before detection 4. **Long-Running Commands**: Commands longer than 10 seconds will timeout (user should wait for completion and retry) ## Dependencies - **psutil**: Cross-platform process detection library - Optional but highly recommended - If missing, concurrency protection is disabled with a warning ## Future Enhancements Potential improvements for future versions: 1. **File-Based Locking**: Add `.dbt_mcp.lock` file for more reliable locking 2. **Configurable Timeout**: Allow users to configure wait timeout 3. **Lock Scope**: Support different lock scopes (project-level vs. global) 4. **Lock Visualization**: Show lock status in tool responses 5. **Priority Queue**: Implement priority for different operation types ## Testing The concurrency protection includes comprehensive tests: ```bash # Run concurrency tests pytest tests/test_process_check.py -v ``` Tests cover: - No process detection (clean state) - Actual process detection (integration test) - Timeout behavior - Wait behavior ## Troubleshooting ### "DBT is already running" Error **Problem**: MCP server reports DBT is running when you're not executing anything **Solutions**: 1. Check for background DBT processes: `ps aux | grep dbt` (Linux/Mac) or Task Manager (Windows) 2. Kill stale DBT processes 3. Wait a few seconds and retry ### "Cannot check for running DBT processes" Warning **Problem**: `psutil` not installed **Solution**: ```bash # Install psutil uv pip install psutil # or pip install psutil ``` ### False Positives **Problem**: Server detects unrelated "dbt" processes **Solution**: This should be rare due to filtering logic. If it occurs, please file an issue with: - Process command line (`ps aux | grep dbt`) - Expected vs. actual behavior ## Implementation Details See source code: - `src/dbt_core_mcp/utils/process_check.py`: Core detection logic - `src/dbt_core_mcp/dbt/bridge_runner.py`: Integration with bridge runner - `tests/test_process_check.py`: Test suite

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/NiclasOlofsson/dbt-core-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server