1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2026-04-07 02:01:12 +00:00

Added small overlap in UserDataTracker polling logic to account for API endpoints not immediately having the data available

This commit is contained in:
Jkorf 2026-03-02 10:47:25 +01:00
parent 204bda8622
commit dabbb5c868
4 changed files with 24 additions and 20 deletions

View File

@ -20,6 +20,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
private readonly ExchangeParameters? _exchangeParameters; private readonly ExchangeParameters? _exchangeParameters;
private readonly bool _requiresSymbolParameterOpenOrders; private readonly bool _requiresSymbolParameterOpenOrders;
private readonly Dictionary<string, int> _openOrderNotReturnedTimes = new(); private readonly Dictionary<string, int> _openOrderNotReturnedTimes = new();
private readonly TimeSpan _pollOverlapPeriod = TimeSpan.FromSeconds(3);
internal event Func<UpdateSource, SharedUserTrade[], Task>? OnTradeUpdate; internal event Func<UpdateSource, SharedUserTrade[], Task>? OnTradeUpdate;
@ -355,17 +356,17 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
DateTime? fromTime = null; DateTime? fromTime = null;
string? source = null; string? source = null;
// Use the last timestamp we we received data from the websocket as state should be correct at that time. 1 seconds buffer // Use the last timestamp we we received data from the websocket as state should be correct at that time
if (_lastDataTimeBeforeDisconnect.HasValue && (fromTime == null || fromTime > _lastDataTimeBeforeDisconnect.Value)) if (_lastDataTimeBeforeDisconnect.HasValue && (fromTime == null || fromTime > _lastDataTimeBeforeDisconnect.Value))
{ {
fromTime = _lastDataTimeBeforeDisconnect.Value.AddSeconds(-1); fromTime = _lastDataTimeBeforeDisconnect.Value.Add(-_pollOverlapPeriod);
source = "LastDataTimeBeforeDisconnect"; source = "LastDataTimeBeforeDisconnect";
} }
// If we've previously polled use that timestamp to request data from // If we've previously polled use that timestamp to request data from
if (_lastPollTime.HasValue && (fromTime == null || _lastPollTime.Value > fromTime)) if (_lastPollTime.HasValue && (fromTime == null || _lastPollTime.Value > fromTime))
{ {
fromTime = _lastPollTime; fromTime = _lastPollTime.Value.Add(-_pollOverlapPeriod);
source = "LastPollTime"; source = "LastPollTime";
} }
@ -378,7 +379,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
{ {
// Could be improved by only requesting the specific open orders if there are only a few that would be better than trying to request a long // Could be improved by only requesting the specific open orders if there are only a few that would be better than trying to request a long
// history if the open order is far back // history if the open order is far back
fromTime = trackedOrdersMinOpenTime.Value.AddMilliseconds(-1); fromTime = trackedOrdersMinOpenTime.Value.AddSeconds(-1);
source = "OpenOrder"; source = "OpenOrder";
} }
@ -388,7 +389,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
source = "StartTime"; source = "StartTime";
} }
if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(1)) if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(5))
{ {
// Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync // Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync
fromTime = DateTime.UtcNow.AddSeconds(-5); fromTime = DateTime.UtcNow.AddSeconds(-5);

View File

@ -18,6 +18,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
private readonly IFuturesOrderRestClient _restClient; private readonly IFuturesOrderRestClient _restClient;
private readonly IUserTradeSocketClient? _socketClient; private readonly IUserTradeSocketClient? _socketClient;
private readonly ExchangeParameters? _exchangeParameters; private readonly ExchangeParameters? _exchangeParameters;
private readonly TimeSpan _pollOverlapPeriod = TimeSpan.FromSeconds(3);
internal Func<string[]>? GetTrackedOrderIds { get; set; } internal Func<string[]>? GetTrackedOrderIds { get; set; }
@ -106,22 +107,22 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
private DateTime? GetTradesRequestStartTime() private DateTime? GetTradesRequestStartTime()
{ {
// Determine the timestamp from which we need to check order status // Determine the timestamp from which we need to request trades from
// Use the timestamp we last know the correct state of the data // Use the timestamp we last know the correct state of the data
DateTime? fromTime = null; DateTime? fromTime = null;
string? source = null; string? source = null;
// Use the last timestamp we we received data from the websocket as state should be correct at that time. 1 seconds buffer // Use the last timestamp we we received data from the websocket as state should be correct at that time.
if (_lastDataTimeBeforeDisconnect.HasValue && (fromTime == null || fromTime > _lastDataTimeBeforeDisconnect.Value)) if (_lastDataTimeBeforeDisconnect.HasValue && (fromTime == null || fromTime > _lastDataTimeBeforeDisconnect.Value))
{ {
fromTime = _lastDataTimeBeforeDisconnect.Value.AddSeconds(-1); fromTime = _lastDataTimeBeforeDisconnect.Value.Add(-_pollOverlapPeriod);
source = "LastDataTimeBeforeDisconnect"; source = "LastDataTimeBeforeDisconnect";
} }
// If we've previously polled use that timestamp to request data from // If we've previously polled use that timestamp to request data from
if (_lastPollTime.HasValue && (fromTime == null || _lastPollTime.Value > fromTime)) if (_lastPollTime.HasValue && (fromTime == null || _lastPollTime.Value > fromTime))
{ {
fromTime = _lastPollTime; fromTime = _lastPollTime.Value.Add(-_pollOverlapPeriod);
source = "LastPollTime"; source = "LastPollTime";
} }
@ -132,7 +133,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
} }
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
if (now - fromTime < TimeSpan.FromSeconds(1)) if (now - fromTime < TimeSpan.FromSeconds(5))
{ {
// Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync // Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync
fromTime = DateTime.UtcNow.AddSeconds(-5); fromTime = DateTime.UtcNow.AddSeconds(-5);

View File

@ -20,6 +20,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
private readonly ExchangeParameters? _exchangeParameters; private readonly ExchangeParameters? _exchangeParameters;
private readonly bool _requiresSymbolParameterOpenOrders; private readonly bool _requiresSymbolParameterOpenOrders;
private readonly Dictionary<string, int> _openOrderNotReturnedTimes = new(); private readonly Dictionary<string, int> _openOrderNotReturnedTimes = new();
private readonly TimeSpan _pollOverlapPeriod = TimeSpan.FromSeconds(3);
internal event Func<UpdateSource, SharedUserTrade[], Task>? OnTradeUpdate; internal event Func<UpdateSource, SharedUserTrade[], Task>? OnTradeUpdate;
@ -366,17 +367,17 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
DateTime? fromTime = null; DateTime? fromTime = null;
string? source = null; string? source = null;
// Use the last timestamp we we received data from the websocket as state should be correct at that time. 1 seconds buffer // Use the last timestamp we we received data from the websocket as state should be correct at that time.
if (_lastDataTimeBeforeDisconnect.HasValue && (fromTime == null || fromTime > _lastDataTimeBeforeDisconnect.Value)) if (_lastDataTimeBeforeDisconnect.HasValue && (fromTime == null || fromTime > _lastDataTimeBeforeDisconnect.Value))
{ {
fromTime = _lastDataTimeBeforeDisconnect.Value.AddSeconds(-1); fromTime = _lastDataTimeBeforeDisconnect.Value.Add(-_pollOverlapPeriod);
source = "LastDataTimeBeforeDisconnect"; source = "LastDataTimeBeforeDisconnect";
} }
// If we've previously polled use that timestamp to request data from // If we've previously polled use that timestamp to request data from
if (_lastPollTime.HasValue && (fromTime == null || _lastPollTime.Value > fromTime)) if (_lastPollTime.HasValue && (fromTime == null || _lastPollTime.Value > fromTime))
{ {
fromTime = _lastPollTime; fromTime = _lastPollTime.Value.Add(-_pollOverlapPeriod);
source = "LastPollTime"; source = "LastPollTime";
} }
@ -389,7 +390,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
{ {
// Could be improved by only requesting the specific open orders if there are only a few that would be better than trying to request a long // Could be improved by only requesting the specific open orders if there are only a few that would be better than trying to request a long
// history if the open order is far back // history if the open order is far back
fromTime = trackedOrdersMinOpenTime.Value.AddMilliseconds(-1); fromTime = trackedOrdersMinOpenTime.Value.AddSeconds(-1);
source = "OpenOrder"; source = "OpenOrder";
} }
@ -399,7 +400,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
source = "StartTime"; source = "StartTime";
} }
if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(1)) if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(5))
{ {
// Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync // Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync
fromTime = DateTime.UtcNow.AddSeconds(-5); fromTime = DateTime.UtcNow.AddSeconds(-5);

View File

@ -18,6 +18,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
private readonly ISpotOrderRestClient _restClient; private readonly ISpotOrderRestClient _restClient;
private readonly IUserTradeSocketClient? _socketClient; private readonly IUserTradeSocketClient? _socketClient;
private readonly ExchangeParameters? _exchangeParameters; private readonly ExchangeParameters? _exchangeParameters;
private readonly TimeSpan _pollOverlapPeriod = TimeSpan.FromSeconds(3);
internal Func<string[]>? GetTrackedOrderIds { get; set; } internal Func<string[]>? GetTrackedOrderIds { get; set; }
@ -103,22 +104,22 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
private DateTime? GetTradesRequestStartTime() private DateTime? GetTradesRequestStartTime()
{ {
// Determine the timestamp from which we need to check order status // Determine the timestamp from which we need to request trades from
// Use the timestamp we last know the correct state of the data // Use the timestamp we last know the correct state of the data
DateTime? fromTime = null; DateTime? fromTime = null;
string? source = null; string? source = null;
// Use the last timestamp we we received data from the websocket as state should be correct at that time. 1 seconds buffer // Use the last timestamp we we received data from the websocket as state should be correct at that time.
if (_lastDataTimeBeforeDisconnect.HasValue && (fromTime == null || fromTime > _lastDataTimeBeforeDisconnect.Value)) if (_lastDataTimeBeforeDisconnect.HasValue && (fromTime == null || fromTime > _lastDataTimeBeforeDisconnect.Value))
{ {
fromTime = _lastDataTimeBeforeDisconnect.Value.AddSeconds(-1); fromTime = _lastDataTimeBeforeDisconnect.Value.Add(-_pollOverlapPeriod);
source = "LastDataTimeBeforeDisconnect"; source = "LastDataTimeBeforeDisconnect";
} }
// If we've previously polled use that timestamp to request data from // If we've previously polled use that timestamp to request data from
if (_lastPollTime.HasValue && (fromTime == null || _lastPollTime.Value > fromTime)) if (_lastPollTime.HasValue && (fromTime == null || _lastPollTime.Value > fromTime))
{ {
fromTime = _lastPollTime; fromTime = _lastPollTime.Value.Add(-_pollOverlapPeriod);
source = "LastPollTime"; source = "LastPollTime";
} }
@ -128,7 +129,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
source = "StartTime"; source = "StartTime";
} }
if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(1)) if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(5))
{ {
// Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync // Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync
fromTime = DateTime.UtcNow.AddSeconds(-5); fromTime = DateTime.UtcNow.AddSeconds(-5);