mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2026-04-13 00:22:22 +00:00
Compare commits
No commits in common. "61c66300af9d6b6289599edd56080e6ae62ba7c1" and "0d3ccf25a732065d0263f4f0e46d88f1008ecfac" have entirely different histories.
61c66300af
...
0d3ccf25a7
@ -1,94 +0,0 @@
|
|||||||
using CryptoExchange.Net.Objects;
|
|
||||||
using CryptoExchange.Net.Sockets.Default;
|
|
||||||
using CryptoExchange.Net.Sockets.Default.Routing;
|
|
||||||
using CryptoExchange.Net.Sockets.Interfaces;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.UnitTests
|
|
||||||
{
|
|
||||||
internal class RoutingTableTests
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void Constructor_CreatesEntriesAndDeduplicatesHandlersPerTypeIdentifier()
|
|
||||||
{
|
|
||||||
var processor = new TestMessageProcessor(1, MessageRouter.Create(
|
|
||||||
MessageRoute<string>.CreateWithoutTopicFilter("ticker", EmptyHandler<string>()),
|
|
||||||
MessageRoute<string>.CreateWithTopicFilter("ticker", "btcusdt", EmptyHandler<string>()),
|
|
||||||
MessageRoute<int>.CreateWithoutTopicFilter("trade", EmptyHandler<int>())));
|
|
||||||
|
|
||||||
var routingTable = new RoutingTable(new[] { processor });
|
|
||||||
var tickerEntry = routingTable.GetRouteTableEntry("ticker");
|
|
||||||
var tradeEntry = routingTable.GetRouteTableEntry("trade");
|
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
|
||||||
{
|
|
||||||
Assert.That(tickerEntry, Is.Not.Null);
|
|
||||||
Assert.That(tickerEntry!.DeserializationType, Is.EqualTo(typeof(string)));
|
|
||||||
Assert.That(tickerEntry.IsStringOutput, Is.True);
|
|
||||||
Assert.That(tickerEntry.Handlers, Has.Count.EqualTo(1));
|
|
||||||
Assert.That(tickerEntry.Handlers[0], Is.SameAs(processor));
|
|
||||||
|
|
||||||
Assert.That(tradeEntry, Is.Not.Null);
|
|
||||||
Assert.That(tradeEntry!.DeserializationType, Is.EqualTo(typeof(int)));
|
|
||||||
Assert.That(tradeEntry.IsStringOutput, Is.False);
|
|
||||||
Assert.That(tradeEntry.Handlers, Has.Count.EqualTo(1));
|
|
||||||
Assert.That(tradeEntry.Handlers[0], Is.SameAs(processor));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Constructor_AddsAllProcessorsForSameTypeIdentifier()
|
|
||||||
{
|
|
||||||
var processor1 = new TestMessageProcessor(1, MessageRouter.Create(
|
|
||||||
MessageRoute<string>.CreateWithoutTopicFilter("ticker", EmptyHandler<string>())));
|
|
||||||
var processor2 = new TestMessageProcessor(2, MessageRouter.Create(
|
|
||||||
MessageRoute<string>.CreateWithTopicFilter("ticker", "ethusdt", EmptyHandler<string>())));
|
|
||||||
|
|
||||||
var routingTable = new RoutingTable(new IMessageProcessor[] { processor1, processor2 });
|
|
||||||
var entry = routingTable.GetRouteTableEntry("ticker");
|
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
|
||||||
{
|
|
||||||
Assert.That(entry, Is.Not.Null);
|
|
||||||
Assert.That(entry!.Handlers, Has.Count.EqualTo(2));
|
|
||||||
Assert.That(entry.Handlers, Does.Contain(processor1));
|
|
||||||
Assert.That(entry.Handlers, Does.Contain(processor2));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void GetRouteTableEntry_ReturnsNullForUnknownTypeIdentifier()
|
|
||||||
{
|
|
||||||
var processor = new TestMessageProcessor(1, MessageRouter.Create(
|
|
||||||
MessageRoute<string>.CreateWithoutTopicFilter("ticker", EmptyHandler<string>())));
|
|
||||||
|
|
||||||
var routingTable = new RoutingTable(new[] { processor });
|
|
||||||
|
|
||||||
Assert.That(routingTable.GetRouteTableEntry("unknown"), Is.Null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Func<SocketConnection, DateTime, string?, T, CallResult?> EmptyHandler<T>()
|
|
||||||
{
|
|
||||||
return (_, _, _, _) => null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestMessageProcessor : IMessageProcessor
|
|
||||||
{
|
|
||||||
public int Id { get; }
|
|
||||||
public MessageRouter MessageRouter { get; }
|
|
||||||
public event Action? OnMessageRouterUpdated;
|
|
||||||
|
|
||||||
public TestMessageProcessor(int id, MessageRouter messageRouter)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
MessageRouter = messageRouter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Handle(string typeIdentifier, string? topicFilter, SocketConnection socketConnection, DateTime receiveTime, string? originalData, object result)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -45,7 +45,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
public override Error? ValidateRequest(string exchange, GetOrderBookRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
public override Error? ValidateRequest(string exchange, GetOrderBookRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
||||||
{
|
{
|
||||||
if (request.Limit == null)
|
if (request.Limit == null)
|
||||||
return base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
return null;
|
||||||
|
|
||||||
if (MaxLimit.HasValue && request.Limit.Value > MaxLimit)
|
if (MaxLimit.HasValue && request.Limit.Value > MaxLimit)
|
||||||
return ArgumentError.Invalid(nameof(GetOrderBookRequest.Limit), $"Max limit is {MaxLimit}");
|
return ArgumentError.Invalid(nameof(GetOrderBookRequest.Limit), $"Max limit is {MaxLimit}");
|
||||||
|
|||||||
@ -22,12 +22,8 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Error? ValidateRequest(string exchange, GetRecentTradesRequest request, TradingMode? tradingMode, TradingMode[] supportedApiTypes)
|
public Error? Validate(GetRecentTradesRequest request)
|
||||||
{
|
{
|
||||||
var baseError = base.ValidateRequest(exchange, request, tradingMode, supportedApiTypes);
|
|
||||||
if (baseError != null)
|
|
||||||
return baseError;
|
|
||||||
|
|
||||||
if (request.Limit > MaxLimit)
|
if (request.Limit > MaxLimit)
|
||||||
return ArgumentError.Invalid(nameof(GetRecentTradesRequest.Limit), $"Only the most recent {MaxLimit} trades are available");
|
return ArgumentError.Invalid(nameof(GetRecentTradesRequest.Limit), $"Only the most recent {MaxLimit} trades are available");
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,7 @@ namespace CryptoExchange.Net.Sockets.Default.Routing
|
|||||||
private List<MessageRoute> _routesWithoutTopicFilter;
|
private List<MessageRoute> _routesWithoutTopicFilter;
|
||||||
private Dictionary<string, List<MessageRoute>> _routesWithTopicFilter;
|
private Dictionary<string, List<MessageRoute>> _routesWithTopicFilter;
|
||||||
#if NET8_0_OR_GREATER
|
#if NET8_0_OR_GREATER
|
||||||
|
// Used for mapping a type identifier to the routes matching it
|
||||||
private FrozenDictionary<string, List<MessageRoute>>? _routesWithTopicFilterFrozen;
|
private FrozenDictionary<string, List<MessageRoute>>? _routesWithTopicFilterFrozen;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -128,7 +129,6 @@ namespace CryptoExchange.Net.Sockets.Default.Routing
|
|||||||
{
|
{
|
||||||
result ??= thisResult;
|
result ??= thisResult;
|
||||||
|
|
||||||
#warning MultipleReaders is only for queries, subscriptions should always have multiple readers = true. Maybe create different RoutingSubTable implementations for Queries and Subscriptions?
|
|
||||||
if (!MultipleReaders)
|
if (!MultipleReaders)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user