Cancellation token injection in ManagedMqttClient
Describe the feature request
I'm working to integrate MQTTnet in an environment where I need to have control over the shutdown process, and generally I would use cancellation tokens to handle this. However, I'm using the ManagedMqttClient and its current implementation does not seem to allow any injection of cancellation tokens, which limits my ability to gracefully handle interruptions and terminations.
Which project is your feature request related to?
- ManagedClient
Describe the solution you'd like
I would like the ability to inject custom cancellation tokens into MQTTnet's client processes, simply as an optional parameter to accept a CancellationToken in relevant methods, most likely in startup methods of each client.
Example
// ... with a cancellationToken already available
var client = new MqttFactory().CreateManagedMqttClient();
client.StartAsync(cancellationToken);
If the cancellation token signals a cancellation, I'd expect MQTTnet to flush all enqueued messages, either by publishing them or ingesting them in configured storage, and terminate its connections.
Describe alternatives you've considered
Please advise on alternatives I should consider for this as I want to be sure that the ManagedMqttClient is able to cleanly shut down based on terminations that are triggered from outside of MQTTnet.
Additional context
Allowing for custom cancellation tokens can provide more benefits, such as more robust error handling and more controlled redeployments.
Are you concerned with doing shutdown or cancellation during startup?
-
If you are just concerned with shutdown, i thought that was accomplished using
client.Dispose()orclient.StopAsync()I don't believe using a cancellation token to trigger shutdown would be an especially common API design. You can setup shutdown from a CancellationToken yourself, if that's how you would like to do it though:
var client = new MqttFactory().CreateManagedMqttClient(); cancellationToken.Register(()=>client.Dispose()); -
If you want to pass a CancellationToken to
StartAsync(), it looks like the function is synchronous unless storage is configured. It would not actually affect shutdown though.There is an internal cancellationToken that deals with shutdown, but i don't get the impression that you would want to mix that CancellationTokenSource with one passed in as an argument. You would call Dispose() to trigger this internal cancellation token.
When storage is configured, the loading of storage seems to be asynchronous but the existing interface doesn't accept a cancellation token argument. To pass a CancellationToken down this would become a breaking change for any implementations of IManagedMqttClientStorage. It probably isn't an especially challenging break but certainly complicates the change.
It seems like it would make sense to be able to interrupt the storage loading process in cases where it runs for a long time. But, you could probably accomplish the same thing by hooking cancellation up to the storage system directly, and outside of the ManagedMqttClient.
With the special needs you have it might be better to use the regular client instead and build your requirements around that client instead. The managed client is only a wrapper around the regular client.