Reputation: 45
I have a service bus trigger function that attempts to retrieve an order and if the order is not available (not found) it will copy the service bus message and resubmit it with a 5 min enqueue time. It will retry 3 times before going to dead letter.
It has been working fine, but with the upgrade to .NET 8, I'm seeing issues with it. As you can see from the screenshot shown below, the log message includes the transaction number on the first resubmit, but on the next retry the transaction number is no long available, which I assume means that new ServiceBusMessage(message)
no longer copies all the custom properties. Also, the automatic incrementing of the retry counter no longer works.
Has anyone else found this to be an issue with .NET 8 upgrade?
This is the code that I currently have for the retry if the transaction is not found.
catch (Exception ex) when (ex.Message.Contains("Not Found"))
{
var parsedMessage = _messageReceiver.ParseServiceBusMessage(message);
var retryCount = message.DeliveryCount;
if (retryCount <= _config.MaxRetryCount)
{
// delete current sb message and create a new one to resubmit
using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
await _messageReceiver.CompleteMessageAsync(message, messageReceiver);
var newMessage = new ServiceBusMessage(message);
newMessage.ScheduledEnqueueTime = DateTime.UtcNow.AddMinutes(_config.HoldServiceBusMsgMinutes);
await _serviceBusClient.SendAsync(newMessage);
_logger.LogInformation("Retry counter: {retryCount} Processing order number {transactionNumber} resulted in not found condition. Resubmitted to service bus", retryCount, parsedMessage.Transaction);
}
}
else
{
_logger.LogError("Max retry count reached for transaction number {transactionNumber}", parsedMessage.Transaction);
await _messageReceiver.DeadletterMessageAsync(message, messageReceiver, ex);
}
}
If anyone has any suggestions it would be greatly appreciated!
Upvotes: -1
Views: 110
Reputation: 11383
Retry works for me using below code:
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace RithApp
{
public class Function1
{
private readonly ILogger<Function1> ri_lg;
public Function1(ILogger<Function1> logger)
{
ri_lg = logger;
}
[Function(nameof(Function1))]
public async Task Run(
[ServiceBusTrigger("myqueue", Connection = "rithwikserviceconnection")]
ServiceBusReceivedMessage message,
ServiceBusMessageActions rimsgact)
{
ri_lg.LogInformation("Hello Rithwik, the Message is : {body}", message.Body);
try
{
bool ri_of = false;
var retryCount = message.ApplicationProperties.ContainsKey("RetryCount")
? (int)message.ApplicationProperties["RetryCount"]
: 0;
var ri_tn = message.ApplicationProperties.ContainsKey("ri_tn")
? message.ApplicationProperties["ri_tn"].ToString()
: "Unknown";
if (!ri_of && retryCount < 3)
{
ri_lg.LogWarning($"Hello Rithwik, Order not found for transc {ri_tn}.and retrying it again, the Retry Count: {retryCount}");
retryCount++;
var rith_msg = new ServiceBusMessage(message.Body)
{
ContentType = message.ContentType,
CorrelationId = message.CorrelationId,
MessageId = Guid.NewGuid().ToString(),
ScheduledEnqueueTime = DateTime.UtcNow.AddMinutes(1)
};
foreach (var prp in message.ApplicationProperties)
{
rith_msg.ApplicationProperties[prp.Key] = prp.Value;
}
rith_msg.ApplicationProperties["RetryCount"] = retryCount;
var sbc = new ServiceBusClient(Environment.GetEnvironmentVariable("rithwikserviceconnection"));
var ri_sen = sbc.CreateSender("myqueue");
await ri_sen.SendMessageAsync(rith_msg);
ri_lg.LogInformation($"Reetry count {retryCount}.");
await rimsgact.CompleteMessageAsync(message);
}
else if (retryCount >= 3)
{
ri_lg.LogError($"Hello Rithwik, Max retry attempts reached for transaction {ri_tn}. Moving to dead-letter.");
var Dead_props = new Dictionary<string, object>
{
{ "Reason for dead lettring ", "3 retries happened" },
{ "Des", "Order is not found" }
};
await rimsgact.DeadLetterMessageAsync(message, Dead_props);
}
}
catch (Exception ri)
{
ri_lg.LogError($"Hello Rthwik, Erro is : {ri.Message}");
throw;
}
}
}
}
csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ServiceBus" Version="5.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
</ItemGroup>
</Project>
Output:
In Service Bus Dead Lettered Queue:
Upvotes: 0