-
Notifications
You must be signed in to change notification settings - Fork 0
docs: Signal record components and DirtyState event #419
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -186,6 +186,7 @@ pub enum Event { | |||||||||||||||||||||||||||||||||||||||||
| HistorySync(Box<LazyHistorySync>), | ||||||||||||||||||||||||||||||||||||||||||
| OfflineSyncPreview(OfflineSyncPreview), | ||||||||||||||||||||||||||||||||||||||||||
| OfflineSyncCompleted(OfflineSyncCompleted), | ||||||||||||||||||||||||||||||||||||||||||
| DirtyState(DirtyState), | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Device Updates | ||||||||||||||||||||||||||||||||||||||||||
| DeviceListUpdate(DeviceListUpdate), | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1994,6 +1995,40 @@ Offline sync happens automatically when the client reconnects after being discon | |||||||||||||||||||||||||||||||||||||||||
| If the server does not complete offline sync within 60 seconds, the client forces completion via a timeout fallback — `OfflineSyncCompleted` is still emitted with the count of items processed so far. This prevents startup from blocking indefinitely. | ||||||||||||||||||||||||||||||||||||||||||
| </Note> | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ### DirtyState | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| **Emitted:** When the server sends an `<ib><dirty type="..." timestamp="...">` marker, telling the client one of its cached protocol domains is stale server-side. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ```rust | ||||||||||||||||||||||||||||||||||||||||||
| #[derive(Debug, Clone, Serialize, bon::Builder)] | ||||||||||||||||||||||||||||||||||||||||||
| #[non_exhaustive] | ||||||||||||||||||||||||||||||||||||||||||
| pub struct DirtyState { | ||||||||||||||||||||||||||||||||||||||||||
| pub dirty_type: DirtyType, | ||||||||||||||||||||||||||||||||||||||||||
| pub timestamp: Option<u64>, | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| **Fields:** | ||||||||||||||||||||||||||||||||||||||||||
| - `dirty_type` - The stale domain, mirroring `wacore::iq::dirty::DirtyType`: `AccountSync`, `Groups`, `SyncdAppState`, `NewsletterMetadata`, or `Other(String)` for a wire value the client doesn't otherwise recognize. | ||||||||||||||||||||||||||||||||||||||||||
| - `timestamp` - `Option<u64>`, `None` if the `<dirty>` stanza omitted the `timestamp` attribute. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| <Note> | ||||||||||||||||||||||||||||||||||||||||||
| This is a pure observability hook — it does not replace or gate the client's built-in handling. The client always sends the matching `<clean>` IQ (throttled behind offline-sync completion for `Groups`/`NewsletterMetadata`, per `WAWebHandleDirtyBits`) and, for `SyncdAppState`, re-syncs all app-state collections, exactly as it did before this event existed. `DirtyState` fires first, right before that built-in work starts, so a handler can refresh its own domain-specific derived state (e.g. invalidate a local groups cache) without parsing raw `<ib>` stanzas via [`RawNode`](#raw-stanza-events) or racing the client's own resync. | ||||||||||||||||||||||||||||||||||||||||||
| </Note> | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+2000
to
+2017
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Apply documentation guidelines for conciseness and perspective. The current description contains long, complex sentences and uses the third person (e.g., "telling the client", "so a handler can"). As per coding guidelines, documentation in 📝 Proposed refactor for documentation clarity-**Emitted:** When the server sends an `<ib><dirty type="..." timestamp="...">` marker, telling the client one of its cached protocol domains is stale server-side.
+**Emitted:** When the server sends an `<ib><dirty type="..." timestamp="...">` marker. This tells your client that a cached protocol domain is stale on the server.
```rust
#[derive(Debug, Clone, Serialize, bon::Builder)]
#[non_exhaustive]
pub struct DirtyState {
pub dirty_type: DirtyType,
pub timestamp: Option<u64>,
}Fields: 📝 Committable suggestion
Suggested change
🤖 Prompt for AI AgentsSource: Coding guidelines |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| **Example:** | ||||||||||||||||||||||||||||||||||||||||||
| ```rust | ||||||||||||||||||||||||||||||||||||||||||
| use wacore::iq::dirty::DirtyType; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Event::DirtyState(DirtyState { dirty_type, timestamp, .. }) => { | ||||||||||||||||||||||||||||||||||||||||||
| match dirty_type { | ||||||||||||||||||||||||||||||||||||||||||
| DirtyType::Groups => println!("groups cache is stale (as of {timestamp:?})"), | ||||||||||||||||||||||||||||||||||||||||||
| DirtyType::SyncdAppState => println!("app-state re-sync incoming"), | ||||||||||||||||||||||||||||||||||||||||||
| other => println!("dirty: {other:?} at {timestamp:?}"), | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ## Device Events | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ### DeviceListUpdate | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -2611,4 +2646,4 @@ async fn handle_event(event: &Event, client: Arc<Client>) -> Result<()> { | |||||||||||||||||||||||||||||||||||||||||
| <Card title="Client API" icon="code" href="/api/client"> | ||||||||||||||||||||||||||||||||||||||||||
| Complete client API reference | ||||||||||||||||||||||||||||||||||||||||||
| </Card> | ||||||||||||||||||||||||||||||||||||||||||
| </CardGroup> | ||||||||||||||||||||||||||||||||||||||||||
| </CardGroup> | ||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ordering does not prevent a race for the default Bot API:
EventDelivery::Concurrentspawns closure callbacks on separate tasks, so dispatch returns and the built-in clean/resync work can start before aDirtyStatecallback runs or finishes. Only an inline struct-basedEventHandlerexecutes before dispatch returns, so the note should not broadly promise that handlers can refresh derived state without racing the client's resync.Useful? React with 👍 / 👎.