Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 66 additions & 13 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Example
root.subscribeToStructure((name, change) => {
if (change === studio.api.structure.ADD)
subscribeToApp(name);
if (change === studio.api.structure.RECONNECT)
console.log(`${name} restarted, subscriptions intact`);
});
}).catch(err => console.error("Connection failed:", err));

Expand All @@ -61,6 +63,41 @@ Benefits
- Simplified firewall configuration - only one port needs to be opened
- SSH port forwarding - forward a single port to access entire CDP system

Structure Events
----------------

On the root node, ``subscribeToStructure`` tracks application lifecycle with three event types:

- ``studio.api.structure.ADD`` (1) — An application appeared for the first time
- ``studio.api.structure.REMOVE`` (0) — An application went offline
- ``studio.api.structure.RECONNECT`` (2) — An application restarted (was seen before, went offline, came back)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doc makes it look like subscribeToStructure is only meant to detect application starts and stops but this is only one of the use cases. It can also detect when nodes (e.g. CDPOperators) are added and deleted during runtime


On other nodes, ADD and REMOVE fire when children are added or removed at runtime.
RECONNECT only fires at the root level.

When an app restarts, the client automatically restores value and event subscriptions,
so user code does not need to re-subscribe. RECONNECT is informational — use it for
logging or UI updates.

.. code:: javascript

client.root().then(root => {
root.subscribeToStructure((appName, change) => {
if (change === studio.api.structure.ADD) {
console.log(`New app online: ${appName}`);
client.find(appName + '.CPULoad').then(node => {
node.subscribeToValues(v => console.log(`[${appName}] CPULoad: ${v}`));
}).catch(err => console.error(`Failed to find ${appName}.CPULoad:`, err));
}
if (change === studio.api.structure.REMOVE) {
console.log(`App offline: ${appName}`);
}
if (change === studio.api.structure.RECONNECT) {
console.log(`App restarted: ${appName}, subscriptions intact`);
}
});
}).catch(err => console.error("Connection failed:", err));

API
---

Expand Down Expand Up @@ -325,31 +362,46 @@ client.root()
// use the system INode object to access connected structure.
});

client.find(path)
^^^^^^^^^^^^^^^^^
client.find(path, options)
^^^^^^^^^^^^^^^^^^^^^^^^^

- Arguments

path - Path of the object to look for.
path - Dot-separated path to target node (e.g. ``'App2.CPULoad'``).

options - Optional. Without this, find() waits indefinitely for the app to appear.
``{ timeout: milliseconds }`` to limit wait time.
``{ timeout: 0 }`` to fail immediately if the app is not available.

- Returns

Promise containing requested INode object when fulfilled.

- Restriction
- Behavior

The requested node must reside in the application client was connected to.
When no timeout option is provided, waits indefinitely for the target application to appear.
If the application is already available, resolves immediately. No prior ``root()`` call is needed — ``find()`` triggers
the connection internally.

- Usage
- Examples

The provided path must contain dot separated path to target node. **Root node is not considered part of the path.**
.. code:: javascript

- Example
// Waits indefinitely for App2 to appear
client.find("App2.CPULoad").then(function (load) {
load.subscribeToValues(function (value) {
console.log("CPULoad:", value);
});
});

.. code:: javascript
// Wait up to 5 seconds
client.find("App2.CPULoad", { timeout: 5000 }).catch(function (err) {
console.log(err.message); // "App2 not found within 5000ms"
});

client.find("MyApp.CPULoad").then(function (load) {
// use the load object referring to CPULoad in MyApp
// Fail immediately if not available (old behavior)
client.find("App2.CPULoad", { timeout: 0 }).catch(function (err) {
console.log("Not available right now");
});

client.close()
Expand Down Expand Up @@ -604,8 +656,9 @@ node.subscribeToStructure(structureConsumer)

- Usage

Subscribe to structure changes on this node. Each time child is added or removed from current node
structureConsumer function is called with the name of the node and change argument where ADD == 1 and REMOVE == 0.
Subscribe to structure changes on this node. Each time a child is added or removed,
structureConsumer is called with the child name and change (ADD == 1, REMOVE == 0).
On the root node, RECONNECT (2) fires when a previously-seen application restarts.

node.unsubscribeFromStructure(structureConsumer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
Loading
Loading