Check for pending disconnect in ThrowIfNotConnected

This might be a little controversial, but it worked for us to correct a problem in which messages get stuck in the managed client storage queue (and are thrown out of the regular message queue without being published!) in the case of a failed connection.  What we were seeing was that ManagedMqttClient.TryPublishQueuedMessage() was discarding a dequeued message without ever removing it from the storage queue because of an OperationCancelledException thrown by MqttClient.PublishAsync().  Tracing the code back, we found that when the connection is interrupted, after the timeout period MqttClient.InitiateDisconnect() would set the cancellation token, and the managed client would continue to try to publish, eventually calling through to MqttClient.SendAndReceiveAsync(), which would throw because the cancellation token is set.  Looking back over the code, we saw that MqttClient.PublishAsync() has a call to ThrowIfNotConnected() at the top, which told us that the intent was to not allow this function to be called after a disconnect.  But the disconnect was still pending, and the function wasn't behaving correctly in this state, so we reasoned that it's best to throw if the disconnect is pending.
This commit is contained in:
Paul Fake
2018-11-14 11:25:12 -05:00
committed by GitHub
parent e9df698a1f
commit a1e258eb24
+3 -3
View File
@@ -29,7 +29,7 @@ namespace MQTTnet.Client
internal Task _keepAliveMessageSenderTask;
private IMqttChannelAdapter _adapter;
private bool _cleanDisconnectInitiated;
private int _disconnectGate;
private long _disconnectGate;
public MqttClient(IMqttClientAdapterFactory channelFactory, IMqttNetLogger logger)
{
@@ -216,7 +216,7 @@ namespace MQTTnet.Client
private void ThrowIfNotConnected()
{
if (!IsConnected) throw new MqttCommunicationException("The client is not connected.");
if (!IsConnected || Interlocked.Read(ref _disconnectGate) == 1) throw new MqttCommunicationException("The client is not connected.");
}
private void ThrowIfConnected(string message)
@@ -551,4 +551,4 @@ namespace MQTTnet.Client
return Interlocked.CompareExchange(ref _disconnectGate, 1, 0) != 0;
}
}
}
}