This allows plugins to add controls to nodes that already have some
controls set by other plugin. Previously only the last plugin that
sets the controls in the node would have its controls visible. That
was because of NodeControls' Merge function that actually weren't
merging data from two inputs, but rather returning data that was newer
and discarding the older one.
This commit makes the LatestMap type a sort of a base class, that
should not be used directly. This also adds a generator for LatestMap
"concrete" types with a specific data type in the LatestEntry.
Plugins are queried for reports two times in a second. That's often
enough to get the shortcut reports. The reports are sent together with
the response.
It exposes a button that allows switching between showing an iowait
statistics and an idle statistics. When the button is pressed it
should be replaced with other button. The button is shown in the host
node.
This is a rather nasty case as it shows several problems:
- Button control races
- The way the NodeControl currently works creates races between
plugins adding buttons to the same node. This is because
NodeControls are not really merged, but rather one of the two are
chosen based on a NodeControls' timestamps, so the older one is
thrown away entirely. In the end GUI can switch randomly between
showing controls from one plugin or from another.
- Showing outdated statistics
- When pressing the button to switch to show the other statistics,
the old ones are still shown for several seconds.
- Slowness of the updates in GUI
- Pressing the button yields no immediate reaction. Changes happen
after several seconds. Probably related to the previous point.
Thanks to that, plugins can react to requests from controls they
exposed.
To make it work, plugins registry modifies each plugin's report by
prepending the plugin ID to the control name the plugin has exposed
before sending it to the app. Then the registry installs the control
request handler for this faked control name, which forwards the
request to the correct plugin.
This adds a new API endpoint to plugins next to "/report" - a
"/control" entry. The body of the request is the JSON-encoded
xfer.Request instance.
It is not a singleton anymore. Instead it is an object with a registry
backend. The default registry backend is provided, which is equivalent
to what used to be before. Custom backend can be provided for testing
purposes.
The registry also supports batch operations to remove and add handlers
as an atomic step.
We will want to put plugin id in a control id, which is sent to an app
and then to GUI. When we get a control request from GUI, we will want
to extract the plugin ID from the control name. To do it unambiguously
we need some separator made of chars that are not allowed in a plugin
name. This is to avoid the situation when there are two plugins:
"Plugin" and "PluginFoo". "Plugin" exposes a control named
"FooControl" and "PluginFoo" exposes a control named "Control". Faking
the control names which will be sent to the app would result in two
"PluginFooControl".
One possible option for plugin ID and control name separator would be
"/", but that won't work, since the request sent from GUI to the app
to <probe>/<node>/<control> would actually be
<probe>/<node>/<plugin>/<control> and as such wouldn't match the URL
template in RegisterControlRoutes().
We have divergent versions of this script across repos.
This particular version comes from 6334836@scope.
We in particular want this version's changes to support branches
with a '/' character in them.
- Within certain bounds. Still have min-label size, mainly effects nodes
that get really big.
- Set a max size on nodes too, really big ones lose their border.