2
0
mirror of synced 2025-01-11 09:06:56 +00:00

Rewarderbot: Speeds up time segments when catching up to realtime.

This commit is contained in:
Ben 2024-09-30 15:34:40 +02:00
parent ffb5eb294a
commit db4c4a87e0
No known key found for this signature in database
GPG Key ID: 0F16E812E736C24B
4 changed files with 67 additions and 18 deletions

View File

@ -48,18 +48,19 @@ namespace CodexContractsPlugin.ChainMonitor
public TimeRange TotalSpan { get; private set; }
public IChainStateRequest[] Requests => requests.ToArray();
public void Update()
public int Update()
{
Update(DateTime.UtcNow);
return Update(DateTime.UtcNow);
}
public void Update(DateTime toUtc)
public int Update(DateTime toUtc)
{
var span = new TimeRange(TotalSpan.To, toUtc);
var events = ChainEvents.FromTimeRange(contracts, span);
Apply(events);
TotalSpan = new TimeRange(TotalSpan.From, span.To);
return events.All.Length;
}
private void Apply(ChainEvents events)

View File

@ -23,7 +23,7 @@ namespace MarketInsights
public MarketTimeSegment[] Segments { get; private set; } = Array.Empty<MarketTimeSegment>();
public Task OnNewSegment(TimeRange timeRange)
public Task<TimeSegmentResponse> OnNewSegment(TimeRange timeRange)
{
var contribution = BuildContribution(timeRange);
contributions.Add(contribution);
@ -35,7 +35,7 @@ namespace MarketInsights
Segments = contributions.ToArray();
return Task.CompletedTask;
return Task.FromResult(TimeSegmentResponse.OK);
}
private MarketTimeSegment BuildContribution(TimeRange timeRange)

View File

@ -31,19 +31,18 @@ namespace TestNetRewarder
chainState = new ChainState(log, contracts, handler, config.HistoryStartUtc);
}
public async Task OnNewSegment(TimeRange timeRange)
public async Task<TimeSegmentResponse> OnNewSegment(TimeRange timeRange)
{
try
{
chainState.Update(timeRange.To);
var sw = System.Diagnostics.Stopwatch.StartNew();
var numberOfChainEvents = await ProcessEvents(timeRange);
var duration = sw.Elapsed;
var events = eventsFormatter.GetEvents();
var request = builder.Build(events);
if (request.HasAny())
{
await client.SendRewards(request);
}
if (numberOfChainEvents == 0) return TimeSegmentResponse.Underload;
if (numberOfChainEvents > 10) return TimeSegmentResponse.Overload;
if (duration > TimeSpan.FromSeconds(1)) return TimeSegmentResponse.Overload;
return TimeSegmentResponse.OK;
}
catch (Exception ex)
{
@ -53,5 +52,19 @@ namespace TestNetRewarder
throw;
}
}
private async Task<int> ProcessEvents(TimeRange timeRange)
{
var numberOfChainEvents = chainState.Update(timeRange.To);
var events = eventsFormatter.GetEvents();
var request = builder.Build(events);
if (request.HasAny())
{
await client.SendRewards(request);
}
return numberOfChainEvents;
}
}
}

View File

@ -5,15 +5,24 @@ namespace TestNetRewarder
{
public interface ITimeSegmentHandler
{
Task OnNewSegment(TimeRange timeRange);
Task<TimeSegmentResponse> OnNewSegment(TimeRange timeRange);
}
public enum TimeSegmentResponse
{
OK,
Underload,
Overload
}
public class TimeSegmenter
{
private const int maxSegmentMult = 50;
private readonly ILog log;
private readonly ITimeSegmentHandler handler;
private readonly TimeSpan segmentSize;
private DateTime latest;
private int currentSegmentMult = 1;
public TimeSegmenter(ILog log, TimeSpan segmentSize, DateTime historyStartUtc, ITimeSegmentHandler handler)
{
@ -30,19 +39,45 @@ namespace TestNetRewarder
public async Task ProcessNextSegment()
{
var end = latest + segmentSize;
var end = GetNewSegmentEnd();
IsRealtime = await WaitUntilTimeSegmentInPast(end);
if (Program.CancellationToken.IsCancellationRequested) return;
var postfix = "(Catching up...)";
if (IsRealtime) postfix = "(Real-time)";
log.Log($"Time segment [{latest} to {end}] {postfix}");
log.Log($"Time segment [{latest} to {end}] {postfix}({currentSegmentMult}x)");
var range = new TimeRange(latest, end);
latest = end;
await handler.OnNewSegment(range);
var response = await handler.OnNewSegment(range);
HandleResponse(response);
}
private DateTime GetNewSegmentEnd()
{
if (IsRealtime) return latest + segmentSize;
var segment = segmentSize * currentSegmentMult;
return latest + segment;
}
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);
}
}
private async Task<bool> WaitUntilTimeSegmentInPast(DateTime end)