2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2026-04-29 06:48:41 +00:00
This commit is contained in:
2026-04-04 23:54:59 +03:00
parent 5b0fba89a4
commit 44983d7784
17 changed files with 181 additions and 66 deletions
@@ -7,4 +7,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Libraries\Esiur\Esiur.csproj" OutputItemType="Analyzer" />
</ItemGroup>
</Project>
@@ -19,7 +19,7 @@
using Esiur.Resource;
using Esiur.Stores;
using Esiur.Net.IIP;
using Esiur.Protocol;
using System.Diagnostics;
var mode = GetArg(args, "--mode", "both");
@@ -29,28 +29,30 @@ var concurrent = int.Parse(GetArg(args, "--concurrent", "50"));
var resources = int.Parse(GetArg(args, "--resources", "200"));
var timeoutMs = int.Parse(GetArg(args, "--timeout", "10000"));
var rounds = int.Parse(GetArg(args, "--rounds", "5"));
var wh = new Warehouse();
// ----------------------------------------------------------------
// SERVER SIDE
// ----------------------------------------------------------------
if (mode == "server" || mode == "both")
{
await Warehouse.Put("sys", new MemoryStore());
await Warehouse.Put("sys/server", new DistributedServer() { Port = (ushort)port });
await wh.Put("sys", new MemoryStore());
await wh.Put("sys/server", new EpServer() { Port = (ushort)port });
for (int i = 0; i < resources; i++)
{
await Warehouse.Put($"sys/sensor_{i}", new SensorResource { SensorId = i, Value = i });
await wh.Put($"sys/sensor_{i}", new SensorResource { SensorId = i, Value = i });
}
await Warehouse.Open();
await wh.Open();
Console.WriteLine($"[Server-T3] Ready: {resources} resources on port {port}");
if (mode == "server")
{
Console.WriteLine("Press ENTER to stop.");
Console.ReadLine();
await Warehouse.Close();
await wh.Close();
return;
}
@@ -88,7 +90,7 @@ for (int round = 0; round < rounds; round++)
using var cts = new CancellationTokenSource(timeoutMs);
try
{
var proxy = await Warehouse.Get<IResource>(
var proxy = await wh.Get<IResource>(
$"iip://{host}:{port}/sys/sensor_{resourceIdx}");
sw.Stop();
@@ -160,7 +162,7 @@ await File.WriteAllTextAsync("test3_concurrent_attach.csv", csv);
Console.WriteLine("\n[Client-T3] Results written to test3_concurrent_attach.csv");
if (mode == "both")
await Warehouse.Close();
await wh.Close();
// ----------------------------------------------------------------
@@ -0,0 +1,15 @@
using Esiur.Resource;
/// <summary>
/// Shared observable sensor resource used across all scalability tests.
/// Property changes via Value setter are automatically propagated
/// to all attached remote peers by the Esiur runtime.
/// </summary>
[Resource]
public partial class SensorResource : Resource
{
public int SensorId { get; set; }
[Export]
public double value;
}
@@ -7,4 +7,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Libraries\Esiur\Esiur.csproj" OutputItemType="Analyzer" />
</ItemGroup>
</Project>
@@ -17,9 +17,9 @@
// Usage (client only): dotnet run -- --mode client --host 127.0.0.1 --concurrent 50 --resources 200
// ============================================================
using Esiur.Protocol;
using Esiur.Resource;
using Esiur.Stores;
using Esiur.Net.IIP;
using System.Diagnostics;
var mode = GetArg(args, "--mode", "both");
@@ -30,27 +30,28 @@ var resources = int.Parse(GetArg(args, "--resources", "200"));
var timeoutMs = int.Parse(GetArg(args, "--timeout", "10000"));
var rounds = int.Parse(GetArg(args, "--rounds", "5"));
var wh = new Warehouse();
// ----------------------------------------------------------------
// SERVER SIDE
// ----------------------------------------------------------------
if (mode == "server" || mode == "both")
{
await Warehouse.Put("sys", new MemoryStore());
await Warehouse.Put("sys/server", new DistributedServer() { Port = (ushort)port });
await wh.Put("sys", new MemoryStore());
await wh.Put("sys/server", new EpServer() { Port = (ushort)port });
for (int i = 0; i < resources; i++)
{
await Warehouse.Put($"sys/sensor_{i}", new SensorResource { SensorId = i, Value = i });
await wh.Put($"sys/sensor_{i}", new SensorResource { SensorId = i, Value = i });
}
await Warehouse.Open();
await wh.Open();
Console.WriteLine($"[Server-T3] Ready: {resources} resources on port {port}");
if (mode == "server")
{
Console.WriteLine("Press ENTER to stop.");
Console.ReadLine();
await Warehouse.Close();
await wh.Close();
return;
}
@@ -88,7 +89,7 @@ for (int round = 0; round < rounds; round++)
using var cts = new CancellationTokenSource(timeoutMs);
try
{
var proxy = await Warehouse.Get<IResource>(
var proxy = await wh.Get<IResource>(
$"iip://{host}:{port}/sys/sensor_{resourceIdx}");
sw.Stop();
@@ -160,7 +161,7 @@ await File.WriteAllTextAsync("test3_concurrent_attach.csv", csv);
Console.WriteLine("\n[Client-T3] Results written to test3_concurrent_attach.csv");
if (mode == "both")
await Warehouse.Close();
await wh.Close();
// ----------------------------------------------------------------
@@ -0,0 +1,15 @@
using Esiur.Resource;
/// <summary>
/// Shared observable sensor resource used across all scalability tests.
/// Property changes via Value setter are automatically propagated
/// to all attached remote peers by the Esiur runtime.
/// </summary>
[Resource]
public partial class SensorResource : Resource
{
public int SensorId { get; set; }
[Export]
public double value;
}
@@ -7,4 +7,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Libraries\Esiur\Esiur.csproj" OutputItemType="Analyzer"/>
</ItemGroup>
</Project>
@@ -32,11 +32,13 @@ var latencyLock = new object();
var proxies = new dynamic[resourceCount];
var sw = Stopwatch.StartNew();
var wh = new Warehouse();
try
{
for (int i = 0; i < resourceCount; i++)
{
proxies[i] = await Warehouse.Get<IResource>($"iip://{host}:{port}/sys/sensor_{i}");
proxies[i] = await wh.Get<IResource>($"iip://{host}:{port}/sys/sensor_{i}");
// Subscribe to property change notifications via the Esiur event model
double lastValue = (double)proxies[i].Value;
@@ -7,4 +7,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Libraries\Esiur\Esiur.csproj" OutputItemType="Analyzer"/>
</ItemGroup>
</Project>
@@ -9,8 +9,8 @@
using Esiur.Resource;
using Esiur.Stores;
using Esiur.Net.IIP;
using System.Diagnostics;
using System.Diagnostics;
using Esiur.Protocol;
var resourceCount = int.Parse(GetArg(args, "--resources", "100"));
var intervalMs = int.Parse(GetArg(args, "--interval", "50"));
@@ -18,19 +18,20 @@ var port = int.Parse(GetArg(args, "--port", "10900"));
Console.WriteLine($"[Server] resources={resourceCount} interval={intervalMs}ms port={port}");
var wh = new Warehouse();
// --- Warehouse setup -------------------------------------------------
await Warehouse.Put("sys", new MemoryStore());
await Warehouse.Put("sys/server", new DistributedServer() { Port = (ushort)port });
await wh.Put("sys", new MemoryStore());
await wh.Put("sys/server", new EpServer() { Port = (ushort)port });
// Create and register all sensor resources
var sensors = new SensorResource[resourceCount];
for (int i = 0; i < resourceCount; i++)
{
sensors[i] = new SensorResource { SensorId = i };
await Warehouse.Put($"sys/sensor_{i}", sensors[i]);
await wh.Put($"sys/sensor_{i}", sensors[i]);
}
await Warehouse.Open();
await wh.Open();
Console.WriteLine($"[Server] Listening on port {port} with {resourceCount} resources.");
// --- Emit loop -------------------------------------------------------
@@ -68,7 +69,7 @@ _ = Task.Run(async () =>
Console.WriteLine("Press ENTER to stop.");
Console.ReadLine();
await Warehouse.Close();
await wh.Close();
// --- Helpers ---------------------------------------------------------
@@ -1,24 +1,15 @@
using Esiur.Resource;
/// <summary>
/// A simple observable sensor resource.
/// Property changes are automatically propagated to all attached peers.
/// Shared observable sensor resource used across all scalability tests.
/// Property changes via Value setter are automatically propagated
/// to all attached remote peers by the Esiur runtime.
/// </summary>
[Resource]
public class SensorResource : Resource
public partial class SensorResource : Resource
{
public int SensorId { get; set; }
private double _value;
[ResourceProperty]
public double Value
{
get => _value;
set
{
_value = value;
PropertyModified("Value"); // notifies Esiur runtime to propagate
}
}
[Export]
public double value;
}
@@ -7,4 +7,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Libraries\Esiur\Esiur.csproj" />
</ItemGroup>
</Project>
@@ -23,7 +23,7 @@ var proxies = new dynamic[resourceCount];
// --- Attach in batches to avoid overwhelming the runtime -------------
var totalSw = Stopwatch.StartNew();
var wh = new Warehouse();
for (int batch = 0; batch < resourceCount; batch += batchSize)
{
int end = Math.Min(batch + batchSize, resourceCount);
@@ -35,7 +35,7 @@ for (int batch = 0; batch < resourceCount; batch += batchSize)
batchTasks[i - batch] = Task.Run(async () =>
{
var sw = Stopwatch.StartNew();
proxies[capturedI] = await Warehouse.Get<IResource>(
proxies[capturedI] = await wh.Get<IResource>(
$"iip://{host}:{port}/sys/sensor_{capturedI}");
sw.Stop();
@@ -7,4 +7,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Libraries\Esiur\Esiur.csproj" OutputItemType="Analyzer"/>
</ItemGroup>
</Project>
@@ -8,25 +8,27 @@
using Esiur.Resource;
using Esiur.Stores;
using Esiur.Net.IIP;
using Esiur.Protocol;
var resourceCount = int.Parse(GetArg(args, "--resources", "10000"));
var port = int.Parse(GetArg(args, "--port", "10901"));
Console.WriteLine($"[Server-T2] Creating {resourceCount} resources on port {port}");
await Warehouse.Put("sys", new MemoryStore());
await Warehouse.Put("sys/server", new DistributedServer() { Port = (ushort)port });
var wh = new Warehouse();
await wh.Put("sys", new MemoryStore());
await wh.Put("sys/server", new EpServer() { Port = (ushort)port });
long memBefore = GC.GetTotalMemory(forceFullCollection: true);
for (int i = 0; i < resourceCount; i++)
{
var s = new SensorResource { SensorId = i, Value = i * 0.1 };
await Warehouse.Put($"sys/sensor_{i}", s);
await wh.Put($"sys/sensor_{i}", s);
}
await Warehouse.Open();
await wh.Open();
long memAfter = GC.GetTotalMemory(forceFullCollection: true);
double memMB = (memAfter - memBefore) / (1024.0 * 1024.0);
@@ -35,7 +37,7 @@ Console.WriteLine($"[Server-T2] Ready. Resources={resourceCount} MemoryUsed={me
Console.WriteLine($"[Server-T2] Per-resource ≈ {(memAfter - memBefore) / (double)resourceCount:F0} bytes");
Console.WriteLine("Press ENTER to stop.");
Console.ReadLine();
await Warehouse.Close();
await wh.Close();
static string GetArg(string[] args, string key, string def)
@@ -0,0 +1,15 @@
using Esiur.Resource;
/// <summary>
/// Shared observable sensor resource used across all scalability tests.
/// Property changes via Value setter are automatically propagated
/// to all attached remote peers by the Esiur runtime.
/// </summary>
[Resource]
public partial class SensorResource : Resource
{
public int SensorId { get; set; }
[Export]
public double value;
}