Skip to content

Instantly share code, notes, and snippets.

@nathan130200
Last active October 8, 2025 00:47
Show Gist options
  • Save nathan130200/722de202b79a73249b80c775c763ec73 to your computer and use it in GitHub Desktop.
Save nathan130200/722de202b79a73249b80c775c763ec73 to your computer and use it in GitHub Desktop.
Codigo fonte do app pra testar a latência do boosteroid.

Dependencias

Precisa da biblioteca Spectre.Console versão 0.51.1

Como funciona

Esse app vai testar todos os hosts disponíveis (configurado pelo código) o ping de cada um deles do servidor do boosteroid e vai exibir na janela do CMD um resumo da latência (min, max, média e ultimo ping)

Por padrão já vem com as 3 principais hosts mais usadas (jacksonville = jv e os dois servidores do brasil sp e so)

using Spectre.Console;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Net.NetworkInformation;
Console.Title = "BOOSTEROID - PING TEST";
List<Entry> hosts = [];
{
var regions = new (string key, int count)[]
{
("so", 7),
("sp", 7),
("jv", 7)
};
foreach (var region in regions)
{
for (var i = 0; i <= region.count; i++)
hosts.Add(new(region.key, $"{region.key}{i}.cloud.boosteroid.com"));
}
}
var comparer = Comparer<Entry>.Create((x, y) =>
{
var r1 = x.Hostname.Split('.')[0];
var r2 = y.Hostname.Split('.')[0];
return r1.CompareTo(r2);
});
hosts.Sort(comparer);
using var ping = new PingService();
var tasks = new List<Task>();
Console.CursorVisible = false;
var process = true;
_ = Task.Run(() =>
{
while (true)
{
if (Console.KeyAvailable)
{
if (Console.ReadKey(true).KeyChar == 'q')
{
process = false;
break;
}
}
}
});
while (process)
{
await Task.Delay(1500);
try
{
Console.Clear();
var grid = new Grid().AddColumns(6);
grid.AddRow([
new Text("Endereço").Centered(),
new Text("Min").Centered(),
new Text("Max").Centered(),
new Text("Atual").Centered(),
new Text("Media").Centered(),
]);
foreach (var entries in hosts.GroupBy(x => x.Region))
{
foreach (var entry in entries)
{
var stats = entry.GetStats();
static Color? MapColor(long last, long min, long max)
{
if (min < last) return Color.Green;
if (max > last) return Color.Red;
return null;
}
var columns = new Text[]
{
new Text(entry.Hostname).Centered(),
new Text(stats.MinRtt + "ms", new(Color.Aqua)).Centered(),
new Text(stats.MaxRtt + "ms", new(Color.Orange1)).Centered(),
new Text(stats.LastRtt + "ms",
new Style(
foreground: MapColor(stats.LastRtt, stats.MinRtt, stats.MaxRtt)
)
).Centered(),
new Text($"{stats.AvgRtt:###}ms",
new Style(
foreground: MapColor((long)stats.AvgRtt, stats.MinRtt, stats.MaxRtt)
)
).Centered()
};
grid.AddRow(columns);
}
}
AnsiConsole.Write(grid);
foreach (var entry in hosts)
tasks.Add(entry.ExecuteAsync(ping));
await Task.WhenAll(tasks).ConfigureAwait(false);
}
finally
{
tasks.Clear();
}
}
class Entry
{
readonly Queue<long> _samples = [];
long _minTime, _maxTime;
float _avgTime;
public string Region { get; }
public string Hostname { get; }
public Entry(string region, string hostname)
{
Region = region;
Hostname = hostname;
}
const int NumKeepMaxSamples = 16;
void AddSample(long latency)
{
lock (this)
{
while (_samples.Count > NumKeepMaxSamples)
_samples.Dequeue();
_samples.Enqueue(latency);
if (_minTime == 0) _minTime = latency;
else _minTime = Math.Min(_minTime, latency);
if (_maxTime == 0) _maxTime = latency;
else _maxTime = Math.Max(_maxTime, latency);
long sum = 0;
foreach (var sample in _samples)
{
if (sample >= 0)
sum += sample;
}
_avgTime = (float)(sum / (float)_samples.Count);
}
}
public (long MinRtt, long MaxRtt, long LastRtt, float AvgRtt) GetStats()
{
lock (this)
{
return (
_minTime,
_maxTime,
_samples.LastOrDefault(),
_avgTime
);
}
}
public async Task ExecuteAsync(PingService ping)
{
var reply = await ping.SendAsync(Hostname);
if (reply.Status != IPStatus.Success)
AddSample(-1);
else
AddSample(reply.RoundtripTime);
}
}
public class PingService : IDisposable
{
readonly Ping _ping = new();
readonly ConcurrentQueue<(string Hostname, TaskCompletionSource<PingReply> Completion)> _queue = [];
volatile bool _disposed;
public PingService()
{
_ = Task.Run(async () =>
{
try
{
while (!_disposed)
{
if (_queue.TryDequeue(out var entry))
{
try
{
var result = await _ping.SendPingAsync(entry.Hostname);
entry.Completion.TrySetResult(result);
}
catch (Exception ex)
{
entry.Completion.TrySetException(ex);
}
}
await Task.Delay(1);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
while (_queue.TryDequeue(out var entry))
entry.Completion.TrySetCanceled();
});
}
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
while (_queue.TryDequeue(out var entry))
entry.Completion.TrySetCanceled();
_ping.Dispose();
}
}
public Task<PingReply> SendAsync(string hostname)
{
var tcs = new TaskCompletionSource<PingReply>();
_queue.Enqueue((hostname, tcs));
return tcs.Task;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment