Closed devpioh closed 1 month ago
hello, I have this filter that works for me but the way I call the service is
Service.WithDeadline().MyMethod name
or
Service.WithCancellationToken().MyMethodName
using MagicOnion.Client;
namespace MagicT.Client.Filters;
/// <summary>
/// Filter for retrying client requests.
/// </summary>
internal sealed class RetryFilter : IClientFilter
{
private readonly int _maxRetryAttempts;
private readonly TimeSpan _retryDelay;
/// <summary>
/// Initializes a new instance of the <see cref="RetryFilter"/> class.
/// </summary>
/// <param name="maxRetryAttempts">The maximum number of retry attempts.</param>
/// <param name="retryDelay">The delay between retries.</param>
public RetryFilter(int maxRetryAttempts, TimeSpan retryDelay)
{
_maxRetryAttempts = maxRetryAttempts;
_retryDelay = retryDelay;
}
/// <summary>
/// Sends the request and retries if it fails.
/// </summary>
/// <param name="context">The request context.</param>
/// <param name="next">The next step in the filter pipeline.</param>
/// <returns>The response context.</returns>
public async ValueTask<ResponseContext> SendAsync(RequestContext context, Func<RequestContext, ValueTask<ResponseContext>> next)
{
var attempt = 0;
while (true)
{
try
{
return await next(context);
}
catch (Exception ex) when (attempt < _maxRetryAttempts)
{
attempt++;
Console.WriteLine($"Attempt {attempt} failed: {ex.Message}. Retrying in {_retryDelay.TotalSeconds} seconds...");
await Task.Delay(_retryDelay);
}
}
}
}
I have more examples in this template project if you are interested
hello, I have this filter that works for me but the way I call the service is
Service.WithDeadline().MyMethod name or Service.WithCancellationToken().MyMethodName
using MagicOnion.Client; namespace MagicT.Client.Filters; /// <summary> /// Filter for retrying client requests. /// </summary> internal sealed class RetryFilter : IClientFilter { private readonly int _maxRetryAttempts; private readonly TimeSpan _retryDelay; /// <summary> /// Initializes a new instance of the <see cref="RetryFilter"/> class. /// </summary> /// <param name="maxRetryAttempts">The maximum number of retry attempts.</param> /// <param name="retryDelay">The delay between retries.</param> public RetryFilter(int maxRetryAttempts, TimeSpan retryDelay) { _maxRetryAttempts = maxRetryAttempts; _retryDelay = retryDelay; } /// <summary> /// Sends the request and retries if it fails. /// </summary> /// <param name="context">The request context.</param> /// <param name="next">The next step in the filter pipeline.</param> /// <returns>The response context.</returns> public async ValueTask<ResponseContext> SendAsync(RequestContext context, Func<RequestContext, ValueTask<ResponseContext>> next) { var attempt = 0; while (true) { try { return await next(context); } catch (Exception ex) when (attempt < _maxRetryAttempts) { attempt++; Console.WriteLine($"Attempt {attempt} failed: {ex.Message}. Retrying in {_retryDelay.TotalSeconds} seconds..."); await Task.Delay(_retryDelay); } } } }
I have more examples in this template project if you are interested
I apologize for the delayed response, licentia88.
The code you provided was helpful (the template project helped with other implementations), but what I am trying to implement is as follows:
I would like to implement this using a ClientFilter. Do you have any ideas?
I do not understand why your code does not work, from my understanding once ShowRetryPopup is popped the if statement should wait for it until you press ok or cancel right?
assuming it's that way I understand your problem is with calling the the endpoint with a deadline..
I will try this tomorrow and give you more feedback on it.
apart from it, why are you asking for user for confirmation for resending the same request?
in my opinion what you are doing there is not good coding practice(your client filter implementation is not reusable), If I really needed to receive confirmation from user to resend request, i would prefer dealing with it in the blazor side not in the filter
Ah, I see. I didn't realize that the filter couldn't be reused.
It seems that instead of reusing the filter as you suggested, I need to construct and send a new request.
I was thinking about the reconnection process that is commonly done in mobile games. (For example, showing a popup with a message like "Would you like to reconnect?" and if it fails, ending the process.)
I thought implementing this common reconnection process as a ClientFilter might be convenient.
Thank you for your help, licentia88.
Hello, I am currently developing a game using MagicOnion. Thank you for creating such an amazing library.
I am currently facing an issue.
I am trying to implement a RetryFilter using the ClientFilter example provided. Additionally, I am trying to apply a timeout to handle this process.
My code is as follows:
The problematic part is context.CallOptions.WithDeadline(DateTime.UtcNow.Add(TimeSpan.FromSeconds(3))).
Even though I set the deadline, debugging shows that the deadline is not being applied.
Is there something I might be doing wrong?