forked from ss13remake/ss13remake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLazyContentLoadFailCounter.cs
96 lines (81 loc) · 3.19 KB
/
LazyContentLoadFailCounter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using log4net;
using NetGore;
namespace SFML
{
/// <summary>
/// Keeps track of the number of times lazy content fails to load and when it can attempt to load again.
/// </summary>
class LazyContentLoadFailCounter
{
static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// The number of attempts to make before raising a debug assertion.
/// </summary>
const int _attemptsBeforeAssert = 3;
byte _attempt;
TickCount _nextAttemptTime;
/// <summary>
/// Gets the current attempt number. When 0, there has been no failures since the last attempt.
/// </summary>
public int CurrentAttempt
{
get { return _attempt; }
}
/// <summary>
/// Gets if enough time has elapsed since the last attempt to attempt loading again.
/// </summary>
public bool HasEnoughTimeElapsed
{
get { return _attempt == 0 || _nextAttemptTime < TickCount.Now; }
}
/// <summary>
/// Gets the delay between loading attempts.
/// </summary>
/// <param name="attempt">The current attempt number.</param>
/// <returns>The delay for the <paramref name="attempt"/>.</returns>
static uint GetAttemptDelay(int attempt)
{
switch (attempt)
{
case 0:
case 1:
return 0; // No delay
case 2:
return 50; // 0.05 seconds
case 3:
return 500; // 0.5 seconds
case 4:
return 5000; // 5 seconds
default:
const int lower = 1000 * 60 * 10; // 10 minutes
const int upper = 1000 * 60 * 20; // 20 minutes
return (uint)RandomHelper.NextInt(lower, upper);
}
}
/// <summary>
/// Handles when an <see cref="LoadingFailedException"/> is thrown while trying to load the lazy content.
/// </summary>
/// <param name="sender">The lazy content that tried to load.</param>
/// <param name="ex">The <see cref="LoadingFailedException"/>.</param>
public void HandleLoadException(object sender, LoadingFailedException ex)
{
// Increment attempt counter
if (_attempt < byte.MaxValue)
_attempt++;
// Log
const string errmsg = "Failed to load content `{0}` (attempt: {1}). Exception: {2}";
if (log.IsErrorEnabled)
log.ErrorFormat(errmsg, sender, _attempt, ex);
// If multiple failures, raise a debug assertion
if (_attempt == _attemptsBeforeAssert)
Debug.Fail(string.Format(errmsg, sender, _attempt, ex));
// Update delay time
var now = TickCount.Now;
var delay = GetAttemptDelay(_attempt);
_nextAttemptTime = now + delay;
}
}
}