Polly
Polly copied to clipboard
Unhandled Stack Overflow Exception
I'm a brand new Polly user so I'm hoping I'm missing something simple but I'm getting an unhandled stack overflow exception in the below code and can't figure the reason why it is doing this. I'm using Polly to handle code that I wrote that uses a custom queue system to constantly download the latest financial data for the stock markets across multiple computers. Here is my reproducible code below and I'm using C# 10 with .Net 6 Update 7, EfCore 6 and Visual Studio 2022. If I'm missing anything from my code please let me know. A couple of things to keep in mind. I'm only having issues with the dequeue portion so I didn't include the other half of my queue code but this should be enough to reproduce the error. I also added extra try catch blocks to try to fix the exception but it still didn't work.
public static async Task<Symbol> HandleNetworkTaskDequeue(string symbol)
{
try
{
using var context = new dbContext();
var wrap = BuildPollyPolicy<Symbol>(context);
return wrap.Execute(() =>
{
try
{
// exception happens here
var item = context.PendingQueues.FromSqlRaw("usp_dequeuePendingSymbol @p0", symbol).AsEnumerable().FirstOrDefault();
return item != null ? new Symbol { Symbol1 = item.Symbol, Market = item.Market } : null;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return null;
});
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return null;
}
public static PolicyWrap<T> BuildPollyPolicy<T>(dbContext context, int maxRetries = 10)
{
RetryPolicy<T> retryPolicy = null;
FallbackPolicy<T> fallbackPolicy = null;
PolicyWrap<T> wrap = null;
try
{
retryPolicy = Policy<T>.Handle<Exception>().WaitAndRetry(maxRetries, retryAttempt => TimeSpan.FromSeconds(1), async (exception, timeSpan, retryCount, con) =>
{
Console.WriteLine(exception.Message);
});
fallbackPolicy = Policy<T>.Handle<Exception>().Fallback(fallbackValue: default, onFallback: (exc, con) => Console.WriteLine(exc.Message));
wrap = fallbackPolicy.Wrap<T>(retryPolicy);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return wrap;
}
public class Symbol
{
public int Id { get; set; }
public string Symbol1 { get; set; }
public string Market { get; set; }
}
public class PendingQueue
{
public DateTime Date { get; set; }
public string Symbol { get; set; }
public string Market { get; set; }
public string Computer { get; set; }
}
CREATE PROCEDURE [dbo].[usp_dequeuePendingSymbol]
@symbol VARCHAR (7)
AS
SET NOCOUNT ON;
DECLARE @now AS DATETIME;
SET @now = getutcdate();
WITH cte
AS (SELECT TOP (1) Symbol,
Market,
Computer,
Date
FROM PendingQueue WITH (ROWLOCK, READPAST)
WHERE Date < @now
AND Symbol = @Symbol
ORDER BY Date)
DELETE cte
OUTPUT deleted.Symbol, deleted.Market, deleted.Computer, deleted.Date;
There's not enough here to repo as-is (where's the DbContext code, for instance), but looking at what you've provided you aren't using the fallback in your Policy Wrap.
Do you have a stack trace for the method that's being called in a cycle that's causing the stack overflow? .NET 6 should be able to output at least the name of the method for you when the program terminates.
Otherwise from what you've provided so far I can't spot a loop that would cause a stack overflow.
Sorry, my mistake you are using the fallback. It's just using a different style of configuring it than I'm used to (I use the Policy.Wrap(a, b, c) style) and I only saw the one argument so thought it was wrong.
If you are still experiencing this problem, please open a new issue with a more complete code sample that can be run and debugged.