-
Notifications
You must be signed in to change notification settings - Fork 2
Sse initial implementation #204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
calebbourg
wants to merge
10
commits into
main
Choose a base branch
from
sse-initial-implementation
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
better connection lookup and remove the need for unwrap
- Add critical warning to docker-compose.yaml about SSE single-instance limitation * SSE connections tracked in-memory with DashMap * Must not scale horizontally without Redis Pub/Sub * Warns about symptom: events randomly fail with multiple replicas - Add nginx configuration for /api/sse endpoint * Disable proxy buffering for immediate event streaming * Set 24h read timeout for long-lived SSE connections * Enable chunked transfer encoding * Clear connection header for proper streaming * Add CORS headers for credential support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Create standalone SSE crate to avoid circular dependencies between service and web layers. Uses generic types (String for IDs, serde_json::Value for payloads) to remain independent of domain models. Key components: - ConnectionRegistry: Dual-index (connection_id, user_id) architecture using DashMap for O(1) concurrent lookups - Manager: High-level API for connection lifecycle and message routing - Message types: Event enum with action, agreement, goal, and system events - MessageScope: User-targeted and broadcast message delivery Architecture decisions: - In-memory connection tracking (single-instance only) - Generic types to avoid domain dependency - Thread-safe using DashMap and Arc - Tokio channels for event distribution 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add SSE manager to the service layer's AppState to enable real-time event distribution throughout the application. The manager is wrapped in Arc for thread-safe sharing across request handlers. Changes: - Add sse dependency to service crate - Add sse_manager: Arc<sse::Manager> field to AppState - Update AppState::new() to accept sse_manager parameter - Make sse_manager publicly accessible via getter This allows controllers to send SSE events by calling app_state.sse_manager.send_message() with appropriate message scope. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Implement Axum SSE handler that establishes long-lived HTTP connections for server-sent events. One connection per authenticated user, persisting across page navigation. Implementation: - Handler at GET /sse (behind authentication middleware) - Uses async_stream::stream! for event streaming - Registers user connection with SSE manager - Automatic cleanup when connection closes - Returns Sse<impl Stream<Item = Result<Event, Infallible>>> - Keep-alive enabled with default settings Technical details: - Tokio unbounded channel receives events from manager - Stream yields events as they arrive from channel - Connection ID generated server-side for lifecycle tracking - Converts domain::Id to String for SSE layer compatibility 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Create and pass SSE manager instance to AppState in both the main application and database seeding utility. Changes: - main.rs: Initialize Arc<sse::Manager::new()> and pass to AppState - seed_db.rs: Initialize SSE manager for test data seeding context The manager is created once at startup and shared across all request handlers via Arc for thread-safe access. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Update three authentication middleware tests to initialize SSE manager when creating AppState, matching the new 3-parameter constructor signature. Fixed tests: - test_require_auth_returns_401_with_no_session - test_require_auth_returns_401_with_invalid_session_cookie - test_require_auth_allows_authenticated_request_to_proceed Each test now creates Arc<sse::Manager::new()> before constructing AppState to maintain test isolation while matching production code. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Update project documentation to reflect the new SSE (Server-Sent Events) real-time communication infrastructure. Changes: - README.md: Add sse crate to project directory structure - crate_dependency_graph.md: Add sse crate dependencies (web→sse, service→sse) - system_architecture_diagram.md: Add SSE Handler and SSE Manager components with event flow from domain layer - network_flow_diagram.md: Document SSE endpoint configuration and single-instance scaling limitation Key documentation notes: - SSE uses in-memory connection tracking (single-instance only) - Nginx configured for long-lived connections (24h timeout, no buffering) - Generic types used in sse crate to avoid circular dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
describe the intent of your changes here
GitHub Issue: [Closes|Fixes|Resolves] #your GitHub issue number here
Changes
Testing Strategy
describe how you or someone else can test and verify the changes
Concerns
describe any concerns that might be worth mentioning or discussing