|
1 | 1 | using Hi3Helper; |
2 | 2 | using System; |
3 | | -using System.Runtime.CompilerServices; |
4 | 3 | using System.Threading; |
5 | 4 | using System.Threading.Tasks; |
6 | 5 | // ReSharper disable UnusedMember.Global |
|
9 | 8 | namespace CollapseLauncher.Extension |
10 | 9 | { |
11 | 10 | public delegate Task<TResult?> ActionTimeoutTaskCallback<TResult>(CancellationToken token); |
12 | | - public delegate ConfiguredTaskAwaitable<TResult?> ActionTimeoutTaskAwaitableCallback<TResult>(CancellationToken token); |
13 | 11 | public delegate void ActionOnTimeOutRetry(int retryAttemptCount, int retryAttemptTotal, int timeOutSecond, int timeOutStep); |
14 | | - internal static class TaskExtensions |
| 12 | + internal static partial class TaskExtensions |
15 | 13 | { |
16 | 14 | internal const int DefaultTimeoutSec = 10; |
17 | 15 | internal const int DefaultRetryAttempt = 5; |
18 | 16 |
|
19 | | - internal static Task<TResult?> |
20 | | - WaitForRetryAsync<TResult>(this ActionTimeoutTaskAwaitableCallback<TResult?> funcCallback, |
21 | | - int? timeout = null, |
22 | | - int? timeoutStep = null, |
23 | | - int? retryAttempt = null, |
24 | | - ActionOnTimeOutRetry? actionOnRetry = null, |
25 | | - CancellationToken fromToken = default) |
26 | | - => WaitForRetryAsync(() => funcCallback, timeout, timeoutStep, retryAttempt, actionOnRetry, fromToken); |
27 | | - |
28 | | - internal static async Task<TResult?> |
29 | | - WaitForRetryAsync<TResult>(Func<ActionTimeoutTaskAwaitableCallback<TResult?>> funcCallback, |
30 | | - int? timeout = null, |
31 | | - int? timeoutStep = null, |
32 | | - int? retryAttempt = null, |
33 | | - ActionOnTimeOutRetry? actionOnRetry = null, |
34 | | - CancellationToken fromToken = default) |
35 | | - { |
36 | | - timeout ??= DefaultTimeoutSec; |
37 | | - timeoutStep ??= 0; |
38 | | - retryAttempt ??= DefaultRetryAttempt; |
39 | | - |
40 | | - int retryAttemptCurrent = 1; |
41 | | - Exception? lastException = null; |
42 | | - while (retryAttemptCurrent < retryAttempt) |
43 | | - { |
44 | | - fromToken.ThrowIfCancellationRequested(); |
45 | | - CancellationTokenSource? innerCancellationToken = null; |
46 | | - CancellationTokenSource? consolidatedToken = null; |
47 | | - |
48 | | - try |
49 | | - { |
50 | | - innerCancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(timeout ?? DefaultTimeoutSec)); |
51 | | - consolidatedToken = CancellationTokenSource.CreateLinkedTokenSource(innerCancellationToken.Token, fromToken); |
52 | | - |
53 | | - ActionTimeoutTaskAwaitableCallback<TResult?> delegateCallback = funcCallback(); |
54 | | - return await delegateCallback(consolidatedToken.Token); |
55 | | - } |
56 | | - catch (OperationCanceledException) when (fromToken.IsCancellationRequested) { throw; } |
57 | | - catch (Exception ex) |
58 | | - { |
59 | | - lastException = ex; |
60 | | - actionOnRetry?.Invoke(retryAttemptCurrent, (int)retryAttempt, timeout ?? 0, timeoutStep ?? 0); |
61 | | - |
62 | | - if (ex is TimeoutException) |
63 | | - { |
64 | | - string msg = $"The operation has timed out! Retrying attempt left: {retryAttemptCurrent}/{retryAttempt}"; |
65 | | - Logger.LogWriteLine(msg, LogType.Warning, true); |
66 | | - } |
67 | | - else |
68 | | - { |
69 | | - string msg = $"The operation has thrown an exception! Retrying attempt left: {retryAttemptCurrent}/{retryAttempt}\r\n{ex}"; |
70 | | - Logger.LogWriteLine(msg, LogType.Error, true); |
71 | | - } |
72 | | - |
73 | | - retryAttemptCurrent++; |
74 | | - timeout += timeoutStep; |
75 | | - } |
76 | | - finally |
77 | | - { |
78 | | - innerCancellationToken?.Dispose(); |
79 | | - consolidatedToken?.Dispose(); |
80 | | - } |
81 | | - } |
82 | | - |
83 | | - if (lastException is not null |
84 | | - && !fromToken.IsCancellationRequested) |
85 | | - throw lastException is TaskCanceledException ? |
86 | | - new TimeoutException("The operation has timed out with inner exception!", lastException) : |
87 | | - lastException; |
88 | | - |
89 | | - throw new TimeoutException("The operation has timed out!"); |
90 | | - } |
91 | | - |
92 | 17 | internal static async Task<TResult?> |
93 | 18 | WaitForRetryAsync<TResult>(this ActionTimeoutTaskCallback<TResult?> funcCallback, |
94 | 19 | int? timeout = null, |
|
0 commit comments