message.DeliveryCount should increment when same message received again
In module to module communication when sender module send the message and receiver module receive the message but due to some exception receiver module return MessageResponse.None (We set MessageResponse.None when module throw any exception). due to MessageResponse.None receiver module receive same message again and again but message.DeliveryCount remain zero("0").
As per business requirement we need to verify failed message 3 times. if same message failed 3 times then we set *MessageResponse.Abandoned*
So could you please let me know the reason for this..
We are using
For reproduce this situation Please look into receiver module code snippet:
In following receiver module if temprature > 30 then we throw the exception.
namespace RouteCommunication
{
using System;
using System.Runtime.Loader;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Client.Transport.Mqtt;
using Newtonsoft.Json;
class Program
{
static int counter;
static void Main(string[] args)
{
Init().Wait();
var cts = new CancellationTokenSource();
AssemblyLoadContext.Default.Unloading += (ctx) => cts.Cancel();
Console.CancelKeyPress += (sender, cpe) => cts.Cancel();
WhenCancelled(cts.Token).Wait();
}
public static Task WhenCancelled(CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<bool>();
cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).SetResult(true), tcs);
return tcs.Task;
}
static async Task Init()
{
MqttTransportSettings mqttSetting = new MqttTransportSettings(TransportType.Mqtt_Tcp_Only);
ITransportSettings[] settings = { mqttSetting };
ModuleClient ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings);
await ioTHubModuleClient.OpenAsync();
Console.WriteLine("Route Hub module client initialized.");
Console.WriteLine("SetInputMessageHandlerAsync.");
await ioTHubModuleClient.SetInputMessageHandlerAsync("input1", PipeMessage, ioTHubModuleClient);
}
static async Task<MessageResponse> PipeMessage(Message message, object userContext)
{
try
{
int counterValue = Interlocked.Increment(ref counter);
var moduleClient = userContext as ModuleClient;
if (moduleClient == null)
{
throw new InvalidOperationException("UserContext doesn't contain " + "expected values");
}
Console.WriteLine("Received byte");
byte[] messageBytes = message.GetBytes();
Console.WriteLine("Byte Length" + messageBytes.Length.ToString());
string messageString = Encoding.UTF8.GetString(messageBytes);
Console.WriteLine($"Received message: {counterValue}, Body: [{messageString}]");
Console.WriteLine($"Mesage Delivery Count: {message.DeliveryCount}");
var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
ValidateTemprature(messageBody.machine.temperature);
var pipeMessage = new Message(messageBytes);
foreach (var prop in message.Properties)
{
pipeMessage.Properties.Add(prop.Key, prop.Value);
}
await moduleClient.SendEventAsync("output1", pipeMessage);
Console.WriteLine("Received message sent");
return MessageResponse.Completed;
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
ModuleClient moduleClient = (ModuleClient)userContext;
return message.DeliveryCount > 3 ? MessageResponse.Abandoned : MessageResponse.None;
}
}
private static void ValidateTemprature(double temprature)
{
if (temprature > 30)
{
throw new ArgumentException("temprature cannot be greater than 30", "original");
}
}
}
}
Hi Team,
Could you please response on this as we are facing this issue on Production
Hi, sorry for the delay on this, I'm still digging into how the C# SDK layer deals with MessageResponse.None, but so far it seems like the response just goes unhandled, and that might not play well with Edge.
What protocol is the receiving module using to connect to Edge?
EDIT:
Okay, after digging into this property some more, it looks like it's not actually supported. I don't see anything in either Edge nor the C# SDK that increments it.
Is there any particular documentation you guys found that indicates the property should be used as such? If so please provide a link and we'll make a call on whether the property will be supported going forward.
In the meantime, I'd recommend just creating a dictionary of MessageId -> FailedCount in the receiving module implementation to keep track of when to Abandon the message.
according to this link
Description : Number of times the message has been previously delivered
It means receiving the same messages multiple times will increase the delivery count of the message
Thanks, I'll file a bug internally to track this for future releases. For now you'll need to keep track of the failure counts by message ID in the module implementation.
Most helpful comment
Thanks, I'll file a bug internally to track this for future releases. For now you'll need to keep track of the failure counts by message ID in the module implementation.