Implement Middleware base class and MiddlewarePipeline executor with priority ordering #105

Closed
opened 2026-03-15 04:13:15 +00:00 by freemo · 1 comment
Owner

Metadata

  • Commit Message: feat(dispatch): implement Middleware base and pipeline executor
  • Branch: feature/m1-middleware-pipeline
  • Milestone: v1.0.0 (milestone id: 20)
  • Type: Type/Feature (label id: 30)

Background

The Middleware base class defines the interface for all middleware. MiddlewarePipeline manages registered middleware and executes them in priority order around the action.

Expected Behavior

  • Middleware base class with register class method and call(action, context) instance method
  • MiddlewarePipeline.execute(action) runs before_action chain, then action, then after_action
  • Middleware can throw :halt to stop the chain
  • Lower priority numbers execute first

Acceptance Criteria

  • Middleware base class with registration API
  • Pipeline executor with priority-ordered before/after phases
  • Halt mechanism for chain interruption
  • BDD scenarios for pipeline execution order and halting

Subtasks

  • Implement Middleware base class with register and call
  • Implement MiddlewarePipeline with priority-sorted execution
  • Implement halt mechanism
  • Write Cucumber scenarios

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
## Metadata - **Commit Message**: `feat(dispatch): implement Middleware base and pipeline executor` - **Branch**: `feature/m1-middleware-pipeline` - **Milestone**: v1.0.0 (milestone id: 20) - **Type**: Type/Feature (label id: 30) ## Background The `Middleware` base class defines the interface for all middleware. `MiddlewarePipeline` manages registered middleware and executes them in priority order around the action. ## Expected Behavior - `Middleware` base class with `register` class method and `call(action, context)` instance method - `MiddlewarePipeline.execute(action)` runs before_action chain, then action, then after_action - Middleware can throw `:halt` to stop the chain - Lower priority numbers execute first ## Acceptance Criteria - Middleware base class with registration API - Pipeline executor with priority-ordered before/after phases - Halt mechanism for chain interruption - BDD scenarios for pipeline execution order and halting ## Subtasks - [x] Implement Middleware base class with `register` and `call` - [x] Implement MiddlewarePipeline with priority-sorted execution - [x] Implement halt mechanism - [x] Write Cucumber scenarios ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly. - The commit is pushed to the remote on the branch matching the Branch in Metadata exactly. - The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
freemo added this to the (deleted) milestone 2026-03-15 04:13:15 +00:00
freemo self-assigned this 2026-03-15 04:25:24 +00:00
freemo modified the milestone from (deleted) to v1.0.0 2026-03-16 00:28:03 +00:00
Author
Owner

Implementation Notes

Files Created

  • lib/aethyr/core/commands/middleware.rb — Middleware base class with priority ordering (default 500), phase designation (:before_action/:after_action), call(action, context) interface (raises NotImplementedError), and class-level register method.
  • lib/aethyr/core/commands/middleware_pipeline.rb — MiddlewarePipeline executor with Mutex-protected registry, priority-sorted before/after phases, throw(:halt) chain interruption mechanism, and reset! for testing.
  • tests/unit/middleware_pipeline.feature — 19 Cucumber BDD scenarios covering execution order, halt behavior, argument validation, context passing, class-level registration, and edge cases.
  • tests/unit/step_definitions/middleware_pipeline_steps.rb — Step definitions using Test::Unit::Assertions with TestTrackingMiddleware and MockPipelineAction test doubles.

Design Decisions

  • Thread-safe: Registry is protected by a Mutex. snapshot_middleware extracts before/after lists under the lock, then execution proceeds without holding the lock.
  • Immutable defaults: VALID_PHASES is frozen. Priority and phase are set at construction time.
  • Argument validation: All public methods validate types per CONTRIBUTING.md (nil checks, type verification, value range for phases).
  • Sorbet typed: Both source files use # typed: strict with full sig annotations.
  • ABC complexity: Extracted snapshot_middleware private method to keep execute under the Metrics/AbcSize threshold.

Quality Gates

  • RuboCop: 0 offenses on all new files
  • Cucumber: 19 scenarios, 74 steps, all passing
  • Coverage: 100% on both new source files when running the middleware_pipeline feature
## Implementation Notes ### Files Created - `lib/aethyr/core/commands/middleware.rb` — Middleware base class with priority ordering (default 500), phase designation (:before_action/:after_action), `call(action, context)` interface (raises NotImplementedError), and class-level `register` method. - `lib/aethyr/core/commands/middleware_pipeline.rb` — MiddlewarePipeline executor with Mutex-protected registry, priority-sorted before/after phases, `throw(:halt)` chain interruption mechanism, and `reset!` for testing. - `tests/unit/middleware_pipeline.feature` — 19 Cucumber BDD scenarios covering execution order, halt behavior, argument validation, context passing, class-level registration, and edge cases. - `tests/unit/step_definitions/middleware_pipeline_steps.rb` — Step definitions using Test::Unit::Assertions with TestTrackingMiddleware and MockPipelineAction test doubles. ### Design Decisions - Thread-safe: Registry is protected by a Mutex. `snapshot_middleware` extracts before/after lists under the lock, then execution proceeds without holding the lock. - Immutable defaults: `VALID_PHASES` is frozen. Priority and phase are set at construction time. - Argument validation: All public methods validate types per CONTRIBUTING.md (nil checks, type verification, value range for phases). - Sorbet typed: Both source files use `# typed: strict` with full `sig` annotations. - ABC complexity: Extracted `snapshot_middleware` private method to keep `execute` under the Metrics/AbcSize threshold. ### Quality Gates - RuboCop: 0 offenses on all new files - Cucumber: 19 scenarios, 74 steps, all passing - Coverage: 100% on both new source files when running the middleware_pipeline feature
freemo added reference feature/m1-middleware-pipeline 2026-03-31 05:33:41 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference: aethyr/Aethyr#105
No description provided.