Add API spec for find() sibling wait and RECONNECT structure event#23
Add API spec for find() sibling wait and RECONNECT structure event#23stefanrammo wants to merge 1 commit intomainfrom
Conversation
Specifies two changes to improve multi-app usability: 1. find() waits for sibling apps by default instead of failing immediately 2. subscribeToStructure gets a RECONNECT event (value 2) to distinguish app restarts from first-time appearances Includes 7 use case examples, backwards compatibility analysis, and comparison with Java/C++ StudioAPI clients. CDP-6069
| ```javascript | ||
| client.find('App2.CPULoad') // waits (default timeout) for App2 to appear | ||
| client.find('App2.CPULoad', { timeout: 5000 }) // waits up to 5s | ||
| client.find('App2.CPULoad', { timeout: 0 }) // fails immediately if App2 not available (old behavior) |
There was a problem hiding this comment.
I think should allow for no timeout. E.g. if one has a panel that only is meant to show some App2 value then indefinite hang might be fine. Maybe that should be even the default?
| - **Immediate fail:** `{ timeout: 0 }` preserves the old behavior — rejects immediately if the app is not available. | ||
| - **No prior `root()` required:** `find()` must trigger the connection internally if not already connected. Callers should not need to call `root()` first. | ||
| - **Direct mode guard (immediate fail only):** When using `{ timeout: 0 }` in direct mode (no proxy protocol), `find()` rejects with `"AppName is not available"` if the app was previously connected but is now disconnected. This prevents returning stale cached nodes whose underlying WebSocket is down. When waiting (default), this guard does not apply — the wait resolves when the app reconnects. In proxy mode, the primary connection maintains the node tree so the guard is not needed. | ||
| - **Direct mode discovery:** In direct mode, `find()` triggers on-demand structure refreshes (every 2s while waiting) to discover new siblings. In proxy mode, discovery is real-time via `ServicesNotification`. |
There was a problem hiding this comment.
"every 2s while waiting" - polling should not be necessary, CDP will notify of any new apps appearing. Although I can't remember if one had to subscribe to root node structure or if the notifications come automatically
There was a problem hiding this comment.
I think how it worked was that CDP app sends invalidate on root node (that is a structure_change_response with id of 0). And after receiving invalidate of root, CDP should poll for structure change to find sibling apps.
| - **Proxy mode:** Sibling app disappears from proxy services, then reappears — fires REMOVE then RECONNECT. | ||
| - **Direct mode:** Direct WebSocket connection drops, then reconnects — fires REMOVE then RECONNECT. | ||
|
|
||
| **Direct mode discovery:** Without this change, `subscribeToStructure` in direct mode does not discover apps that start after the subscription — it only sees apps that were already connected. This change adds periodic structure polling (every 2s) while subscribers exist, so that ADD/RECONNECT events fire for late-starting apps in direct mode. In proxy mode, discovery is real-time via `ServicesNotification` so no polling is needed. Polling stops automatically when all subscribers unsubscribe or `client.close()` is called. |
There was a problem hiding this comment.
Even in direct mode CDP apps notify their siblings are started/stopped. You don't need to poll. One could only consider automatic reconnect for resiliency when first CDP app reports siblings but connection had failed (some networking issue or something).
| - **Immediate fail:** `{ timeout: 0 }` preserves the old behavior — rejects immediately if the app is not available. | ||
| - **No prior `root()` required:** `find()` must trigger the connection internally if not already connected. Callers should not need to call `root()` first. | ||
| - **Direct mode guard (immediate fail only):** When using `{ timeout: 0 }` in direct mode (no proxy protocol), `find()` rejects with `"AppName is not available"` if the app was previously connected but is now disconnected. This prevents returning stale cached nodes whose underlying WebSocket is down. When waiting (default), this guard does not apply — the wait resolves when the app reconnects. In proxy mode, the primary connection maintains the node tree so the guard is not needed. | ||
| - **Direct mode discovery:** In direct mode, `find()` triggers on-demand structure refreshes (every 2s while waiting) to discover new siblings. In proxy mode, discovery is real-time via `ServicesNotification`. |
There was a problem hiding this comment.
I think how it worked was that CDP app sends invalidate on root node (that is a structure_change_response with id of 0). And after receiving invalidate of root, CDP should poll for structure change to find sibling apps.
| **Direct mode discovery:** Without this change, `subscribeToStructure` in direct mode does not discover apps that start after the subscription — it only sees apps that were already connected. This change adds periodic structure polling (every 2s) while subscribers exist, so that ADD/RECONNECT events fire for late-starting apps in direct mode. In proxy mode, discovery is real-time via `ServicesNotification` so no polling is needed. Polling stops automatically when all subscribers unsubscribe or `client.close()` is called. | ||
|
|
||
| - **Backwards compatible for `=== ADD` checks:** Existing code checking `change === studio.api.structure.ADD` still works — new apps still get ADD. Only restarted apps get RECONNECT. | ||
| - **Not compatible with `!== ADD` patterns:** Code that treats any non-ADD change as REMOVE (e.g. `if (change !== ADD) handleRemove()`) will incorrectly trigger on RECONNECT. Such code should be updated to check `change === REMOVE` explicitly. |
There was a problem hiding this comment.
I think we can update the version number to new major version and list the API changes. The RECONNECT sounds like a good change.
Specifies two changes to improve multi-app usability:
Includes 7 use case examples, backwards compatibility analysis, and comparison with Java/C++ StudioAPI clients.
CDP-6069