17 using System.Threading;
32 private volatile bool _failed;
33 private volatile bool _stopped;
34 private long _additionalMinutes;
37 private readonly TimeSpan _timeLoopMaximum;
57 _timeLoopMaximum = timeLoopMaximum;
74 throw new InvalidOperationException(
"The AlgorithmTimeLimitManager may not be stopped and restarted.");
82 Interlocked.Exchange(ref _additionalMinutes, 0L);
90 internal void StopEnforcingTimeLimit()
100 TimeSpan currentTimeStepElapsed;
101 var message = IsOutOfTime(out currentTimeStepElapsed) ? GetErrorMessage(currentTimeStepElapsed) :
string.Empty;
119 Log.
Debug($
"AlgorithmTimeLimitManager.RequestAdditionalTime({minutes}): Failed to acquire additional time. Marking failed.");
134 Log.
Debug($
"AlgorithmTimeLimitManager.TryRequestAdditionalTime({minutes}): Requesting additional time. Available: {AdditionalTimeBucket.AvailableTokens}");
139 var newValue = Interlocked.Add(ref _additionalMinutes, minutes);
140 Log.
Debug($
"AlgorithmTimeLimitManager.TryRequestAdditionalTime({minutes}): Success: AdditionalMinutes: {newValue}");
150 private bool IsOutOfTime(out TimeSpan currentTimeStepElapsed)
154 currentTimeStepElapsed = TimeSpan.Zero;
158 currentTimeStepElapsed = GetCurrentTimeStepElapsed();
164 var additionalMinutes = TimeSpan.FromMinutes(Interlocked.Read(ref _additionalMinutes));
165 return currentTimeStepElapsed > _timeLoopMaximum.Add(additionalMinutes);
172 private TimeSpan GetCurrentTimeStepElapsed()
174 var currentValue = _currentTimeStepTime.
Value;
175 if (currentValue == DateTime.MinValue)
178 return TimeSpan.Zero;
181 return DateTime.UtcNow - currentValue;
184 private string GetErrorMessage(TimeSpan currentTimeStepElapsed)
186 var message = $
"Algorithm took longer than {_timeLoopMaximum.TotalMinutes} minutes on a single time loop.";
188 var minutesAboveStandardLimit = _additionalMinutes - (int) _timeLoopMaximum.TotalMinutes;
189 if (minutesAboveStandardLimit > 0)
191 message = $
"{message} An additional {minutesAboveStandardLimit} minutes were also allocated and consumed.";
194 message = $
"{message} CurrentTimeStepElapsed: {currentTimeStepElapsed.TotalMinutes:0.0} minutes";