Skip to content

Add ConsumerSupervisor for background task management#18

Merged
aidankhogg merged 4 commits into
dev/alphafrom
claude/zealous-shannon-gogwex
Jun 22, 2026
Merged

Add ConsumerSupervisor for background task management#18
aidankhogg merged 4 commits into
dev/alphafrom
claude/zealous-shannon-gogwex

Conversation

@aidankhogg

Copy link
Copy Markdown
Contributor

Summary

This PR introduces a ConsumerSupervisor class to manage long-running consumer tasks (like DNS update processing) with automatic restart on failure. It refactors the DNS consumer from an ad-hoc background task into a supervised, managed consumer that runs after all phases complete.

Key Changes

  • New ConsumerSupervisor class (netengine/core/consumer_supervisor.py):

    • Manages registration and lifecycle of long-running consumer coroutines
    • Provides automatic restart on failure with 5-second backoff
    • Graceful shutdown with cancellation handling
    • Status monitoring for all registered consumers
  • Orchestrator integration (netengine/core/orchestrator.py):

    • Initialize ConsumerSupervisor in orchestrator constructor
    • Pass supervisor to PhaseContext for access by phase handlers
    • Add start_consumers() method to start all registered consumers after phases complete
  • Phase context updates (netengine/handlers/context.py):

    • Add consumer_supervisor field to PhaseContext with TYPE_CHECKING import to avoid circular dependencies
  • DNS consumer refactoring (netengine/phases/phase_registries.py):

    • Replace direct asyncio.create_task() with supervisor registration
    • Improve error handling with nested try-except blocks
    • Add logging for DNS update processing and error cases
    • Implement dead-letter queue (DLQ) archival for failed messages
    • Add backoff delay on consumer loop errors
  • OIDC handler enhancement (netengine/handlers/oidc_handler.py):

    • Add add_token_mapper() method to configure protocol mappers for JWT claims
  • Platform identity phase updates (netengine/phases/phase_platform_identity.py):

    • Create platform API client with OIDC
    • Add token mapper to include organization claim in JWT tokens
    • Store platform client ID in runtime state
  • CLI updates (netengine/cli/main.py):

    • Start background consumers after all phases complete
    • Keep event loop alive to allow consumers to run
    • Graceful shutdown on Ctrl+C with consumer cleanup

Implementation Details

The ConsumerSupervisor wraps consumer coroutines in a supervised loop that automatically restarts them on failure. This provides resilience for long-running background tasks without requiring manual restart logic. The DNS consumer now properly handles message processing errors by archiving failed messages to a DLQ, improving observability and error recovery.

https://claude.ai/code/session_017q7TcBiinkpr66zwYFgjHB

claude added 4 commits June 22, 2026 08:00
…loop

Phase 4: Keycloak realm/user/client creation
- Add platform client creation to OIDCHandler with create_client()
- Add token mapper method to include org claim in JWT tokens
- Store platform_client_id in runtime state for later use
- This unblocks Phase 6 (in-world realms) and OIDC-authenticated API calls

Phase 5: pgmq consumer loop supervision
- Create ConsumerSupervisor to manage long-running consumer tasks
- Add automatic restart on consumer failure with exponential backoff
- Integrate supervisor into orchestrator and pass to phase context
- Register DNS update consumer with supervisor in Phase 5
- Update CLI to start consumers after phases complete and keep event loop alive
- Add error handling and logging to DNS consumer loop for visibility
- Consumer loops now properly process queued DNS update events

This ensures:
- Keycloak platform realm is fully bootstrapped with client credentials
- DNS updates from domain registrations are actually consumed and processed
- Background consumers stay alive and restart on failure
- Event loop remains active to support async event processing

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q7TcBiinkpr66zwYFgjHB
- Add proper type annotations to ConsumerSupervisor for mypy strict mode
- Fix CLI to only keep event loop alive if consumers are registered
- Update test mocking to handle async operations and empty consumer list
- Format code with Black for linting compliance
- Prevent test timeout by exiting when no consumers are registered

Resolves PR #18 CI failures (linting, type checking, test failures).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q7TcBiinkpr66zwYFgjHB
- Add type hints to BaseNetEngineException.__init__ parameters (*args, **kwargs)
- Add Any type annotations to dict type arguments
- Fix kwargs unpacking: for k, v in kwargs.items()
- Add missing return type annotation -> None
- Add __future__ import for type hints
- Format with Black

Fixes mypy --strict errors and linting issues in errors.py.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q7TcBiinkpr66zwYFgjHB
The get_logger import was not being used, causing flake8 F401 error.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q7TcBiinkpr66zwYFgjHB
@aidankhogg aidankhogg self-assigned this Jun 22, 2026
@aidankhogg aidankhogg added the enhancement New feature or request label Jun 22, 2026
@aidankhogg aidankhogg marked this pull request as ready for review June 22, 2026 09:22
@aidankhogg aidankhogg merged commit dec981f into dev/alpha Jun 22, 2026
2 of 3 checks passed
@aidankhogg aidankhogg deleted the claude/zealous-shannon-gogwex branch June 22, 2026 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants