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
Browse filesBrowse the repository at this point in the historyBrowse files
dirkwa
committed
docs(plugins): recommend sourcePolicy:all for correction plugins
excludeSelf runs the priority cascade on the plugin's own input feed, so
when the user ranks a correction plugin above its upstream source the
real source is throttled to the fallback timeout instead of arriving at
full rate. A correction plugin's input must be independent of
prioritisation: subscribe with sourcePolicy:'all' and skip updates whose
$source is the plugin id; prioritisation then applies only to consumers.
Note that $source is a property of the update, not of each value.
A derived-data plugin often consumes one or more upstream sources for a path and publishes an improved value on the same path under its own label. With the user's [source priority](../../setup/source-priority.md) ranking the plugin's output above the upstream sources, downstream consumers get the improved value. But the plugin itself cannot just subscribe with `sourcePolicy: 'preferred'` — that returns the priority winner, which is the plugin's own output, creating a feedback loop. Subscribing with `sourcePolicy: 'all'` avoids the loop but loses the priority cascade across the upstream sources.
188
+
A plugin may want a priority-resolved view of a path with one or more sources removed from the cascade — for example to see the preferred upstream source while ignoring a known-bad device. `excludeSources` / `excludeSelf` provide that: the subscription still receives a single priority-resolved value per path, but the cascade runs without the excluded refs.
189
189
190
-
`excludeSources` removes the listed source refs from the priority cascade's candidate set. The subscription still receives a single priority-resolved value per path; the cascade just runs without the excluded sources, with the same fallback semantics the user configured.
190
+
> **Note:** Because the cascade runs on the subscription's feed, this delivers a single priority-resolved value — and if the user ranks the plugin itself above the upstream source, that source is held to the fallback timeout on the plugin's own input. That is the right behaviour for a plugin that wants _the preferred remaining upstream value_, but **not** for a correction/transform plugin that must see every raw sample at full rate — for that case see [Correction and transform plugins](#correction-and-transform-plugins) below, which uses `sourcePolicy: 'all'`.
191
+
192
+
The same fallback semantics the user configured still apply across the remaining sources:
191
193
192
194
```javascript
193
195
let localSubscription = {
@@ -267,10 +269,13 @@ app.handleMessage(
267
269
268
270
A common pattern is a plugin that reads an upstream value on a path, applies a correction or transform, and publishes an improved value on the **same** path under its own label — a speed-through-water heel correction, a calibration offset, and so on. The user then ranks the plugin's output above the raw source in [source priority](../../setup/source-priority.md), so downstream consumers get the corrected value.
269
271
270
-
For this pattern, **subscribe with `excludeSelf`** as described in [Excluding Sources](#excluding-sources-excludesources--excludeself). Do **not** use `registerDeltaInputHandler`:
272
+
A correction plugin needs its **input** at full rate, _independent_ of the priority ranking — you correct every reading from the upstream source, not just whichever one a cascade would currently prefer — while the user's ranking decides what _consumers_ see. Subscribe with **`sourcePolicy: 'all'`** and skip your own output in the callback:
273
+
274
+
-`sourcePolicy: 'all'` delivers every source at full rate with no cascade on your input. Skip updates whose `$source` is your own `plugin.id` so you don't reprocess your output. The global priority cascade still applies to consumers, so the user's ranking of your output works as expected.
275
+
276
+
Do **not** use `registerDeltaInputHandler` for this: delta input handlers run **after** source-priority filtering, so once the user ranks your output above the raw source the filter removes the raw value before your handler sees it — the handler stops firing, your value goes stale, the path falls back to the raw source, your handler fires once, and the path oscillates.
271
277
272
-
- Delta input handlers run **after** source-priority filtering. Once the user ranks your output above the raw source, the priority filter removes the raw source's value before your handler sees it. Your handler stops being triggered, your corrected value goes stale and falls back to the raw source, the raw source flows again, your handler fires once — and the path oscillates.
273
-
- An `excludeSelf` subscription reads every source on the path regardless of ranking (so the raw source always reaches you) while masking out your own output (so you don't re-process it). The user's priority ranking still decides which value is canonical for everyone else.
278
+
`excludeSelf` (see [Excluding Sources](#excluding-sources-excludesources--excludeself)) is a different tool and **not** what you want for a full-rate correction. It runs the priority cascade on your input feed, so it delivers a single ranked-and-throttled upstream value rather than every reading: with the user ranking your plugin rank-0, the real source is held as a lower-ranked fallback and only reaches you after the fallback timeout. `excludeSelf` fits a plugin that wants _the preferred remaining upstream value_ (e.g. "show source B, fall back to A, never my own C"), not one that corrects each raw sample.
0 commit comments