Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MagicOnion 7.0 #791

Merged
merged 88 commits into from
Jun 17, 2024
Merged
Changes from 2 commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
9a3ac31
Multicaster
mayuki May 2, 2024
151ad5d
Update
mayuki May 2, 2024
c611fdd
Update
mayuki May 2, 2024
578767d
Update
mayuki May 7, 2024
a403615
Update
mayuki May 8, 2024
58a974f
Implicitly call AddLogging and AddGrpc
mayuki May 8, 2024
339cbdd
Update build-canary.yml
mayuki May 8, 2024
2563db3
Update build-debug.yml
mayuki May 8, 2024
13fbd09
Merge pull request #768 from Cysharp/feature/ImplicitlyAddLoggingAndGrpc
mayuki May 8, 2024
9e42910
Bump version to 7.0
mayuki May 8, 2024
e2f6428
Make StreamingHubHandlerRepository non-static class
mayuki May 8, 2024
f1e9adc
Merge pull request #769 from Cysharp/feature/BumpVersion7.0
mayuki May 8, 2024
dc90d87
Merge pull request #770 from Cysharp/feature/refactor/StreamingHubHan…
mayuki May 8, 2024
0d02295
Removal of support for NET 7
mayuki May 8, 2024
d7a5cc9
Merge pull request #771 from Cysharp/feature/RemoveNet7.0
mayuki May 8, 2024
46b8873
Add support for void as a return type for StreamingHub
mayuki Apr 8, 2024
94d323a
Update reference sources
mayuki May 8, 2024
23e72ff
Remove an unused test case
mayuki May 8, 2024
4f9d226
Fix unit test
mayuki May 8, 2024
fb31696
Fix unit test
mayuki May 8, 2024
ed08f70
Merge pull request #772 from Cysharp/feature/StreamingHubVoidMethod
mayuki May 8, 2024
e9afc54
Merge branch 'main' into vNext
mayuki May 9, 2024
508a465
Pooling Payload on the server's StreamingHub.
mayuki Apr 9, 2024
a8d8c7d
Return ArrayPoolBufferWriter
mayuki May 8, 2024
2e22679
Cleanup codes
mayuki May 8, 2024
c357d3a
Cleanup codes
mayuki May 8, 2024
b201f3b
Update reference sources
mayuki May 9, 2024
d1aa67f
Merge pull request #774 from Cysharp/feature/MemoryPool
mayuki May 9, 2024
1e81d0a
Refactor StreamingHub message handling
mayuki May 9, 2024
02da73e
Merge pull request #775 from Cysharp/feature/refactor/StreamingHubMes…
mayuki May 9, 2024
6b3fea0
Process requests outside the message loop
mayuki May 9, 2024
4f72d94
Cleanup usings
mayuki May 9, 2024
837504f
CancellationToken
mayuki May 9, 2024
f53e40c
Add unit test
mayuki May 20, 2024
78c7eac
Fix warnings
mayuki May 20, 2024
3eb31a7
Merge pull request #776 from Cysharp/feature/ProcessRequestOutsideMes…
mayuki May 20, 2024
41a7ad3
Merge branch 'vNext' into poc/Multicaster
mayuki May 20, 2024
c0e372a
Change the backend of HubGroup to Multicaster
mayuki May 29, 2024
0db3c7d
Remove Broadcast*
mayuki May 29, 2024
9b17004
Update Multicaster
mayuki May 30, 2024
e3019ee
Merge pull request #778 from Cysharp/feature/Multicaster
mayuki May 30, 2024
1e1f84b
Expose ServiceContext
mayuki May 30, 2024
3c8e94a
Make StreamingServiceContext as a private field
mayuki May 30, 2024
dfe700d
Merge pull request #779 from Cysharp/feature/ExposeServiceContext
mayuki May 30, 2024
8cfdb07
Multicaster 0.1.4
mayuki May 30, 2024
d4fa162
Merge pull request #780 from Cysharp/feature/UpdateMulticaster-0.1.4
mayuki May 30, 2024
064d7ca
Update Multicaster to 0.1.5
mayuki May 31, 2024
d5237a2
SingleReader = true
mayuki May 31, 2024
b2882de
Add support for Client Results
mayuki Jun 5, 2024
13ffb96
Add support for Client Result with DynamicStreamingHubClientFactoryPr…
mayuki Jun 6, 2024
110e402
Fix source generator
mayuki Jun 6, 2024
6035fda
Cancel Client Result tasks when the connection has been disconnected
mayuki Jun 7, 2024
f5434e7
Add unit test
mayuki Jun 7, 2024
bc288c7
Add ClientResultsDefaultTimeout option
mayuki Jun 7, 2024
ce479b6
Dump Exception
mayuki Jun 7, 2024
891f03b
Fix test
mayuki Jun 7, 2024
32655b8
Merge pull request #783 from Cysharp/feature/ClientResult
mayuki Jun 7, 2024
668b7a7
Remove unused code
mayuki Jun 7, 2024
bb2259d
Add built-in heartbeat support to StreamingHub.
mayuki Jun 11, 2024
332eee8
Rename methods
mayuki Jun 11, 2024
2b147dc
Add unit tests
mayuki Jun 11, 2024
4fa9247
Return to pool
mayuki Jun 11, 2024
351f56b
Return to pool
mayuki Jun 11, 2024
fdbfbcb
Add unit tests
mayuki Jun 11, 2024
eeea1ae
Update generated sources
mayuki Jun 11, 2024
5452352
Use fixed bytes
mayuki Jun 11, 2024
4fc4044
Add unit tests
mayuki Jun 12, 2024
9631da6
Update document comment
mayuki Jun 12, 2024
761b7e7
Merge pull request #784 from Cysharp/feature/Heartbeat
mayuki Jun 12, 2024
ac9fe02
feat: Update MagicOnion.Client.SourceGenerator.Unity
github-actions[bot] Jun 12, 2024
753ddb1
Fix heartbeat log and timer
mayuki Jun 13, 2024
22253b7
Check timer
mayuki Jun 13, 2024
10aaed4
Merge pull request #785 from Cysharp/feature/FixHeartbeatLogAndTimer
mayuki Jun 13, 2024
5a54485
Reset ResponseSize
mayuki Jun 13, 2024
03c041a
Reduce allocation on StreamingHubClient method calls
mayuki Jun 14, 2024
c3de2a6
Fix deadlock
mayuki Jun 14, 2024
8d78eba
Merge pull request #786 from Cysharp/feature/ReduceAllocationStreamin…
mayuki Jun 14, 2024
7f64279
Reduce allocation on StreamingHubClient broadcast events
mayuki Jun 14, 2024
49b57ee
Merge pull request #787 from Cysharp/feature/ReduceBroadcastAllocatio…
mayuki Jun 14, 2024
fe52b7b
Fix MethodId
mayuki Jun 17, 2024
b96835e
Merge pull request #788 from Cysharp/feature/FixMethodId
mayuki Jun 17, 2024
7758c0d
Fix warnings
mayuki Jun 17, 2024
6407f91
Merge pull request #789 from Cysharp/feature/FixWarnings
mayuki Jun 17, 2024
0589f8b
Use Dictionary + lock instead of ConcurrentDictionary
mayuki Jun 17, 2024
0d71347
Update benchmark
mayuki Jun 17, 2024
0e5cb85
Fix build
mayuki Jun 17, 2024
036e813
Fix
mayuki Jun 17, 2024
02bf1ed
Merge pull request #790 from Cysharp/feature/ReduceAllocationOnStream…
mayuki Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions perf/Microbenchmark/Microbenchmark.Client/HubMethodBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using BenchmarkDotNet.Attributes;
using MagicOnion.Client.DynamicClient;

namespace Microbenchmark.Client;

[MemoryDiagnoser, RankColumn]
[ShortRunJob]
public class HubMethodBenchmarks
{
readonly StreamingHubClientTestHelper<ITestHub, ITestHubReceiver> helper;
readonly Task responseTask;
readonly ITestHub client;

static ReadOnlySpan<byte> IntResponse => [0xcd, 0x30, 0x39 /* 12345 (int) */];
static ReadOnlySpan<byte> NilResponse => [0xc0 /* Nil */];
static ReadOnlySpan<byte> StringResponse => [0xa6, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21 /* "Hello!" (string) */];

public HubMethodBenchmarks()
{
this.helper = new StreamingHubClientTestHelper<ITestHub, ITestHubReceiver>(new TestHubReceiver(), DynamicStreamingHubClientFactoryProvider.Instance);
this.responseTask = Task.Run(async () =>
{
while (true)
{
var req = await helper.ReadRequestNoDeserializeAsync();
if (req.MethodId is -2087943100 or 1273874383)
{
// Parameter_Zero_Return_ValueType, Parameter_Many_Return_ValueType
helper.WriteResponse(req.MessageId, req.MethodId, IntResponse);
}
else if (req.MethodId is -1841486598)
{
// ValueTask_Parameter_Zero_NoReturn
helper.WriteResponse(req.MessageId, req.MethodId, NilResponse);
}
else if (req.MethodId is -440496944 or -1110031569)
{
// Parameter_Zero_Return_RefType, Parameter_Many_Return_RefType
helper.WriteResponse(req.MessageId, req.MethodId, StringResponse);
}
}
});
this.client = helper.ConnectAsync().GetAwaiter().GetResult();
}

[Benchmark]
public async Task Void_Parameter_Zero_NoReturn()
{
client.Void_Parameter_Zero_NoReturn();
}

[Benchmark]
public async Task ValueTask_Parameter_Zero_NoReturn()
{
await client.ValueTask_Parameter_Zero_NoReturn();
}

[Benchmark]
public async Task Parameter_Zero_Return_ValueType()
{
var value = await client.Parameter_Zero_Return_ValueType();
}

[Benchmark]
public async Task Parameter_Many_Return_ValueType()
{
var value = await client.Parameter_Many_Return_ValueType("Hello", 12345, true);
}

[Benchmark]
public async Task Parameter_Zero_Return_RefType()
{
var value = await client.Parameter_Zero_Return_RefType();
}

[Benchmark]
public async Task Parameter_Many_Return_RefType()
{
var value = await client.Parameter_Many_Return_RefType("Hello", 12345, true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using BenchmarkDotNet.Attributes;
using MagicOnion.Client.DynamicClient;

namespace Microbenchmark.Client;

[MemoryDiagnoser, RankColumn]
[ShortRunJob]
public class HubReceiverBroadcastBenchmarks
{
StreamingHubClientTestHelper<ITestHub, ITestHubReceiver> helper = default!;
ITestHub client = default!;
TestHubReceiver receiver = default!;

static ReadOnlySpan<byte> BroadcastMessage_Parameter_Zero => [0x92, 0xce, 0x76, 0xe4, 0x37, 0x1b /* 1994667803 */, 0xc0 /* Nil */]; // [MethodId(int), SerializedArgument]
static ReadOnlySpan<byte> BroadcastMessage_Parameter_Many => [0x92, 0xce, 0x4c, 0xb8, 0x83, 0xca /* 1287160778 */, 0x93, 0xa6, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xcd, 0x30, 0x39, 0xc3 /* [ "Hello", 12345, true ] */]; // [MethodId(int), SerializedArgument]

void Setup()
{
this.receiver = new TestHubReceiver();
this.helper = new StreamingHubClientTestHelper<ITestHub, ITestHubReceiver>(receiver, DynamicStreamingHubClientFactoryProvider.Instance);
this.client = helper.ConnectAsync().GetAwaiter().GetResult();
}

[GlobalSetup(Targets = [nameof(Parameter_Zero), nameof(Parameter_Many)])]
public void UnsetSynchronizationContext()
{
SynchronizationContext.SetSynchronizationContext(null);
Setup();
}

[GlobalSetup(Targets = [nameof(Parameter_Zero_With_SynchronizationContext), nameof(Parameter_Many_With_SynchronizationContext)])]
public void SetSynchronizationContext()
{
SynchronizationContext.SetSynchronizationContext(new MySynchronizationContext());
Setup();
}

[Benchmark]
public void Parameter_Zero()
{
helper.WriteResponseRaw(BroadcastMessage_Parameter_Zero);
receiver.Received.Wait();
}

[Benchmark]
public void Parameter_Many()
{
helper.WriteResponseRaw(BroadcastMessage_Parameter_Many);
receiver.Received.Wait();
}

[Benchmark]
public void Parameter_Zero_With_SynchronizationContext()
{
helper.WriteResponseRaw(BroadcastMessage_Parameter_Zero);
receiver.Received.Wait();
}

[Benchmark]
public void Parameter_Many_With_SynchronizationContext()
{
helper.WriteResponseRaw(BroadcastMessage_Parameter_Many);
receiver.Received.Wait();
}
}
85 changes: 11 additions & 74 deletions perf/Microbenchmark/Microbenchmark.Client/Program.cs
Original file line number Diff line number Diff line change
@@ -1,90 +1,26 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using MagicOnion;
using MagicOnion.Client.DynamicClient;
using Microbenchmark.Client;

BenchmarkRunner.Run<Benchmarks>();
BenchmarkRunner.Run<HubReceiverBroadcastBenchmarks>();

[MemoryDiagnoser, RankColumn]
[ShortRunJob]
public class Benchmarks
{
readonly StreamingHubClientTestHelper<ITestHub, ITestHubReceiver> helper;
readonly Task responseTask;
readonly ITestHub client;

static ReadOnlySpan<byte> IntResponse => [0xcd, 0x30, 0x39 /* 12345 (int) */];
static ReadOnlySpan<byte> NilResponse => [0xc0 /* Nil */];
static ReadOnlySpan<byte> StringResponse => [0xa6, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21 /* "Hello!" (string) */];

public Benchmarks()
{
this.helper = new StreamingHubClientTestHelper<ITestHub, ITestHubReceiver>(new TestHubReceiver(), DynamicStreamingHubClientFactoryProvider.Instance);
this.responseTask = Task.Run(async () =>
{
while (true)
{
var req = await helper.ReadRequestNoDeserializeAsync();
if (req.MethodId is - 2087943100 or 1273874383)
{
// Parameter_Zero_Return_ValueType, Parameter_Many_Return_ValueType
helper.WriteResponse(req.MessageId, req.MethodId, IntResponse);
}
else if (req.MethodId is -1841486598)
{
// ValueTask_Parameter_Zero_NoReturn
helper.WriteResponse(req.MessageId, req.MethodId, NilResponse);
}
else if (req.MethodId is -440496944 or -1110031569)
{
// Parameter_Zero_Return_RefType, Parameter_Many_Return_RefType
helper.WriteResponse(req.MessageId, req.MethodId, StringResponse);
}
}
});
this.client = helper.ConnectAsync().GetAwaiter().GetResult();
}
class MySynchronizationContext : SynchronizationContext;

[Benchmark]
public async Task Void_Parameter_Zero_NoReturn()
{
client.Void_Parameter_Zero_NoReturn();
}

[Benchmark]
public async Task ValueTask_Parameter_Zero_NoReturn()
{
await client.ValueTask_Parameter_Zero_NoReturn();
}

[Benchmark]
public async Task Parameter_Zero_Return_ValueType()
{
var value = await client.Parameter_Zero_Return_ValueType();
}

[Benchmark]
public async Task Parameter_Many_Return_ValueType()
{
var value = await client.Parameter_Many_Return_ValueType("Hello", 12345, true);
}
class TestHubReceiver : ITestHubReceiver
{
public ManualResetEventSlim Received { get; } = new();

[Benchmark]
public async Task Parameter_Zero_Return_RefType()
public void Parameter_Zero()
{
var value = await client.Parameter_Zero_Return_RefType();
Received.Set();
}

[Benchmark]
public async Task Parameter_Many_Return_RefType()
public void Parameter_Many(string arg0, int arg1, bool arg2)
{
var value = await client.Parameter_Many_Return_RefType("Hello", 12345, true);
Received.Set();
}
}

class TestHubReceiver : ITestHubReceiver;

public interface ITestHub : IStreamingHub<ITestHub, ITestHubReceiver>
{
void Void_Parameter_Zero_NoReturn();
@@ -98,5 +34,6 @@ public interface ITestHub : IStreamingHub<ITestHub, ITestHubReceiver>

public interface ITestHubReceiver
{

void Parameter_Zero();
void Parameter_Many(string arg0, int arg1, bool arg2);
}
Original file line number Diff line number Diff line change
@@ -32,6 +32,11 @@ public StreamingHubMessageType ReadMessageType()
};
}

public (int MethodId, int Cosumed) ReadBroadcastMessageMethodId()
{
return (reader.ReadInt32(), (int)reader.Consumed);
}

public (int MethodId, ReadOnlyMemory<byte> Body) ReadBroadcastMessage()
{
var methodId = reader.ReadInt32();
Loading
Loading