mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-07 07:56:12 +00:00
Fixed various info-warnings and spelling issues
This commit is contained in:
parent
024e8dcfe2
commit
e07f24ea0a
@ -5,6 +5,7 @@ namespace CryptoExchange.Net.Attributes
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Map a enum entry to string values
|
/// Map a enum entry to string values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Field)]
|
||||||
public class MapAttribute : Attribute
|
public class MapAttribute : Attribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -459,10 +459,10 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
/// <param name="serializer"></param>
|
/// <param name="serializer"></param>
|
||||||
/// <param name="parameters"></param>
|
/// <param name="parameters"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected string GetSerializedBody(IMessageSerializer serializer, IDictionary<string, object> parameters)
|
protected static string GetSerializedBody(IMessageSerializer serializer, IDictionary<string, object> parameters)
|
||||||
{
|
{
|
||||||
if (parameters.Count == 1 && parameters.ContainsKey(Constants.BodyPlaceHolderKey))
|
if (parameters.Count == 1 && parameters.TryGetValue(Constants.BodyPlaceHolderKey, out object? value))
|
||||||
return serializer.Serialize(parameters[Constants.BodyPlaceHolderKey]);
|
return serializer.Serialize(value);
|
||||||
else
|
else
|
||||||
return serializer.Serialize(parameters);
|
return serializer.Serialize(parameters);
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Logger</param>
|
/// <param name="logger">Logger</param>
|
||||||
/// <param name="outputOriginalData">Should data from this client include the orginal data in the call result</param>
|
/// <param name="outputOriginalData">Should data from this client include the original data in the call result</param>
|
||||||
/// <param name="baseAddress">Base address for this API client</param>
|
/// <param name="baseAddress">Base address for this API client</param>
|
||||||
/// <param name="apiCredentials">Api credentials</param>
|
/// <param name="apiCredentials">Api credentials</param>
|
||||||
/// <param name="clientOptions">Client options</param>
|
/// <param name="clientOptions">Client options</param>
|
||||||
|
@ -49,7 +49,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected internal ILogger _logger;
|
protected internal ILogger _logger;
|
||||||
|
|
||||||
private object _versionLock = new object();
|
private readonly object _versionLock = new object();
|
||||||
private Version _exchangeVersion;
|
private Version _exchangeVersion;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -93,6 +93,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
{
|
{
|
||||||
tasks.Add(client.ReconnectAsync());
|
tasks.Add(client.ReconnectAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.WhenAll(tasks.ToArray()).ConfigureAwait(false);
|
await Task.WhenAll(tasks.ToArray()).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
{
|
{
|
||||||
result.AppendLine(client.GetSubscriptionsState());
|
result.AppendLine(client.GetSubscriptionsState());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.ToString();
|
return result.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +122,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
{
|
{
|
||||||
result.Add(client.GetState());
|
result.Add(client.GetState());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CryptoBaseClient : IDisposable
|
public class CryptoBaseClient : IDisposable
|
||||||
{
|
{
|
||||||
private Dictionary<Type, object> _serviceCache = new Dictionary<Type, object>();
|
private readonly Dictionary<Type, object> _serviceCache = new Dictionary<Type, object>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Service provider
|
/// Service provider
|
||||||
|
@ -89,7 +89,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Memory cache
|
/// Memory cache
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static MemoryCache _cache = new MemoryCache();
|
private readonly static MemoryCache _cache = new MemoryCache();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
@ -826,7 +826,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
if (parameterPosition == HttpMethodParameterPosition.InUri)
|
if (parameterPosition == HttpMethodParameterPosition.InUri)
|
||||||
{
|
{
|
||||||
foreach (var parameter in parameters)
|
foreach (var parameter in parameters)
|
||||||
uri = uri.AddQueryParmeter(parameter.Key, parameter.Value.ToString()!);
|
uri = uri.AddQueryParameter(parameter.Key, parameter.Value.ToString()!);
|
||||||
}
|
}
|
||||||
|
|
||||||
var headers = new Dictionary<string, string>();
|
var headers = new Dictionary<string, string>();
|
||||||
|
@ -82,7 +82,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!socketConnections.Any())
|
if (socketConnections.IsEmpty)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return socketConnections.Sum(s => s.Value.IncomingKbps);
|
return socketConnections.Sum(s => s.Value.IncomingKbps);
|
||||||
@ -97,7 +97,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!socketConnections.Any())
|
if (socketConnections.IsEmpty)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return socketConnections.Sum(s => s.Value.UserSubscriptionCount);
|
return socketConnections.Sum(s => s.Value.UserSubscriptionCount);
|
||||||
@ -510,7 +510,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
|
|
||||||
if (connection != null)
|
if (connection != null)
|
||||||
{
|
{
|
||||||
if (connection.UserSubscriptionCount < ClientOptions.SocketSubscriptionsCombineTarget || socketConnections.Count >= (ApiOptions.MaxSocketConnections ?? ClientOptions.MaxSocketConnections) && socketConnections.All(s => s.Value.UserSubscriptionCount >= ClientOptions.SocketSubscriptionsCombineTarget))
|
if (connection.UserSubscriptionCount < ClientOptions.SocketSubscriptionsCombineTarget || (socketConnections.Count >= (ApiOptions.MaxSocketConnections ?? ClientOptions.MaxSocketConnections) && socketConnections.All(s => s.Value.UserSubscriptionCount >= ClientOptions.SocketSubscriptionsCombineTarget)))
|
||||||
// Use existing socket if it has less than target connections OR it has the least connections and we can't make new
|
// Use existing socket if it has less than target connections OR it has the least connections and we can't make new
|
||||||
return new CallResult<SocketConnection>(connection);
|
return new CallResult<SocketConnection>(connection);
|
||||||
}
|
}
|
||||||
@ -598,7 +598,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
KeepAliveInterval = KeepAliveInterval,
|
KeepAliveInterval = KeepAliveInterval,
|
||||||
ReconnectInterval = ClientOptions.ReconnectInterval,
|
ReconnectInterval = ClientOptions.ReconnectInterval,
|
||||||
RateLimiter = ClientOptions.RateLimiterEnabled ? RateLimiter : null,
|
RateLimiter = ClientOptions.RateLimiterEnabled ? RateLimiter : null,
|
||||||
RateLimitingBehaviour = ClientOptions.RateLimitingBehaviour,
|
RateLimitingBehavior = ClientOptions.RateLimitingBehaviour,
|
||||||
Proxy = ClientOptions.Proxy,
|
Proxy = ClientOptions.Proxy,
|
||||||
Timeout = ApiOptions.SocketNoDataTimeout ?? ClientOptions.SocketNoDataTimeout
|
Timeout = ApiOptions.SocketNoDataTimeout ?? ClientOptions.SocketNoDataTimeout
|
||||||
};
|
};
|
||||||
@ -718,7 +718,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
base.SetOptions(options);
|
base.SetOptions(options);
|
||||||
|
|
||||||
if ((!previousProxyIsSet && options.Proxy == null)
|
if ((!previousProxyIsSet && options.Proxy == null)
|
||||||
|| !socketConnections.Any())
|
|| socketConnections.IsEmpty)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Node accessor
|
/// Node accessor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct NodeAccessor
|
public readonly struct NodeAccessor
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Index
|
/// Index
|
||||||
|
@ -6,9 +6,9 @@ namespace CryptoExchange.Net.Converters.MessageParsing
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Message access definition
|
/// Message access definition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct MessagePath : IEnumerable<NodeAccessor>
|
public readonly struct MessagePath : IEnumerable<NodeAccessor>
|
||||||
{
|
{
|
||||||
private List<NodeAccessor> _path;
|
private readonly List<NodeAccessor> _path;
|
||||||
|
|
||||||
internal void Add(NodeAccessor node)
|
internal void Add(NodeAccessor node)
|
||||||
{
|
{
|
||||||
|
@ -20,8 +20,8 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected JsonDocument? _document;
|
protected JsonDocument? _document;
|
||||||
|
|
||||||
private static JsonSerializerOptions _serializerOptions = SerializerOptions.WithConverters;
|
private static readonly JsonSerializerOptions _serializerOptions = SerializerOptions.WithConverters;
|
||||||
private JsonSerializerOptions? _customSerializerOptions;
|
private readonly JsonSerializerOptions? _customSerializerOptions;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsJson { get; set; }
|
public bool IsJson { get; set; }
|
||||||
@ -148,6 +148,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
return value.Value.Deserialize<T>(_customSerializerOptions ?? _serializerOptions);
|
return value.Value.Deserialize<T>(_customSerializerOptions ?? _serializerOptions);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +360,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string GetOriginalString() =>
|
public override string GetOriginalString() =>
|
||||||
// Netstandard 2.0 doesn't support GetString from a ReadonlySpan<byte>, so use ToArray there instead
|
// NetStandard 2.0 doesn't support GetString from a ReadonlySpan<byte>, so use ToArray there instead
|
||||||
#if NETSTANDARD2_0
|
#if NETSTANDARD2_0
|
||||||
Encoding.UTF8.GetString(_bytes.ToArray());
|
Encoding.UTF8.GetString(_bytes.ToArray());
|
||||||
#else
|
#else
|
||||||
|
@ -160,7 +160,7 @@ namespace CryptoExchange.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate a new unique id. The id is staticly stored so it is guarenteed to be unique
|
/// Generate a new unique id. The id is statically stored so it is guaranteed to be unique
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static int NextId() => Interlocked.Increment(ref _lastId);
|
public static int NextId() => Interlocked.Increment(ref _lastId);
|
||||||
|
@ -111,6 +111,7 @@ namespace CryptoExchange.Net
|
|||||||
formData.Add(kvp.Key, string.Format(CultureInfo.InvariantCulture, "{0}", kvp.Value));
|
formData.Add(kvp.Key, string.Format(CultureInfo.InvariantCulture, "{0}", kvp.Value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return formData.ToString()!;
|
return formData.ToString()!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,6 +287,7 @@ namespace CryptoExchange.Net
|
|||||||
httpValueCollection.Add(parameter.Key, parameter.Value.ToString());
|
httpValueCollection.Add(parameter.Key, parameter.Value.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uriBuilder.Query = httpValueCollection.ToString();
|
uriBuilder.Query = httpValueCollection.ToString();
|
||||||
return uriBuilder.Uri;
|
return uriBuilder.Uri;
|
||||||
}
|
}
|
||||||
@ -333,6 +335,7 @@ namespace CryptoExchange.Net
|
|||||||
httpValueCollection.Add(parameter.Key, parameter.Value.ToString());
|
httpValueCollection.Add(parameter.Key, parameter.Value.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uriBuilder.Query = httpValueCollection.ToString();
|
uriBuilder.Query = httpValueCollection.ToString();
|
||||||
return uriBuilder.Uri;
|
return uriBuilder.Uri;
|
||||||
}
|
}
|
||||||
@ -344,7 +347,7 @@ namespace CryptoExchange.Net
|
|||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
/// <param name="value"></param>
|
/// <param name="value"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Uri AddQueryParmeter(this Uri uri, string name, string value)
|
public static Uri AddQueryParameter(this Uri uri, string name, string value)
|
||||||
{
|
{
|
||||||
var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);
|
var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
int CurrentSubscriptions { get; }
|
int CurrentSubscriptions { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Incoming data kpbs
|
/// Incoming data Kbps
|
||||||
/// </summary>
|
/// </summary>
|
||||||
double IncomingKbps { get; }
|
double IncomingKbps { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -105,7 +105,7 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
Task StopAsync();
|
Task StopAsync();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the average price that a market order would fill at at the current order book state. This is no guarentee that an order of that quantity would actually be filled
|
/// Get the average price that a market order would fill at at the current order book state. This is no guarantee that an order of that quantity would actually be filled
|
||||||
/// at that price since between this calculation and the order placement the book might have changed.
|
/// at that price since between this calculation and the order placement the book might have changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="quantity">The quantity in base asset to fill</param>
|
/// <param name="quantity">The quantity in base asset to fill</param>
|
||||||
@ -115,7 +115,7 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the amount of base asset which can be traded with the quote quantity when placing a market order at at the current order book state.
|
/// Get the amount of base asset which can be traded with the quote quantity when placing a market order at at the current order book state.
|
||||||
/// This is no guarentee that an order of that quantity would actually be fill the quantity returned by this since between this calculation and the order placement the book might have changed.
|
/// This is no guarantee that an order of that quantity would actually be fill the quantity returned by this since between this calculation and the order placement the book might have changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="quoteQuantity">The quantity in quote asset looking to trade</param>
|
/// <param name="quoteQuantity">The quantity in quote asset looking to trade</param>
|
||||||
/// <param name="type">The type</param>
|
/// <param name="type">The type</param>
|
||||||
|
@ -47,7 +47,7 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
event Func<Task> OnReconnected;
|
event Func<Task> OnReconnected;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get reconntion url
|
/// Get reconnection url
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Func<Task<Uri?>>? GetReconnectionUrl { get; set; }
|
Func<Task<Uri?>>? GetReconnectionUrl { get; set; }
|
||||||
|
|
||||||
|
@ -10,9 +10,9 @@ namespace CryptoExchange.Net
|
|||||||
public static class LibraryHelpers
|
public static class LibraryHelpers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Client order id seperator
|
/// Client order id separator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string ClientOrderIdSeperator = "JK";
|
public const string ClientOrderIdSeparator = "JK";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Apply broker id to a client order id
|
/// Apply broker id to a client order id
|
||||||
@ -20,25 +20,25 @@ namespace CryptoExchange.Net
|
|||||||
/// <param name="clientOrderId"></param>
|
/// <param name="clientOrderId"></param>
|
||||||
/// <param name="brokerId"></param>
|
/// <param name="brokerId"></param>
|
||||||
/// <param name="maxLength"></param>
|
/// <param name="maxLength"></param>
|
||||||
/// <param name="allowValueAdjustement"></param>
|
/// <param name="allowValueAdjustment"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string ApplyBrokerId(string? clientOrderId, string brokerId, int maxLength, bool allowValueAdjustement)
|
public static string ApplyBrokerId(string? clientOrderId, string brokerId, int maxLength, bool allowValueAdjustment)
|
||||||
{
|
{
|
||||||
var reservedLength = brokerId.Length + ClientOrderIdSeperator.Length;
|
var reservedLength = brokerId.Length + ClientOrderIdSeparator.Length;
|
||||||
|
|
||||||
if ((clientOrderId?.Length + reservedLength) > maxLength)
|
if ((clientOrderId?.Length + reservedLength) > maxLength)
|
||||||
return clientOrderId!;
|
return clientOrderId!;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(clientOrderId))
|
if (!string.IsNullOrEmpty(clientOrderId))
|
||||||
{
|
{
|
||||||
if (allowValueAdjustement)
|
if (allowValueAdjustment)
|
||||||
clientOrderId = brokerId + ClientOrderIdSeperator + clientOrderId;
|
clientOrderId = brokerId + ClientOrderIdSeparator + clientOrderId;
|
||||||
|
|
||||||
return clientOrderId!;
|
return clientOrderId!;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clientOrderId = ExchangeHelpers.AppendRandomString(brokerId + ClientOrderIdSeperator, maxLength);
|
clientOrderId = ExchangeHelpers.AppendRandomString(brokerId + ClientOrderIdSeparator, maxLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientOrderId;
|
return clientOrderId;
|
||||||
|
@ -33,7 +33,7 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
private static readonly Action<ILogger, int, Exception?> _receiveLoopStoppedWithException;
|
private static readonly Action<ILogger, int, Exception?> _receiveLoopStoppedWithException;
|
||||||
private static readonly Action<ILogger, int, Exception?> _receiveLoopFinished;
|
private static readonly Action<ILogger, int, Exception?> _receiveLoopFinished;
|
||||||
private static readonly Action<ILogger, int, TimeSpan?, Exception?> _startingTaskForNoDataReceivedCheck;
|
private static readonly Action<ILogger, int, TimeSpan?, Exception?> _startingTaskForNoDataReceivedCheck;
|
||||||
private static readonly Action<ILogger, int, TimeSpan?, Exception?> _noDataReceiveTimoutReconnect;
|
private static readonly Action<ILogger, int, TimeSpan?, Exception?> _noDataReceiveTimeoutReconnect;
|
||||||
private static readonly Action<ILogger, int, string, string, Exception?> _socketProcessingStateChanged;
|
private static readonly Action<ILogger, int, string, string, Exception?> _socketProcessingStateChanged;
|
||||||
private static readonly Action<ILogger, int, Exception?> _socketPingTimeout;
|
private static readonly Action<ILogger, int, Exception?> _socketPingTimeout;
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
new EventId(1026, "StartingTaskForNoDataReceivedCheck"),
|
new EventId(1026, "StartingTaskForNoDataReceivedCheck"),
|
||||||
"[Sckt {SocketId}] starting task checking for no data received for {Timeout}");
|
"[Sckt {SocketId}] starting task checking for no data received for {Timeout}");
|
||||||
|
|
||||||
_noDataReceiveTimoutReconnect = LoggerMessage.Define<int, TimeSpan?>(
|
_noDataReceiveTimeoutReconnect = LoggerMessage.Define<int, TimeSpan?>(
|
||||||
LogLevel.Warning,
|
LogLevel.Warning,
|
||||||
new EventId(1027, "NoDataReceiveTimeoutReconnect"),
|
new EventId(1027, "NoDataReceiveTimeoutReconnect"),
|
||||||
"[Sckt {SocketId}] no data received for {Timeout}, reconnecting socket");
|
"[Sckt {SocketId}] no data received for {Timeout}, reconnecting socket");
|
||||||
@ -356,7 +356,7 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
public static void SocketNoDataReceiveTimoutReconnect(
|
public static void SocketNoDataReceiveTimoutReconnect(
|
||||||
this ILogger logger, int socketId, TimeSpan? timeSpan)
|
this ILogger logger, int socketId, TimeSpan? timeSpan)
|
||||||
{
|
{
|
||||||
_noDataReceiveTimoutReconnect(logger, socketId, timeSpan, null);
|
_noDataReceiveTimeoutReconnect(logger, socketId, timeSpan, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SocketProcessingStateChanged(
|
public static void SocketProcessingStateChanged(
|
||||||
|
@ -22,7 +22,6 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
private static readonly Action<ILogger, string, Exception?> _restApiCacheHit;
|
private static readonly Action<ILogger, string, Exception?> _restApiCacheHit;
|
||||||
private static readonly Action<ILogger, string, Exception?> _restApiCacheNotHit;
|
private static readonly Action<ILogger, string, Exception?> _restApiCacheNotHit;
|
||||||
|
|
||||||
|
|
||||||
static RestApiClientLoggingExtensions()
|
static RestApiClientLoggingExtensions()
|
||||||
{
|
{
|
||||||
_restApiErrorReceived = LoggerMessage.Define<int?, int?, long, string?>(
|
_restApiErrorReceived = LoggerMessage.Define<int?, int?, long, string?>(
|
||||||
@ -37,7 +36,7 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
|
|
||||||
_restApiFailedToSyncTime = LoggerMessage.Define<int, string>(
|
_restApiFailedToSyncTime = LoggerMessage.Define<int, string>(
|
||||||
LogLevel.Debug,
|
LogLevel.Debug,
|
||||||
new EventId(4002, "RestApifailedToSyncTime"),
|
new EventId(4002, "RestApiFailedToSyncTime"),
|
||||||
"[Req {RequestId}] Failed to sync time, aborting request: {ErrorMessage}");
|
"[Req {RequestId}] Failed to sync time, aborting request: {ErrorMessage}");
|
||||||
|
|
||||||
_restApiNoApiCredentials = LoggerMessage.Define<int, string>(
|
_restApiNoApiCredentials = LoggerMessage.Define<int, string>(
|
||||||
|
@ -10,7 +10,7 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
private static readonly Action<ILogger, int, bool, Exception?> _activityPaused;
|
private static readonly Action<ILogger, int, bool, Exception?> _activityPaused;
|
||||||
private static readonly Action<ILogger, int, Sockets.SocketConnection.SocketStatus, Sockets.SocketConnection.SocketStatus, Exception?> _socketStatusChanged;
|
private static readonly Action<ILogger, int, Sockets.SocketConnection.SocketStatus, Sockets.SocketConnection.SocketStatus, Exception?> _socketStatusChanged;
|
||||||
private static readonly Action<ILogger, int, string?, Exception?> _failedReconnectProcessing;
|
private static readonly Action<ILogger, int, string?, Exception?> _failedReconnectProcessing;
|
||||||
private static readonly Action<ILogger, int, Exception?> _unkownExceptionWhileProcessingReconnection;
|
private static readonly Action<ILogger, int, Exception?> _unknownExceptionWhileProcessingReconnection;
|
||||||
private static readonly Action<ILogger, int, WebSocketError, string?, Exception?> _webSocketErrorCodeAndDetails;
|
private static readonly Action<ILogger, int, WebSocketError, string?, Exception?> _webSocketErrorCodeAndDetails;
|
||||||
private static readonly Action<ILogger, int, string?, Exception?> _webSocketError;
|
private static readonly Action<ILogger, int, string?, Exception?> _webSocketError;
|
||||||
private static readonly Action<ILogger, int, int, Exception?> _messageSentNotPending;
|
private static readonly Action<ILogger, int, int, Exception?> _messageSentNotPending;
|
||||||
@ -28,7 +28,7 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
private static readonly Action<ILogger, int, Exception?> _closingNoMoreSubscriptions;
|
private static readonly Action<ILogger, int, Exception?> _closingNoMoreSubscriptions;
|
||||||
private static readonly Action<ILogger, int, int, int, Exception?> _addingNewSubscription;
|
private static readonly Action<ILogger, int, int, int, Exception?> _addingNewSubscription;
|
||||||
private static readonly Action<ILogger, int, Exception?> _nothingToResubscribeCloseConnection;
|
private static readonly Action<ILogger, int, Exception?> _nothingToResubscribeCloseConnection;
|
||||||
private static readonly Action<ILogger, int, Exception?> _failedAuthenticationDisconnectAndRecoonect;
|
private static readonly Action<ILogger, int, Exception?> _failedAuthenticationDisconnectAndReconnect;
|
||||||
private static readonly Action<ILogger, int, Exception?> _authenticationSucceeded;
|
private static readonly Action<ILogger, int, Exception?> _authenticationSucceeded;
|
||||||
private static readonly Action<ILogger, int, string?, Exception?> _failedRequestRevitalization;
|
private static readonly Action<ILogger, int, string?, Exception?> _failedRequestRevitalization;
|
||||||
private static readonly Action<ILogger, int, Exception?> _allSubscriptionResubscribed;
|
private static readonly Action<ILogger, int, Exception?> _allSubscriptionResubscribed;
|
||||||
@ -55,15 +55,15 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
new EventId(2002, "FailedReconnectProcessing"),
|
new EventId(2002, "FailedReconnectProcessing"),
|
||||||
"[Sckt {SocketId}] failed reconnect processing: {ErrorMessage}, reconnecting again");
|
"[Sckt {SocketId}] failed reconnect processing: {ErrorMessage}, reconnecting again");
|
||||||
|
|
||||||
_unkownExceptionWhileProcessingReconnection = LoggerMessage.Define<int>(
|
_unknownExceptionWhileProcessingReconnection = LoggerMessage.Define<int>(
|
||||||
LogLevel.Warning,
|
LogLevel.Warning,
|
||||||
new EventId(2003, "UnkownExceptionWhileProcessingReconnection"),
|
new EventId(2003, "UnknownExceptionWhileProcessingReconnection"),
|
||||||
"[Sckt {SocketId}] Unknown exception while processing reconnection, reconnecting again");
|
"[Sckt {SocketId}] Unknown exception while processing reconnection, reconnecting again");
|
||||||
|
|
||||||
_webSocketErrorCodeAndDetails = LoggerMessage.Define<int, WebSocketError, string?>(
|
_webSocketErrorCodeAndDetails = LoggerMessage.Define<int, WebSocketError, string?>(
|
||||||
LogLevel.Warning,
|
LogLevel.Warning,
|
||||||
new EventId(2004, "WebSocketErrorCode"),
|
new EventId(2004, "WebSocketErrorCode"),
|
||||||
"[Sckt {SocketId}] error: Websocket error code {WebSocketErrorCdoe}, details: {Details}");
|
"[Sckt {SocketId}] error: Websocket error code {WebSocketErrorCode}, details: {Details}");
|
||||||
|
|
||||||
_webSocketError = LoggerMessage.Define<int, string?>(
|
_webSocketError = LoggerMessage.Define<int, string?>(
|
||||||
LogLevel.Warning,
|
LogLevel.Warning,
|
||||||
@ -145,7 +145,7 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
new EventId(2020, "NothingToResubscribe"),
|
new EventId(2020, "NothingToResubscribe"),
|
||||||
"[Sckt {SocketId}] nothing to resubscribe, closing connection");
|
"[Sckt {SocketId}] nothing to resubscribe, closing connection");
|
||||||
|
|
||||||
_failedAuthenticationDisconnectAndRecoonect = LoggerMessage.Define<int>(
|
_failedAuthenticationDisconnectAndReconnect = LoggerMessage.Define<int>(
|
||||||
LogLevel.Warning,
|
LogLevel.Warning,
|
||||||
new EventId(2021, "FailedAuthentication"),
|
new EventId(2021, "FailedAuthentication"),
|
||||||
"[Sckt {SocketId}] authentication failed on reconnected socket. Disconnecting and reconnecting");
|
"[Sckt {SocketId}] authentication failed on reconnected socket. Disconnecting and reconnecting");
|
||||||
@ -206,9 +206,9 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
_failedReconnectProcessing(logger, socketId, error, null);
|
_failedReconnectProcessing(logger, socketId, error, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UnkownExceptionWhileProcessingReconnection(this ILogger logger, int socketId, Exception e)
|
public static void UnknownExceptionWhileProcessingReconnection(this ILogger logger, int socketId, Exception e)
|
||||||
{
|
{
|
||||||
_unkownExceptionWhileProcessingReconnection(logger, socketId, e);
|
_unknownExceptionWhileProcessingReconnection(logger, socketId, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WebSocketErrorCodeAndDetails(this ILogger logger, int socketId, WebSocketError error, string? details, Exception e)
|
public static void WebSocketErrorCodeAndDetails(this ILogger logger, int socketId, WebSocketError error, string? details, Exception e)
|
||||||
@ -285,7 +285,7 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
}
|
}
|
||||||
public static void FailedAuthenticationDisconnectAndRecoonect(this ILogger logger, int socketId)
|
public static void FailedAuthenticationDisconnectAndRecoonect(this ILogger logger, int socketId)
|
||||||
{
|
{
|
||||||
_failedAuthenticationDisconnectAndRecoonect(logger, socketId, null);
|
_failedAuthenticationDisconnectAndReconnect(logger, socketId, null);
|
||||||
}
|
}
|
||||||
public static void AuthenticationSucceeded(this ILogger logger, int socketId)
|
public static void AuthenticationSucceeded(this ILogger logger, int socketId)
|
||||||
{
|
{
|
||||||
|
@ -62,7 +62,6 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
new EventId(5005, "OrderBookStopping"),
|
new EventId(5005, "OrderBookStopping"),
|
||||||
"{Api} order book {Symbol} stopping");
|
"{Api} order book {Symbol} stopping");
|
||||||
|
|
||||||
|
|
||||||
_orderBookStopped = LoggerMessage.Define<string, string>(
|
_orderBookStopped = LoggerMessage.Define<string, string>(
|
||||||
LogLevel.Trace,
|
LogLevel.Trace,
|
||||||
new EventId(5006, "OrderBookStopped"),
|
new EventId(5006, "OrderBookStopped"),
|
||||||
|
@ -97,7 +97,6 @@ namespace CryptoExchange.Net.Logging.Extensions
|
|||||||
new EventId(6012, "KlineTrackerConnectionRestored"),
|
new EventId(6012, "KlineTrackerConnectionRestored"),
|
||||||
"Kline tracker for {Symbol} successfully resynchronized");
|
"Kline tracker for {Symbol} successfully resynchronized");
|
||||||
|
|
||||||
|
|
||||||
_tradeTrackerStatusChanged = LoggerMessage.Define<string, SyncStatus, SyncStatus>(
|
_tradeTrackerStatusChanged = LoggerMessage.Define<string, SyncStatus, SyncStatus>(
|
||||||
LogLevel.Debug,
|
LogLevel.Debug,
|
||||||
new EventId(6013, "KlineTrackerStatusChanged"),
|
new EventId(6013, "KlineTrackerStatusChanged"),
|
||||||
|
@ -89,7 +89,7 @@ namespace CryptoExchange.Net.Objects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new error result
|
/// Create a new error result
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="error">The erro rto return</param>
|
/// <param name="error">The error to return</param>
|
||||||
public CallResult(Error error) : this(default, null, error) { }
|
public CallResult(Error error) : this(default, null, error) { }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace CryptoExchange.Net.Objects
|
using CryptoExchange.Net.Attributes;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.Objects
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// What to do when a request would exceed the rate limit
|
/// What to do when a request would exceed the rate limit
|
||||||
@ -92,7 +94,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disposed
|
/// Disposed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Diposed
|
Disposed
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -215,7 +217,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
FixedDelay,
|
FixedDelay,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Backof policy of 2^`reconnectAttempt`, where `reconnectAttempt` has a max value of 5
|
/// Backoff policy of 2^`reconnectAttempt`, where `reconnectAttempt` has a max value of 5
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExponentialBackoff
|
ExponentialBackoff
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ namespace CryptoExchange.Net.Objects.Options
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Trade environment. Contains info about URL's to use to connect to the API. To swap environment select another environment for
|
/// Trade environment. Contains info about URL's to use to connect to the API. To swap environment select another environment for
|
||||||
/// the exhange's environment list or create a custom environment using either `[Exchange]Environment.CreateCustom()` or `[Exchange]Environment.[Environment]`, for example `KucoinEnvironment.TestNet` or `BinanceEnvironment.Live`
|
/// the exchange's environment list or create a custom environment using either `[Exchange]Environment.CreateCustom()` or `[Exchange]Environment.[Environment]`, for example `KucoinEnvironment.TestNet` or `BinanceEnvironment.Live`
|
||||||
/// </summary>
|
/// </summary>
|
||||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||||
public TEnvironment Environment { get; set; }
|
public TEnvironment Environment { get; set; }
|
||||||
|
@ -25,8 +25,7 @@ namespace CryptoExchange.Net.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Authenticated { get; set; }
|
public bool Authenticated { get; set; }
|
||||||
|
|
||||||
|
// Formatting
|
||||||
// Formating
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The body format for this request
|
/// The body format for this request
|
||||||
|
@ -41,7 +41,7 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event when the connection is restored. Timespan parameter indicates the time the socket has been offline for before reconnecting.
|
/// Event when the connection is restored. Timespan parameter indicates the time the socket has been offline for before reconnecting.
|
||||||
/// Note that when the executing code is suspended and resumed at a later period (for example, a laptop going to sleep) the disconnect time will be incorrect as the diconnect
|
/// Note that when the executing code is suspended and resumed at a later period (for example, a laptop going to sleep) the disconnect time will be incorrect as the disconnect
|
||||||
/// will only be detected after resuming the code, so the initial disconnect time is lost. Use the timespan only for informational purposes.
|
/// will only be detected after resuming the code, so the initial disconnect time is lost. Use the timespan only for informational purposes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<TimeSpan> ConnectionRestored
|
public event Action<TimeSpan> ConnectionRestored
|
||||||
|
@ -41,7 +41,7 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
public ApiProxy? Proxy { get; set; }
|
public ApiProxy? Proxy { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The maximum time of no data received before considering the connection lost and closting/reconnecting the socket
|
/// The maximum time of no data received before considering the connection lost and closing/reconnecting the socket
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TimeSpan? Timeout { get; set; }
|
public TimeSpan? Timeout { get; set; }
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ namespace CryptoExchange.Net.Objects.Sockets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// What to do when rate limit is reached
|
/// What to do when rate limit is reached
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RateLimitingBehaviour RateLimitingBehaviour { get; set; }
|
public RateLimitingBehaviour RateLimitingBehavior { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Encoding for sending/receiving data
|
/// Encoding for sending/receiving data
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Trade environment. Contains info about URL's to use to connect to the API. To swap environment select another environment for
|
/// Trade environment. Contains info about URL's to use to connect to the API. To swap environment select another environment for
|
||||||
/// the echange's environment list or create a custom environment using either `[Exchange]Environment.CreateCustom()` or `[Exchange]Environment.[Environment]`, for example `KucoinEnvironment.TestNet` or `BinanceEnvironment.Live`
|
/// the exchange's environment list or create a custom environment using either `[Exchange]Environment.CreateCustom()` or `[Exchange]Environment.[Environment]`, for example `KucoinEnvironment.TestNet` or `BinanceEnvironment.Live`
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TradeEnvironment
|
public class TradeEnvironment
|
||||||
{
|
{
|
||||||
|
@ -74,8 +74,7 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether levels should be strictly enforced. For example, when an order book has 25 levels and a new update comes in which pushes
|
/// Whether levels should be strictly enforced. For example, when an order book has 25 levels and a new update comes in which pushes
|
||||||
/// the current level 25 ask out of the top 25, should the curent the level 26 entry be removed from the book or does the
|
/// the current level 25 ask out of the top 25, should the level 26 entry be removed from the book or does the server handle this
|
||||||
/// server handle this
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected bool _strictLevels;
|
protected bool _strictLevels;
|
||||||
|
|
||||||
@ -250,6 +249,7 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
|
|
||||||
// Clear any previous messages
|
// Clear any previous messages
|
||||||
while (_processQueue.TryDequeue(out _)) { }
|
while (_processQueue.TryDequeue(out _)) { }
|
||||||
|
|
||||||
_processBuffer.Clear();
|
_processBuffer.Clear();
|
||||||
_bookSet = false;
|
_bookSet = false;
|
||||||
|
|
||||||
@ -407,7 +407,7 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the initial data for the order book. Typically the snapshot which was requested from the Rest API, or the first snapshot
|
/// Set the initial data for the order book. Typically the snapshot which was requested from the Rest API, or the first snapshot
|
||||||
/// received from a socket subcription
|
/// received from a socket subscription
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="orderBookSequenceNumber">The last update sequence number until which the snapshot is in sync</param>
|
/// <param name="orderBookSequenceNumber">The last update sequence number until which the snapshot is in sync</param>
|
||||||
/// <param name="askList">List of asks</param>
|
/// <param name="askList">List of asks</param>
|
||||||
@ -618,6 +618,7 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
var bid = book.bids.Count() > i ? book.bids.ElementAt(i): null;
|
var bid = book.bids.Count() > i ? book.bids.ElementAt(i): null;
|
||||||
stringBuilder.AppendLine($"[{ask?.Quantity.ToString(CultureInfo.InvariantCulture),14}] {ask?.Price.ToString(CultureInfo.InvariantCulture),14} | {bid?.Price.ToString(CultureInfo.InvariantCulture),-14} [{bid?.Quantity.ToString(CultureInfo.InvariantCulture),-14}]");
|
stringBuilder.AppendLine($"[{ask?.Quantity.ToString(CultureInfo.InvariantCulture),14}] {ask?.Price.ToString(CultureInfo.InvariantCulture),14} | {bid?.Price.ToString(CultureInfo.InvariantCulture),-14} [{bid?.Quantity.ToString(CultureInfo.InvariantCulture),-14}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
return stringBuilder.ToString();
|
return stringBuilder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,6 +637,7 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
_queueEvent.Set();
|
_queueEvent.Set();
|
||||||
// Clear queue
|
// Clear queue
|
||||||
while (_processQueue.TryDequeue(out _)) { }
|
while (_processQueue.TryDequeue(out _)) { }
|
||||||
|
|
||||||
_processBuffer.Clear();
|
_processBuffer.Clear();
|
||||||
_bookSet = false;
|
_bookSet = false;
|
||||||
DoReset();
|
DoReset();
|
||||||
@ -732,7 +734,7 @@ namespace CryptoExchange.Net.OrderBook
|
|||||||
var (prevBestBid, prevBestAsk) = BestOffers;
|
var (prevBestBid, prevBestAsk) = BestOffers;
|
||||||
ProcessRangeUpdates(item.StartUpdateId, item.EndUpdateId, item.Bids, item.Asks);
|
ProcessRangeUpdates(item.StartUpdateId, item.EndUpdateId, item.Bids, item.Asks);
|
||||||
|
|
||||||
if (!_asks.Any() || !_bids.Any())
|
if (_asks.Count == 0 || _bids.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_asks.First().Key < _bids.First().Key)
|
if (_asks.First().Key < _bids.First().Key)
|
||||||
|
@ -32,9 +32,9 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
|||||||
|
|
||||||
private readonly IEnumerable<IGuardFilter> _filters;
|
private readonly IEnumerable<IGuardFilter> _filters;
|
||||||
private readonly Dictionary<string, IWindowTracker> _trackers;
|
private readonly Dictionary<string, IWindowTracker> _trackers;
|
||||||
private RateLimitWindowType _windowType;
|
private readonly RateLimitWindowType _windowType;
|
||||||
private double? _decayRate;
|
private readonly double? _decayRate;
|
||||||
private int? _connectionWeight;
|
private readonly int? _connectionWeight;
|
||||||
private readonly Func<RequestDefinition, string, string?, string> _keySelector;
|
private readonly Func<RequestDefinition, string, string?, string> _keySelector;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -38,7 +38,7 @@ namespace CryptoExchange.Net.RateLimiting.Trackers
|
|||||||
if (Current == 0)
|
if (Current == 0)
|
||||||
{
|
{
|
||||||
throw new Exception("Request limit reached without any prior request. " +
|
throw new Exception("Request limit reached without any prior request. " +
|
||||||
$"This request can never execute with the current rate limiter. Request weight: {weight}, Ratelimit: {Limit}");
|
$"This request can never execute with the current rate limiter. Request weight: {weight}, RateLimit: {Limit}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the time to wait before this weight can be applied without going over the rate limit
|
// Determine the time to wait before this weight can be applied without going over the rate limit
|
||||||
|
@ -45,7 +45,7 @@ namespace CryptoExchange.Net.RateLimiting.Trackers
|
|||||||
if (Current == 0)
|
if (Current == 0)
|
||||||
{
|
{
|
||||||
throw new Exception("Request limit reached without any prior request. " +
|
throw new Exception("Request limit reached without any prior request. " +
|
||||||
$"This request can never execute with the current rate limiter. Request weight: {weight}, Ratelimit: {Limit}");
|
$"This request can never execute with the current rate limiter. Request weight: {weight}, RateLimit: {Limit}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the time to wait before this weight can be applied without going over the rate limit
|
// Determine the time to wait before this weight can be applied without going over the rate limit
|
||||||
|
@ -41,7 +41,7 @@ namespace CryptoExchange.Net.RateLimiting.Trackers
|
|||||||
if (Current == 0)
|
if (Current == 0)
|
||||||
{
|
{
|
||||||
throw new Exception("Request limit reached without any prior request. " +
|
throw new Exception("Request limit reached without any prior request. " +
|
||||||
$"This request can never execute with the current rate limiter. Request weight: {weight}, Ratelimit: {Limit}");
|
$"This request can never execute with the current rate limiter. Request weight: {weight}, RateLimit: {Limit}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the time to wait before this weight can be applied without going over the rate limit
|
// Determine the time to wait before this weight can be applied without going over the rate limit
|
||||||
|
@ -40,7 +40,7 @@ namespace CryptoExchange.Net.RateLimiting.Trackers
|
|||||||
if (Current == 0)
|
if (Current == 0)
|
||||||
{
|
{
|
||||||
throw new Exception("Request limit reached without any prior request. " +
|
throw new Exception("Request limit reached without any prior request. " +
|
||||||
$"This request can never execute with the current rate limiter. Request weight: {weight}, Ratelimit: {Limit}");
|
$"This request can never execute with the current rate limiter. Request weight: {weight}, RateLimit: {Limit}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the time to wait before this weight can be applied without going over the rate limit
|
// Determine the time to wait before this weight can be applied without going over the rate limit
|
||||||
@ -102,7 +102,7 @@ namespace CryptoExchange.Net.RateLimiting.Trackers
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw new Exception("Request not possible to execute with current rate limit guard. " +
|
throw new Exception("Request not possible to execute with current rate limit guard. " +
|
||||||
$" Request weight: {requestWeight}, Ratelimit: {Limit}");
|
$" Request weight: {requestWeight}, RateLimit: {Limit}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
public class ExchangeParameters
|
public class ExchangeParameters
|
||||||
{
|
{
|
||||||
private readonly List<ExchangeParameter> _parameters;
|
private readonly List<ExchangeParameter> _parameters;
|
||||||
private static List<ExchangeParameter> _staticParameters = new List<ExchangeParameter>();
|
private readonly static List<ExchangeParameter> _staticParameters = new List<ExchangeParameter>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
|
@ -132,7 +132,6 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
NextPageToken = nextPageToken;
|
NextPageToken = nextPageToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copy the ExchangeWebResult to a new data type
|
/// Copy the ExchangeWebResult to a new data type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -46,14 +46,14 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private ProcessState _processState;
|
private ProcessState _processState;
|
||||||
private DateTime _lastReconnectTime;
|
private DateTime _lastReconnectTime;
|
||||||
private string _baseAddress;
|
private readonly string _baseAddress;
|
||||||
private int _reconnectAttempt;
|
private int _reconnectAttempt;
|
||||||
|
|
||||||
private const int _receiveBufferSize = 1048576;
|
private const int _receiveBufferSize = 1048576;
|
||||||
private const int _sendBufferSize = 4096;
|
private const int _sendBufferSize = 4096;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Received messages, the size and the timstamp
|
/// Received messages, the size and the timestamp
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly List<ReceiveItem> _receivedMessages;
|
protected readonly List<ReceiveItem> _receivedMessages;
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
{
|
{
|
||||||
UpdateReceivedMessages();
|
UpdateReceivedMessages();
|
||||||
|
|
||||||
if (!_receivedMessages.Any())
|
if (_receivedMessages.Count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return Math.Round(_receivedMessages.Sum(v => v.Bytes) / 1000d / 3d);
|
return Math.Round(_receivedMessages.Sum(v => v.Bytes) / 1000d / 3d);
|
||||||
@ -219,7 +219,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
if (Parameters.RateLimiter != null)
|
if (Parameters.RateLimiter != null)
|
||||||
{
|
{
|
||||||
var definition = new RequestDefinition(Uri.AbsolutePath, HttpMethod.Get) { ConnectionId = Id };
|
var definition = new RequestDefinition(Uri.AbsolutePath, HttpMethod.Get) { ConnectionId = Id };
|
||||||
var limitResult = await Parameters.RateLimiter.ProcessAsync(_logger, Id, RateLimitItemType.Connection, definition, _baseAddress, null, 1, Parameters.RateLimitingBehaviour, _ctsSource.Token).ConfigureAwait(false);
|
var limitResult = await Parameters.RateLimiter.ProcessAsync(_logger, Id, RateLimitItemType.Connection, definition, _baseAddress, null, 1, Parameters.RateLimitingBehavior, _ctsSource.Token).ConfigureAwait(false);
|
||||||
if (!limitResult)
|
if (!limitResult)
|
||||||
return new CallResult(new ClientRateLimitError("Connection limit reached"));
|
return new CallResult(new ClientRateLimitError("Connection limit reached"));
|
||||||
}
|
}
|
||||||
@ -296,7 +296,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
await (OnReconnecting?.Invoke() ?? Task.CompletedTask).ConfigureAwait(false);
|
await (OnReconnecting?.Invoke() ?? Task.CompletedTask).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delay here to prevent very repid looping when a connection to the server is accepted and immediately disconnected
|
// Delay here to prevent very rapid looping when a connection to the server is accepted and immediately disconnected
|
||||||
var initialDelay = GetReconnectDelay();
|
var initialDelay = GetReconnectDelay();
|
||||||
await Task.Delay(initialDelay).ConfigureAwait(false);
|
await Task.Delay(initialDelay).ConfigureAwait(false);
|
||||||
|
|
||||||
@ -491,7 +491,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!_sendBuffer.Any())
|
if (_sendBuffer.IsEmpty)
|
||||||
await _sendEvent.WaitAsync(ct: _ctsSource.Token).ConfigureAwait(false);
|
await _sendEvent.WaitAsync(ct: _ctsSource.Token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
@ -508,7 +508,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var limitResult = await Parameters.RateLimiter.ProcessAsync(_logger, data.Id, RateLimitItemType.Request, requestDefinition, _baseAddress, null, data.Weight, Parameters.RateLimitingBehaviour, _ctsSource.Token).ConfigureAwait(false);
|
var limitResult = await Parameters.RateLimiter.ProcessAsync(_logger, data.Id, RateLimitItemType.Request, requestDefinition, _baseAddress, null, data.Weight, Parameters.RateLimitingBehavior, _ctsSource.Token).ConfigureAwait(false);
|
||||||
if (!limitResult)
|
if (!limitResult)
|
||||||
{
|
{
|
||||||
await (OnRequestRateLimited?.Invoke(data.Id) ?? Task.CompletedTask).ConfigureAwait(false);
|
await (OnRequestRateLimited?.Invoke(data.Id) ?? Task.CompletedTask).ConfigureAwait(false);
|
||||||
@ -589,9 +589,9 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
}
|
}
|
||||||
catch (OperationCanceledException ex)
|
catch (OperationCanceledException ex)
|
||||||
{
|
{
|
||||||
if (ex.InnerException?.InnerException?.Message.Equals("The WebSocket didn't recieve a Pong frame in response to a Ping frame within the configured KeepAliveTimeout.") == true)
|
if (ex.InnerException?.InnerException?.Message.Equals("The WebSocket didn't receive a Pong frame in response to a Ping frame within the configured KeepAliveTimeout.") == true)
|
||||||
{
|
{
|
||||||
// Spefic case that the websocket connection got closed because of a ping frame timeout
|
// Specific case that the websocket connection got closed because of a ping frame timeout
|
||||||
// Unfortunately doesn't seem to be a nicer way to catch
|
// Unfortunately doesn't seem to be a nicer way to catch
|
||||||
_logger.SocketPingTimeout(Id);
|
_logger.SocketPingTimeout(Id);
|
||||||
}
|
}
|
||||||
@ -679,11 +679,11 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
|
|
||||||
if (multiPartMessage)
|
if (multiPartMessage)
|
||||||
{
|
{
|
||||||
// When the connection gets interupted we might not have received a full message
|
// When the connection gets interrupted we might not have received a full message
|
||||||
if (receiveResult?.EndOfMessage == true)
|
if (receiveResult?.EndOfMessage == true)
|
||||||
{
|
{
|
||||||
_logger.SocketReassembledMessage(Id, multipartStream!.Length);
|
_logger.SocketReassembledMessage(Id, multipartStream!.Length);
|
||||||
// Get the underlying buffer of the memorystream holding the written data and delimit it (GetBuffer return the full array, not only the written part)
|
// Get the underlying buffer of the memory stream holding the written data and delimit it (GetBuffer return the full array, not only the written part)
|
||||||
await ProcessData(receiveResult.MessageType, new ReadOnlyMemory<byte>(multipartStream.GetBuffer(), 0, (int)multipartStream.Length)).ConfigureAwait(false);
|
await ProcessData(receiveResult.MessageType, new ReadOnlyMemory<byte>(multipartStream.GetBuffer(), 0, (int)multipartStream.Length)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -710,7 +710,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Proccess a stream message
|
/// Process a stream message
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
@ -742,6 +742,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
_ = ReconnectAsync().ConfigureAwait(false);
|
_ = ReconnectAsync().ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Task.Delay(500, _ctsSource.Token).ConfigureAwait(false);
|
await Task.Delay(500, _ctsSource.Token).ConfigureAwait(false);
|
||||||
|
@ -143,7 +143,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
public DateTime? DisconnectTime { get; set; }
|
public DateTime? DisconnectTime { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tag for identificaion
|
/// Tag for identification
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Tag { get; set; }
|
public string Tag { get; set; }
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
private readonly IByteMessageAccessor _accessor;
|
private readonly IByteMessageAccessor _accessor;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The task that is sending periodic data on the websocket. Can be used for sending Ping messages every x seconds or similair. Not necesarry.
|
/// The task that is sending periodic data on the websocket. Can be used for sending Ping messages every x seconds or similar. Not necessary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected Task? periodicTask;
|
protected Task? periodicTask;
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
|
|
||||||
foreach (var query in _listeners.OfType<Query>().ToList())
|
foreach (var query in _listeners.OfType<Query>().ToList())
|
||||||
{
|
{
|
||||||
query.Fail(new WebError("Connection interupted"));
|
query.Fail(new WebError("Connection interrupted"));
|
||||||
_listeners.Remove(query);
|
_listeners.Remove(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,7 +311,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
|
|
||||||
foreach (var query in _listeners.OfType<Query>().ToList())
|
foreach (var query in _listeners.OfType<Query>().ToList())
|
||||||
{
|
{
|
||||||
query.Fail(new WebError("Connection interupted"));
|
query.Fail(new WebError("Connection interrupted"));
|
||||||
_listeners.Remove(query);
|
_listeners.Remove(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,7 +340,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
{
|
{
|
||||||
foreach (var query in _listeners.OfType<Query>().ToList())
|
foreach (var query in _listeners.OfType<Query>().ToList())
|
||||||
{
|
{
|
||||||
query.Fail(new WebError("Connection interupted"));
|
query.Fail(new WebError("Connection interrupted"));
|
||||||
_listeners.Remove(query);
|
_listeners.Remove(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -369,7 +369,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
_logger.UnkownExceptionWhileProcessingReconnection(SocketId, ex);
|
_logger.UnknownExceptionWhileProcessingReconnection(SocketId, ex);
|
||||||
_ = _socket.ReconnectAsync().ConfigureAwait(false);
|
_ = _socket.ReconnectAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -392,7 +392,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handler for whenever a request is rate limited and rate limit behaviour is set to fail
|
/// Handler for whenever a request is rate limited and rate limit behavior is set to fail
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="requestId"></param>
|
/// <param name="requestId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
@ -172,7 +172,7 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
throw new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {propValue}");
|
throw new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {propValue}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propertyValue == default && (propValue.Type == JTokenType.Null || string.IsNullOrEmpty(propValue.ToString())) || propValue.ToString() == "0")
|
if ((propertyValue == default && (propValue.Type == JTokenType.Null || string.IsNullOrEmpty(propValue.ToString()))) || propValue.ToString() == "0")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (propertyValue!.GetType().GetInterfaces().Contains(typeof(IDictionary)))
|
if (propertyValue!.GetType().GetInterfaces().Contains(typeof(IDictionary)))
|
||||||
|
@ -69,11 +69,11 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
}
|
}
|
||||||
else if (jsonObject!.Type == JTokenType.Array)
|
else if (jsonObject!.Type == JTokenType.Array)
|
||||||
{
|
{
|
||||||
var jObjs = (JArray)jsonObject;
|
var jArray = (JArray)jsonObject;
|
||||||
if (resultData is IEnumerable list)
|
if (resultData is IEnumerable list)
|
||||||
{
|
{
|
||||||
var enumerator = list.GetEnumerator();
|
var enumerator = list.GetEnumerator();
|
||||||
foreach (var jObj in jObjs)
|
foreach (var jObj in jArray)
|
||||||
{
|
{
|
||||||
if (!enumerator.MoveNext())
|
if (!enumerator.MoveNext())
|
||||||
{
|
{
|
||||||
@ -123,7 +123,7 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
{
|
{
|
||||||
var resultProps = resultData.GetType().GetProperties().Select(p => (p, p.GetCustomAttributes(typeof(ArrayPropertyAttribute), true).Cast<ArrayPropertyAttribute>().SingleOrDefault()));
|
var resultProps = resultData.GetType().GetProperties().Select(p => (p, p.GetCustomAttributes(typeof(ArrayPropertyAttribute), true).Cast<ArrayPropertyAttribute>().SingleOrDefault()));
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var item in jObjs.Children())
|
foreach (var item in jArray.Children())
|
||||||
{
|
{
|
||||||
var arrayProp = resultProps.Where(p => p.Item2 != null).SingleOrDefault(p => p.Item2!.Index == i).p;
|
var arrayProp = resultProps.Where(p => p.Item2 != null).SingleOrDefault(p => p.Item2!.Index == i).p;
|
||||||
if (arrayProp != null)
|
if (arrayProp != null)
|
||||||
@ -196,7 +196,7 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
throw new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {propValue}");
|
throw new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {propValue}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propertyValue == default && (propValue.Type == JTokenType.Null || string.IsNullOrEmpty(propValue.ToString())) || propValue.ToString() == "0")
|
if ((propertyValue == default && (propValue.Type == JTokenType.Null || string.IsNullOrEmpty(propValue.ToString()))) || propValue.ToString() == "0")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (propertyValue!.GetType().GetInterfaces().Contains(typeof(IDictionary)))
|
if (propertyValue!.GetType().GetInterfaces().Contains(typeof(IDictionary)))
|
||||||
@ -227,10 +227,10 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
if (propValue.Type != JTokenType.Array)
|
if (propValue.Type != JTokenType.Array)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var jObjs = (JArray)propValue;
|
var jArray = (JArray)propValue;
|
||||||
var list = (IEnumerable)propertyValue;
|
var list = (IEnumerable)propertyValue;
|
||||||
var enumerator = list.GetEnumerator();
|
var enumerator = list.GetEnumerator();
|
||||||
foreach (JToken jtoken in jObjs)
|
foreach (JToken jToken in jArray)
|
||||||
{
|
{
|
||||||
var moved = enumerator.MoveNext();
|
var moved = enumerator.MoveNext();
|
||||||
if (!moved)
|
if (!moved)
|
||||||
@ -241,9 +241,9 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
// Custom converter for the type, skip
|
// Custom converter for the type, skip
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (jtoken.Type == JTokenType.Object)
|
if (jToken.Type == JTokenType.Object)
|
||||||
{
|
{
|
||||||
foreach (var subProp in ((JObject)jtoken).Properties())
|
foreach (var subProp in ((JObject)jToken).Properties())
|
||||||
{
|
{
|
||||||
if (ignoreProperties?.Contains(subProp.Name) == true)
|
if (ignoreProperties?.Contains(subProp.Name) == true)
|
||||||
continue;
|
continue;
|
||||||
@ -251,7 +251,7 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
CheckObject(method, subProp, enumerator.Current, ignoreProperties);
|
CheckObject(method, subProp, enumerator.Current, ignoreProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (jtoken.Type == JTokenType.Array)
|
else if (jToken.Type == JTokenType.Array)
|
||||||
{
|
{
|
||||||
var resultObj = enumerator.Current;
|
var resultObj = enumerator.Current;
|
||||||
var resultProps = resultObj.GetType().GetProperties().Select(p => (p, p.GetCustomAttributes(typeof(ArrayPropertyAttribute), true).Cast<ArrayPropertyAttribute>().SingleOrDefault()));
|
var resultProps = resultObj.GetType().GetProperties().Select(p => (p, p.GetCustomAttributes(typeof(ArrayPropertyAttribute), true).Cast<ArrayPropertyAttribute>().SingleOrDefault()));
|
||||||
@ -262,7 +262,7 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var item in jtoken.Children())
|
foreach (var item in jToken.Children())
|
||||||
{
|
{
|
||||||
var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p;
|
var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p;
|
||||||
if (arrayProp != null)
|
if (arrayProp != null)
|
||||||
@ -274,10 +274,10 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var value = enumerator.Current;
|
var value = enumerator.Current;
|
||||||
if (value == default && ((JValue)jtoken).Type != JTokenType.Null)
|
if (value == default && ((JValue)jToken).Type != JTokenType.Null)
|
||||||
throw new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {jtoken}");
|
throw new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {jToken}");
|
||||||
|
|
||||||
CheckValues(method, propertyName!, propertyType, (JValue)jtoken, value!);
|
CheckValues(method, propertyName!, propertyType, (JValue)jToken, value!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,11 +298,11 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
}
|
}
|
||||||
else if (propValue.Type == JTokenType.Array)
|
else if (propValue.Type == JTokenType.Array)
|
||||||
{
|
{
|
||||||
var jObjs = (JArray)propValue;
|
var jArray = (JArray)propValue;
|
||||||
if (propertyValue is IEnumerable list)
|
if (propertyValue is IEnumerable list)
|
||||||
{
|
{
|
||||||
var enumerator = list.GetEnumerator();
|
var enumerator = list.GetEnumerator();
|
||||||
foreach (var jObj in jObjs)
|
foreach (var jObj in jArray)
|
||||||
{
|
{
|
||||||
if (!enumerator.MoveNext())
|
if (!enumerator.MoveNext())
|
||||||
{
|
{
|
||||||
@ -348,7 +348,7 @@ namespace CryptoExchange.Net.Testing.Comparers
|
|||||||
{
|
{
|
||||||
var resultProps = propertyValue.GetType().GetProperties().Select(p => (p, p.GetCustomAttributes(typeof(ArrayPropertyAttribute), true).Cast<ArrayPropertyAttribute>().SingleOrDefault()));
|
var resultProps = propertyValue.GetType().GetProperties().Select(p => (p, p.GetCustomAttributes(typeof(ArrayPropertyAttribute), true).Cast<ArrayPropertyAttribute>().SingleOrDefault()));
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var item in jObjs.Children())
|
foreach (var item in jArray.Children())
|
||||||
{
|
{
|
||||||
var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p;
|
var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p;
|
||||||
if (arrayProp != null)
|
if (arrayProp != null)
|
||||||
|
@ -11,7 +11,7 @@ namespace CryptoExchange.Net.Testing
|
|||||||
/// Base class for executing REST API integration tests
|
/// Base class for executing REST API integration tests
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TClient">Client type</typeparam>
|
/// <typeparam name="TClient">Client type</typeparam>
|
||||||
public abstract class RestIntergrationTest<TClient>
|
public abstract class RestIntegrationTest<TClient>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a client instance
|
/// Get a client instance
|
@ -113,7 +113,6 @@ namespace CryptoExchange.Net.Testing
|
|||||||
if (lastMessage == null)
|
if (lastMessage == null)
|
||||||
throw new Exception($"{name} expected to {line} to be send to server but did not receive anything");
|
throw new Exception($"{name} expected to {line} to be send to server but did not receive anything");
|
||||||
|
|
||||||
|
|
||||||
var lastMessageJson = JToken.Parse(lastMessage);
|
var lastMessageJson = JToken.Parse(lastMessage);
|
||||||
var expectedJson = JToken.Parse(line.Substring(2));
|
var expectedJson = JToken.Parse(line.Substring(2));
|
||||||
foreach(var item in expectedJson)
|
foreach(var item in expectedJson)
|
||||||
@ -133,7 +132,9 @@ namespace CryptoExchange.Net.Testing
|
|||||||
overrideValue = lastMessageJson[prop.Name]?.Value<decimal>().ToString();
|
overrideValue = lastMessageJson[prop.Name]?.Value<decimal>().ToString();
|
||||||
}
|
}
|
||||||
else if (lastMessageJson[prop.Name]?.Value<string>() != val.ToString() && ignoreProperties?.Contains(prop.Name) != true)
|
else if (lastMessageJson[prop.Name]?.Value<string>() != val.ToString() && ignoreProperties?.Contains(prop.Name) != true)
|
||||||
|
{
|
||||||
throw new Exception($"{name} Expected {prop.Name} to be {val}, but was {lastMessageJson[prop.Name]?.Value<string>()}");
|
throw new Exception($"{name} Expected {prop.Name} to be {val}, but was {lastMessageJson[prop.Name]?.Value<string>()}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check objects and arrays
|
// TODO check objects and arrays
|
||||||
|
@ -94,7 +94,7 @@ namespace CryptoExchange.Net.Trackers.Klines
|
|||||||
IEnumerable<SharedKline> GetData(DateTime? fromTimestamp = null, DateTime? toTimestamp = null);
|
IEnumerable<SharedKline> GetData(DateTime? fromTimestamp = null, DateTime? toTimestamp = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get statitistics on the klines
|
/// Get statistics on the klines
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fromTimestamp">Start timestamp to get the data from, defaults to tracked data start time</param>
|
/// <param name="fromTimestamp">Start timestamp to get the data from, defaults to tracked data start time</param>
|
||||||
/// <param name="toTimestamp">End timestamp to get the data until, defaults to current time</param>
|
/// <param name="toTimestamp">End timestamp to get the data until, defaults to current time</param>
|
||||||
|
@ -90,7 +90,7 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
IEnumerable<SharedTrade> GetData(DateTime? fromTimestamp = null, DateTime? toTimestamp = null);
|
IEnumerable<SharedTrade> GetData(DateTime? fromTimestamp = null, DateTime? toTimestamp = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get statitistics on the trades
|
/// Get statistics on the trades
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fromTimestamp">Start timestamp to get the data from, defaults to tracked data start time</param>
|
/// <param name="fromTimestamp">Start timestamp to get the data from, defaults to tracked data start time</param>
|
||||||
/// <param name="toTimestamp">End timestamp to get the data until, defaults to current time</param>
|
/// <param name="toTimestamp">End timestamp to get the data until, defaults to current time</param>
|
||||||
|
@ -163,7 +163,7 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
Period = period;
|
Period = period;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TradesStats GetStats(IEnumerable<SharedTrade> trades)
|
private static TradesStats GetStats(IEnumerable<SharedTrade> trades)
|
||||||
{
|
{
|
||||||
if (!trades.Any())
|
if (!trades.Any())
|
||||||
return new TradesStats();
|
return new TradesStats();
|
||||||
@ -350,7 +350,7 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
_data.Add(item);
|
_data.Add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_data.Any())
|
if (_data.Count != 0)
|
||||||
_firstTimestamp = _data.Min(v => v.Timestamp);
|
_firstTimestamp = _data.Min(v => v.Timestamp);
|
||||||
|
|
||||||
ApplyWindow(false);
|
ApplyWindow(false);
|
||||||
@ -431,7 +431,6 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
SetSyncStatus();
|
SetSyncStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void HandleConnectionLost()
|
private void HandleConnectionLost()
|
||||||
{
|
{
|
||||||
_logger.TradeTrackerConnectionLost(SymbolName);
|
_logger.TradeTrackerConnectionLost(SymbolName);
|
||||||
|
@ -47,7 +47,7 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
public bool Complete { get; set; }
|
public bool Complete { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Compare 2 stat snapshots to eachother
|
/// Compare 2 stat snapshots to each other
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TradesCompare CompareTo(TradesStats otherStats)
|
public TradesCompare CompareTo(TradesStats otherStats)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user