2024-01-22 09:27:07 +00:00
|
|
|
|
using Logging;
|
|
|
|
|
using Utils;
|
|
|
|
|
|
|
|
|
|
namespace TestNetRewarder
|
|
|
|
|
{
|
2024-06-14 09:05:29 +00:00
|
|
|
|
public interface ITimeSegmentHandler
|
|
|
|
|
{
|
2024-09-30 13:34:40 +00:00
|
|
|
|
Task<TimeSegmentResponse> OnNewSegment(TimeRange timeRange);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public enum TimeSegmentResponse
|
|
|
|
|
{
|
|
|
|
|
OK,
|
|
|
|
|
Underload,
|
|
|
|
|
Overload
|
2024-06-14 09:05:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-22 09:27:07 +00:00
|
|
|
|
public class TimeSegmenter
|
|
|
|
|
{
|
2024-09-30 13:34:40 +00:00
|
|
|
|
private const int maxSegmentMult = 50;
|
2024-01-22 09:27:07 +00:00
|
|
|
|
private readonly ILog log;
|
2024-06-14 09:05:29 +00:00
|
|
|
|
private readonly ITimeSegmentHandler handler;
|
2024-01-22 09:27:07 +00:00
|
|
|
|
private readonly TimeSpan segmentSize;
|
2024-06-14 09:05:29 +00:00
|
|
|
|
private DateTime latest;
|
2024-09-30 13:34:40 +00:00
|
|
|
|
private int currentSegmentMult = 1;
|
2024-01-22 09:27:07 +00:00
|
|
|
|
|
2024-08-21 13:03:20 +00:00
|
|
|
|
public TimeSegmenter(ILog log, TimeSpan segmentSize, DateTime historyStartUtc, ITimeSegmentHandler handler)
|
2024-01-22 09:27:07 +00:00
|
|
|
|
{
|
|
|
|
|
this.log = log;
|
2024-06-14 09:05:29 +00:00
|
|
|
|
this.handler = handler;
|
2024-08-21 13:03:20 +00:00
|
|
|
|
this.segmentSize = segmentSize;
|
|
|
|
|
latest = historyStartUtc;
|
2024-01-22 09:27:07 +00:00
|
|
|
|
|
2024-06-14 09:05:29 +00:00
|
|
|
|
log.Log("Starting time segments at " + latest);
|
2024-01-22 09:27:07 +00:00
|
|
|
|
log.Log("Segment size: " + Time.FormatDuration(segmentSize));
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-21 13:03:20 +00:00
|
|
|
|
public bool IsRealtime { get; private set; } = false;
|
|
|
|
|
|
2024-06-14 09:05:29 +00:00
|
|
|
|
public async Task ProcessNextSegment()
|
2024-01-22 09:27:07 +00:00
|
|
|
|
{
|
2024-09-30 13:34:40 +00:00
|
|
|
|
var end = GetNewSegmentEnd();
|
2024-08-21 13:03:20 +00:00
|
|
|
|
IsRealtime = await WaitUntilTimeSegmentInPast(end);
|
2024-01-22 09:27:07 +00:00
|
|
|
|
|
|
|
|
|
if (Program.CancellationToken.IsCancellationRequested) return;
|
|
|
|
|
|
2024-01-22 10:47:28 +00:00
|
|
|
|
var postfix = "(Catching up...)";
|
2024-08-21 13:03:20 +00:00
|
|
|
|
if (IsRealtime) postfix = "(Real-time)";
|
2024-09-30 13:34:40 +00:00
|
|
|
|
log.Log($"Time segment [{latest} to {end}] {postfix}({currentSegmentMult}x)");
|
2024-06-14 09:05:29 +00:00
|
|
|
|
|
|
|
|
|
var range = new TimeRange(latest, end);
|
|
|
|
|
latest = end;
|
2024-01-22 10:47:28 +00:00
|
|
|
|
|
2024-09-30 13:34:40 +00:00
|
|
|
|
var response = await handler.OnNewSegment(range);
|
|
|
|
|
HandleResponse(response);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private DateTime GetNewSegmentEnd()
|
|
|
|
|
{
|
|
|
|
|
if (IsRealtime) return latest + segmentSize;
|
|
|
|
|
var segment = segmentSize * currentSegmentMult;
|
2024-09-30 14:08:16 +00:00
|
|
|
|
var end = latest + segment;
|
|
|
|
|
if (end > DateTime.UtcNow) return DateTime.UtcNow + segmentSize;
|
|
|
|
|
return end;
|
2024-09-30 13:34:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void HandleResponse(TimeSegmentResponse response)
|
|
|
|
|
{
|
|
|
|
|
switch (response)
|
|
|
|
|
{
|
|
|
|
|
case TimeSegmentResponse.OK:
|
|
|
|
|
if (currentSegmentMult > 1) currentSegmentMult--;
|
|
|
|
|
break;
|
|
|
|
|
case TimeSegmentResponse.Underload:
|
|
|
|
|
if (currentSegmentMult < maxSegmentMult) currentSegmentMult++;
|
|
|
|
|
break;
|
|
|
|
|
case TimeSegmentResponse.Overload:
|
|
|
|
|
currentSegmentMult = 1;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
throw new Exception("Unknown response type: " + response);
|
|
|
|
|
}
|
2024-06-14 09:05:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task<bool> WaitUntilTimeSegmentInPast(DateTime end)
|
|
|
|
|
{
|
|
|
|
|
await Task.Delay(TimeSpan.FromSeconds(3), Program.CancellationToken);
|
2024-01-22 09:27:07 +00:00
|
|
|
|
|
2024-06-14 09:05:29 +00:00
|
|
|
|
var now = DateTime.UtcNow;
|
|
|
|
|
while (end > now)
|
|
|
|
|
{
|
2024-09-30 14:08:16 +00:00
|
|
|
|
currentSegmentMult = 1;
|
2024-06-14 09:05:29 +00:00
|
|
|
|
var delay = (end - now) + TimeSpan.FromSeconds(3);
|
|
|
|
|
await Task.Delay(delay, Program.CancellationToken);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2024-01-22 09:27:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|