You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add message ordering guidance to Rails docs (#288)
## Summary
- Added documentation for handling ActionCable message ordering issues
- Includes a Stimulus controller solution for client-side reordering
- Mentions async stack and AnyCable as alternatives
## Context
This PR addresses the message ordering issues discussed in #282. The
documentation includes:
1. A Stimulus controller that reorders messages based on timestamps
2. Explanation of ActionCable's ordering limitations
3. Alternative approaches (async stack, AnyCable)
## Request for Review
@ioquatix@palkan - I'd appreciate your review on the technical accuracy
of this documentation, particularly:
- Is my description of ActionCable's ordering behavior accurate?
- Are the suggested solutions appropriate?
- Any other approaches you'd recommend documenting?
## Test Plan
- [x] Documentation builds correctly
- [x] Code examples are syntactically correct
- [ ] Technical accuracy verified by domain experts
Copy file name to clipboardExpand all lines: docs/guides/rails.md
+102Lines changed: 102 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -579,6 +579,108 @@ This setup allows for:
579
579
2. Background processing to prevent request timeouts
580
580
3. Automatic persistence of all messages and tool calls
581
581
582
+
### Handling Message Ordering with ActionCable
583
+
584
+
ActionCable does not guarantee message order due to its concurrent processing model. Messages are distributed to worker threads that deliver them to clients concurrently, which can cause out-of-order delivery (e.g., assistant responses appearing above user messages). Here are the recommended solutions:
585
+
586
+
#### Option 1: Client-Side Reordering with Stimulus (Recommended)
587
+
588
+
Add a Stimulus controller that maintains correct chronological order based on timestamps. This example demonstrates the concept - adapt it to your specific needs:
[AnyCable](https://anycable.io) provides order guarantees at the server level through "sticky concurrency" - ensuring messages from the same stream are processed by the same worker. This eliminates the need for client-side reordering code.
672
+
673
+
#### Understanding the Root Cause
674
+
675
+
As confirmed by the ActionCable maintainers, ActionCable uses a threaded executor to distribute broadcast messages, so messages are delivered to connected clients concurrently. This is by design for performance reasons.
676
+
677
+
The most reliable solution is client-side reordering with order information in the payload. For applications requiring strict ordering guarantees, consider:
678
+
- Server-sent events (SSE) for unidirectional streaming
679
+
- WebSocket libraries with ordered stream support like [Lively](https://github.com/socketry/lively/tree/main/examples/chatbot)
680
+
- AnyCable for server-side ordering guarantees
681
+
682
+
**Note**: Some users report better behavior with the async Ruby stack (Falcon + async-cable), but this doesn't guarantee ordering and shouldn't be relied upon as a solution.
683
+
582
684
## Customizing Models
583
685
584
686
Your `Chat`, `Message`, and `ToolCall` models are standard ActiveRecord models. You can add any other associations, validations, scopes, callbacks, or methods as needed for your application logic. The `acts_as` helpers provide the core persistence bridge to RubyLLM without interfering with other model behavior.
0 commit comments