Перейти к основному содержимому
Эта страница ещё не переведена

Ниже показан английский оригинал.

retry

retry() leaves a delivery unacknowledged: it comes back when a persistent session resumes, never within the connection.

The outcome asks the broker for a negative acknowledgement, and MQTT has none. The runtime logs the refusal and moves on, and nothing acknowledges the delivery later. At QoS 1 and 2 the server keeps the message in the client's session. It sends the message again when the service connects with the same client id and the session is still there: clean_start(false) and a session_expiry longer than the gap. With a clean start, or once the session expired, the message is gone; at QoS 0 it is gone at once. Until the connection ends, the delivery holds one slot of the receive_maximum window, 1000 by default. When the window is full of unacknowledged deliveries, the server sends no more QoS 1 or 2 messages on that connection. For a retry within the session, a handler returns retry_after. A registration with a cap turns retry() into an immediate copy of the message instead.

Example​

An update that needs a reboot waits for the next session of the device agent.

/// An update that needs a reboot waits for the next session: the handler leaves it
/// unacknowledged, and the server hands it back when the device agent reconnects.
#[subscriber(MqttTopic::new("devices/dev42/firmware").qos(Qos::AtLeastOnce))]
async fn install(update: &Firmware) -> HandlerOutcome {
if update.needs_reboot {
tracing::info!(update.version, "update left for the next session");
return HandlerOutcome::retry();
}
tracing::info!(update.version, "update installed");
HandlerOutcome::ack()
}

The broker keeps the session for a day after the connection ends:

#[ruststream::app]
fn app() -> impl App {
service(MqttBroker::new(
"mqtt://localhost:1883",
"device-agent-dev42",
))
}

/// The session outlives the connection by a day, so what the handler left unacknowledged comes
/// back when the agent connects again within it, under the same client id.
fn service(broker: MqttBroker) -> RustStream {
RustStream::new(AppInfo::new("device-agent", "0.1.0")).with_broker(
broker
.clean_start(false)
.session_expiry(Duration::from_hours(24)),
|b| {
b.include(install);
},
)
}