Skip to content

Commit

Permalink
Merge pull request #172 from coinapi/SDKConsoleApp
Browse files Browse the repository at this point in the history
latency_type param
  • Loading branch information
kgrudzien authored Mar 27, 2024
2 parents 923116f + 6eb7d30 commit 87dbe63
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
33 changes: 30 additions & 3 deletions data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ internal enum Endpoints
ncsa
}

internal enum LatencyType
{
nc, //Now-CoinAPI
ne, //Now-Exchange
ce, //CoinAPI-Exchange
}

internal class Program
{
public static IConfiguration Configuration { get; private set; }
Expand Down Expand Up @@ -75,7 +82,7 @@ static async Task Main(string[] args)

public async Task MakeRequest([FromService] IConfiguration configuration, string endpoint_name = null,
string subscribe_data_type = null, string asset = null, string symbol = null,
string exchange = null, string apikey = null, string type = "hello", bool supress_hb = false)
string exchange = null, string apikey = null, string type = "hello", bool supress_hb = false, string latency_type = "ce")
{
var typeNames = Enum.GetNames<SubType>().ToList();
if (!typeNames.Any(x => x == subscribe_data_type))
Expand All @@ -90,12 +97,19 @@ public async Task MakeRequest([FromService] IConfiguration configuration, string
Serilog.Log.Error($"Invalid endpoint_name, valid values: {string.Join(",", endpointNames)}");
return;
}
var latencyTypes = Enum.GetNames<LatencyType>().ToList();
if (!string.IsNullOrWhiteSpace(latency_type) && !latencyTypes.Any(x => x == latency_type))
{
Serilog.Log.Error($"Invalid latency_type, valid values: {string.Join(",", latencyTypes)}");
return;
}

using (var wsClient = string.IsNullOrWhiteSpace(endpoint_name) ? new CoinApiWsClient() : new CoinApiWsClient(Endpoints[endpoint_name]))
{
wsClient.SupressHeartbeat(supress_hb);
int msgCount = 0;
int errorCount = 0;
LatencyType latencyType = Enum.GetValues<LatencyType>().FirstOrDefault(x => x.ToString() == latency_type);

void WsClient_Error(object? sender, Exception e)
{
Expand All @@ -112,7 +126,18 @@ void ProcessMsg(DateTime? time_exchange, DateTime? time_coinapi)
msgCount++;
if (time_coinapi.HasValue && time_exchange.HasValue)
{
latencyList.Add((time_exchange.Value, time_coinapi.Value));
switch(latencyType)
{
case LatencyType.nc:
latencyList.Add((DateTime.UtcNow, time_coinapi.Value));
break;
case LatencyType.ne:
latencyList.Add((DateTime.UtcNow, time_exchange.Value));
break;
case LatencyType.ce:
latencyList.Add((time_coinapi.Value, time_exchange.Value));
break;
}
}
}

Expand Down Expand Up @@ -180,6 +205,8 @@ void ProcessMsg(DateTime? time_exchange, DateTime? time_coinapi)
{
strbld.Append($", symbol = {symbol}");
}
strbld.Append($", supress_hb = {supress_hb}");
strbld.Append($", latency_type = {latency_type}");

Serilog.Log.Information(strbld.ToString());

Expand Down Expand Up @@ -222,7 +249,7 @@ void ProcessMsg(DateTime? time_exchange, DateTime? time_coinapi)

var msgCountOnInterval = msgCount - msgCountPrev;
var bytesCountOnInterval = wsClient.TotalBytesReceived - totalBytesReceivedPrev;
var latencies = latencyList.Select(x => x.Item2 - x.Item1).ToList();
var latencies = latencyList.Select(x => x.Item1 - x.Item2).ToList();
latencyList.Clear();


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"CoinAPI.WebSocket.Stats.Console": {
"commandName": "Project",
"commandLineArgs": "--subscribe_data_type book --symbol COINBASE_SPOT_BTC_USD$"
"commandLineArgs": ""
}
}
}
31 changes: 30 additions & 1 deletion data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,44 @@ dotnet run -- [options]
- `--apikey <APIKEY>`: Your CoinAPI API key. Optional if specified in `appsettings.json`.
- `--type <TYPE>`: The type of message to send. Default is "hello".
- `--supress_hb <BOOL>`: Whether to suppress heartbeat messages. Default is false.
- `--latency_type <TYPE>`: Type of measured latency, valid types are:
- `nc` client UTC to CoinApi time,
- `ne` client UTC to exchange time
- `ce` CoinApi time to exchange time.

Default value is `ce`.

### Example

```bash
dotnet run -- --endpoint_name emea --subscribe_data_type quote --symbol COINBASE_SPOT_BTC_USD$
```

which is equivalent to:
```bash
dotnet run -- --endpoint_name emea --subscribe_data_type quote --symbol COINBASE_SPOT_BTC_USD$ --supress_hb false --latency_type ce
```
This command subscribes to quote data for the BTC_USD spot symbol in Coinbase exchange from the EMEA endpoint.

### Output
```terminal
[10:32:35 DBG] Hosting starting
[10:32:35 DBG] Hosting started
[10:32:35 INF] Time: 03/27/2024 09:32:35
[10:32:35 INF] Subscribed to: subscribe_data_type = quote, symbol = COINBASE_SPOT_BTC_USD$, supress_hb = False, latency_type = ce
[10:32:35 INF] Endpoint ws://api-emea.coinapi.net, 0 iterations, 0 messages received, 0 bytes received, Error count 0
[10:32:36 INF] Messages: 138 | Recv bytes: 34351 | CPU: wait: 97.58% | parse: 2.32% | process: 0.10% | Latency min: 51.9639 ms | max: 249.1233ms
[10:32:37 INF] Messages: 109 | Recv bytes: 27166 | CPU: wait: 99.66% | parse: 0.33% | process: 0.01% | Latency min: 51.9898 ms | max: 70.521 ms
[10:32:38 INF] Messages: 94 | Recv bytes: 23411 | CPU: wait: 99.78% | parse: 0.21% | process: 0.01% | Latency min: 51.8882 ms | max: 85.2687 ms
[10:32:39 INF] Messages: 236 | Recv bytes: 58615 | CPU: wait: 99.66% | parse: 0.32% | process: 0.02% | Latency min: 51.8318 ms | max: 170.4874ms
[10:32:40 INF] Messages: 89 | Recv bytes: 22200 | CPU: wait: 99.81% | parse: 0.18% | process: 0.01% | Latency min: 51.8809 ms | max: 61.0727 ms
[10:32:41 INF] Messages: 24 | Recv bytes: 5900 | CPU: wait: 99.94% | parse: 0.06% | process: 0.00% | Latency min: 52.0308 ms | max: 58.7746 ms
[10:32:42 INF] Messages: 136 | Recv bytes: 33908 | CPU: wait: 99.72% | parse: 0.26% | process: 0.01% | Latency min: 51.8673 ms | max: 88.1614 ms
[10:32:43 INF] Messages: 241 | Recv bytes: 60031 | CPU: wait: 99.61% | parse: 0.38% | process: 0.02% | Latency min: 51.8677 ms | max: 57.4617 ms
[10:32:44 INF] Messages: 176 | Recv bytes: 43977 | CPU: wait: 99.66% | parse: 0.32% | process: 0.02% | Latency min: 51.6744 ms | max: 64.6544 ms
[10:32:45 INF] Messages: 292 | Recv bytes: 72844 | CPU: wait: 99.54% | parse: 0.43% | process: 0.03% | Latency min: 51.9092 ms | max: 60.2158 ms
[10:32:45 INF] Endpoint ws://api-emea.coinapi.net, 10 iterations, 1555 messages received, 387420 bytes received, Error count 0
[10:32:46 INF] Messages: 116 | Recv bytes: 28854 | CPU: wait: 99.77% | parse: 0.22% | process: 0.01% | Latency min: 51.786
```
## Logging

The application logs detailed information to the console, including subscribed data types, message counts, CPU usage, and latencies.
Expand Down

0 comments on commit 87dbe63

Please sign in to comment.