Skip to content

feat: [#156] Implement Dispatch Layer with ExecutionContext wrapper#161

Merged
josecelano merged 2 commits into
mainfrom
156-create-dispatch-layer
Nov 10, 2025
Merged

feat: [#156] Implement Dispatch Layer with ExecutionContext wrapper#161
josecelano merged 2 commits into
mainfrom
156-create-dispatch-layer

Conversation

@josecelano

Copy link
Copy Markdown
Member

🎯 Overview

This PR implements Proposal 2: Create Dispatch Layer from the presentation layer reorganization epic (#154).

The Dispatch Layer establishes clear separation between command routing, execution context, and command execution, following the four-layer presentation architecture: Input → Dispatch → Controllers → Views.

📋 What's Implemented

Core Components

  • ExecutionContext wrapper around Arc<Container> for future-proof command signatures
  • Central command routing with route_command(command, working_dir, &context) function
  • Complete dispatch module with router and context submodules
  • Bootstrap integration - Updated bootstrap/app.rs to use new dispatch layer
  • Legacy deprecation - Marked old presentation::execute as deprecated with migration guide

Documentation & Quality

  • Architectural Decision Record - docs/decisions/execution-context-wrapper.md documenting design rationale
  • Comprehensive documentation - Module-level docs explaining architecture and benefits
  • Fixed all doctest issues - All 303 documentation tests compile and pass
  • Linting fixes - Added 'configurator' to spell-check dictionary, fixed clippy issues

🏗️ Architecture Benefits

ExecutionContext Design

The dispatch layer uses an ExecutionContext wrapper instead of passing Container directly:

pub struct ExecutionContext {
    container: Arc<Container>,
    // Future extensions without breaking changes:
    // request_id: RequestId,
    // execution_metadata: ExecutionMetadata,
    // tracing_context: TracingContext,
}

Benefits:

  • Future-proof - Can extend execution context without breaking command signatures
  • Clear abstraction - Represents "everything a command needs" vs generic container
  • Command-specific access - Convenience methods for common services
  • Type safety - Compile-time guarantees for service access

Routing Architecture

pub fn route_command(
    command: Commands,
    working_dir: &Path,
    context: &ExecutionContext,
) -> Result<(), CommandError>

Benefits:

  • Centralized routing - All command dispatch logic in one place
  • Type safety - Compile-time guarantees that all commands are handled
  • Testable - Router can be tested independently of handlers
  • Scalable - Easy to add new commands without modifying existing code

🔧 Module Structure

src/presentation/dispatch/
├── mod.rs       # Layer exports and comprehensive documentation
├── router.rs    # Central command routing logic
└── context.rs   # ExecutionContext wrapper implementation

✅ Quality Validation

All quality checks pass:

  • 1,200+ Unit Tests ✅ - All pass successfully
  • E2E Tests ✅ - Provision and configuration tests validated
  • Documentation Tests ✅ - All 303 doctests compile and pass
  • Linting ✅ - cargo machete, clippy, rustfmt, shellcheck, cspell all pass
  • Pre-commit Validation ✅ - Complete pre-commit suite passes

📖 Related Documentation

  • ADR: docs/decisions/execution-context-wrapper.md - Design rationale for ExecutionContext wrapper
  • Epic Issue: #154 - Presentation layer reorganization roadmap
  • Module Documentation - Comprehensive docs in src/presentation/dispatch/mod.rs

🚀 Next Steps

After this PR is merged:

  1. Update epic progress - Mark Proposal 2 as completed in #156
  2. Begin Proposal 3 - Start implementing Controllers layer
  3. Integration - New dispatch layer is ready for remaining presentation components

🔍 Migration Guide

For code using the old presentation::execute function:

// Old (deprecated)
use torrust_tracker_deployer_lib::presentation::execute;
execute(command, working_dir, user_output).await?;

// New (recommended)
use torrust_tracker_deployer_lib::presentation::dispatch::{route_command, ExecutionContext};
let context = ExecutionContext::new(Arc::new(container));
route_command(command, working_dir, &context)?;

Closes: #156
Part of Epic: #154

- Create ExecutionContext wrapper around Container for future-proof command signatures
- Implement router::route_command function to handle command dispatch
- Update bootstrap::app to use new dispatch layer instead of presentation::execute
- Mark old presentation::execute as deprecated with migration guide
- Add comprehensive documentation and ADR explaining ExecutionContext design choice

The ExecutionContext wrapper provides:
- Future-proof command signatures (can add context without breaking handlers)
- Clear abstraction for command execution (vs dependency injection container)
- Command-specific service access patterns
- Enhanced testability with different execution contexts

Closes Phase 3-5 of issue #156 implementation plan.
@josecelano josecelano self-assigned this Nov 7, 2025
@josecelano josecelano linked an issue Nov 7, 2025 that may be closed by this pull request
68 tasks
@josecelano josecelano force-pushed the 156-create-dispatch-layer branch from 91e042c to 73abd3b Compare November 7, 2025 17:47
- Add ExecutionContext wrapper around Arc<Container> for future-proof command signatures
- Implement central command routing in route_command function
- Create comprehensive dispatch layer with router and context modules
- Update bootstrap/app.rs to use new dispatch layer instead of direct presentation::execute
- Mark old presentation::execute as deprecated with migration guide
- Add ExecutionContext wrapper ADR documenting design decisions
- Fix doctest compilation errors and linting issues
- Add 'configurator' to project dictionary for spell checking

The dispatch layer establishes clear separation between command routing, execution context,
and command execution, following the four-layer presentation architecture:
Input → Dispatch → Controllers → Views
@josecelano josecelano force-pushed the 156-create-dispatch-layer branch from 73abd3b to aa531e3 Compare November 7, 2025 17:59
@josecelano

Copy link
Copy Markdown
Member Author

ACK aa531e3

@josecelano josecelano merged commit 1fe82de into main Nov 10, 2025
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal 2: Create Dispatch Layer

1 participant