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
Is your feature request related to a problem? Please describe.
with_qos on an inbound MQTT link has no effect. The value is stored in the link config, but both backends subscribe every inbound topic at QoS 1:
Native (rumqttc): native.rs subscribes with QoS::AtLeastOnce.
Embedded (mountain-mqtt): embedded/session.rs and embedded/tls.rs build every subscription with QualityOfService::Qos1.
A subscriber receives min(publish QoS, subscribe QoS), so:
with_qos(0): a high-rate telemetry link cannot opt out of acknowledgements. The broker still keeps state and waits for a PUBACK for every message.
with_qos(2): a QoS 2 publish still arrives at QoS 1, so it can be delivered twice after a reconnect. Only the native backend could honour QoS 2; mountain-mqtt rejects QoS 2 subscriptions.
Until #267, the MqttLinkExt::with_qos doc claimed "Inbound: the subscribe QoS". #267 corrects the doc and keeps the behaviour. Design 055 lists inbound subscribe QoS as a non-goal (§2).
Describe the solution you'd like
Subscribe each filter at the highest qos among the inbound links it stands for, default 1.
Since feat: wildcard inbound links (055) #267, one subscribed filter can stand for several links: Router::subscriptions() leaves out a filter another one covers, such as sensors/kitchen/temp under sensors/+/temp. The highest QoS among those links guarantees every covered link at least what it asked for.
The router therefore has to expose each subscribed filter's link configs. For example, subscriptions() could return Subscription { filter, links: Vec<Arc<[(String, String)]>> } instead of Arc<str>. Core does not interpret the config; the MQTT backends read qos.
The embedded backend caps at 1, and warn_unsupported_qos (today only outbound) also names each inbound route that asks for 2, once at build.
Both backends pass the per-filter QoS to their subscribe calls.
Tests:
A unit test that the highest qos wins and the default is 1.
An extension of the backend parity test: with with_qos(2) on a covered link, the native backend subscribes the covering filter at QoS 2 (the fake broker records the requested QoS) and the embedded backend at QoS 1.
Describe alternatives you've considered
Reject with_qos on inbound links at build(). Honest, but it removes a knob users reasonably expect from MQTT.
Subscribe each link's filter separately at its own QoS, without covering. Overlapping subscriptions deliver twice to MQTT 5 clients but once to MQTT 3.1.1 clients (measured against Mosquitto 2.0.18, 055 §3.1), so the two backends would disagree.
Additional context
The design text for this came from an earlier draft of 055 §5.7 ("Subscribe QoS"), removed when the scope was narrowed. See the history of docs/design/055-wildcard-inbound-links.md.
Is your feature request related to a problem? Please describe.
with_qoson an inbound MQTT link has no effect. The value is stored in the link config, but both backends subscribe every inbound topic at QoS 1:rumqttc):native.rssubscribes withQoS::AtLeastOnce.mountain-mqtt):embedded/session.rsandembedded/tls.rsbuild every subscription withQualityOfService::Qos1.A subscriber receives
min(publish QoS, subscribe QoS), so:with_qos(0): a high-rate telemetry link cannot opt out of acknowledgements. The broker still keeps state and waits for a PUBACK for every message.with_qos(2): a QoS 2 publish still arrives at QoS 1, so it can be delivered twice after a reconnect. Only the native backend could honour QoS 2;mountain-mqttrejects QoS 2 subscriptions.Until #267, the
MqttLinkExt::with_qosdoc claimed "Inbound: the subscribe QoS". #267 corrects the doc and keeps the behaviour. Design 055 lists inbound subscribe QoS as a non-goal (§2).Describe the solution you'd like
Subscribe each filter at the highest
qosamong the inbound links it stands for, default 1.Router::subscriptions()leaves out a filter another one covers, such assensors/kitchen/tempundersensors/+/temp. The highest QoS among those links guarantees every covered link at least what it asked for.subscriptions()could returnSubscription { filter, links: Vec<Arc<[(String, String)]>> }instead ofArc<str>. Core does not interpret the config; the MQTT backends readqos.warn_unsupported_qos(today only outbound) also names each inbound route that asks for 2, once at build.Tests:
qoswins and the default is 1.with_qos(2)on a covered link, the native backend subscribes the covering filter at QoS 2 (the fake broker records the requested QoS) and the embedded backend at QoS 1.Describe alternatives you've considered
with_qoson inbound links atbuild(). Honest, but it removes a knob users reasonably expect from MQTT.Additional context
docs/design/055-wildcard-inbound-links.md.