Skip to content

Commit 77fb269

Browse files
committed
API vocabulary: MethodInfo spelled out, sessionId everywhere, legacy registration obsolete
"method" is the JSON-RPC callable named on the wire and a MethodInfo is always spelled MethodInfo: RpcMethod.FromMethod is FromMethodInfo and RpcInterfaceMethod.Method is MethodInfo. The session parameter is spelled sessionId on every overload; BindService, Handler.RegisterInstance and the JsonRpcService(string) constructor used sessionID. Handler gets a class summary and SessionSelector's summary says the selection is independent of ASP.NET Core session state. Handler.RegisterFuction and UnRegisterFunction keep their names and behaviour and are obsolete; the message says that BindMethod throws on a duplicate name where RegisterFuction replaces it. Tests that exercise the legacy pair suppress CS0618 locally. The README defines "method" at the top of Defining methods and "session" at the top of Sessions and context; the package README gets the method sentence; CHANGELOG and the upgrade guide record the renames.
1 parent e581235 commit 77fb269

18 files changed

Lines changed: 85 additions & 54 deletions

‎AustinHarris.JsonRpc.AspNetCore/JsonRpcOptions.cs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ public class JsonRpcOptions
1616
public string SessionId { get; set; }
1717

1818
/// <summary>
19-
/// Picks the session per HTTP request (for example from a route value or a header). When set it takes
20-
/// precedence over <see cref="SessionId"/>. Not used by the raw connection handler.
19+
/// Selects the JSON-RPC session id for this HTTP request, for example from a route value or a header;
20+
/// selection is independent of ASP.NET Core session state unless the callback explicitly uses it.
21+
/// When set it takes precedence over <see cref="SessionId"/>. Not used by the raw connection handler.
2122
/// </summary>
2223
public Func<HttpContext, string> SessionSelector { get; set; }
2324

‎AustinHarris.JsonRpcTestN/AsyncInvocationTests.cs‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ public async Task CompatibilityRegistrationSurfaces_SupportAsyncMethods(int surf
140140
var method = new Func<Task<int>>(() => Task.FromResult(7));
141141
var handler = Handler.GetSessionHandler(_session);
142142
if (surface == 0) handler.MetaData.Services["run"] = new SMDService("POST", "JSON-RPC-2.0", types, new Dictionary<string, object>(), method);
143+
#pragma warning disable CS0618
143144
else if (surface == 1) handler.RegisterFuction("run", types, null, method);
145+
#pragma warning restore CS0618
144146
else _ = new AutoAsyncService(_session);
145147
Assert.AreEqual(7, (int)JObject.Parse(await Run(Request("run")))["result"]);
146148
Assert.AreEqual(typeof(int), handler.MetaData.Services["run"].Method.ResultType);
@@ -172,13 +174,15 @@ public void AsyncVoid_IsRejectedOnEverySurface(int surface)
172174
var types = new Dictionary<string, Type> { ["returns"] = typeof(void) };
173175
TestDelegate registration = surface switch
174176
{
175-
0 => () => RpcMethod.FromMethod("invalid", typeof(InvalidService).GetMethod("Invalid"), new InvalidService()),
177+
0 => () => RpcMethod.FromMethodInfo("invalid", typeof(InvalidService).GetMethod("Invalid"), new InvalidService()),
176178
1 => () => RpcMethod.FromDelegate("invalid", invalid),
177179
2 => () => ServiceBinder.BindService(_session, new InvalidService()),
178180
3 => () => Bind("invalid", invalid),
179181
4 => () => new InvalidAutoService(_session),
180182
5 => () => new SMDService("POST", "JSON-RPC-2.0", types, new Dictionary<string, object>(), invalid),
183+
#pragma warning disable CS0618
181184
_ => () => Handler.GetSessionHandler(_session).RegisterFuction("invalid", types, null, invalid)
185+
#pragma warning restore CS0618
182186
};
183187
StringAssert.Contains("async void", Assert.Throws<NotSupportedException>(registration).Message);
184188
}

‎AustinHarris.JsonRpcTestN/DelegateBindingTests.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ public void Names_MustBeFree_AndUnbindFreesThem()
128128
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"result\":2,\"id\":1}", Run("{\"method\":\"m\",\"id\":1}"));
129129

130130
// the legacy surface keeps replacing silently
131+
#pragma warning disable CS0618
131132
Handler.GetSessionHandler(Session).RegisterFuction("m", new Dictionary<string, Type> { ["returns"] = typeof(int) }, null, new Func<int>(() => 3));
133+
#pragma warning restore CS0618
132134
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"result\":3,\"id\":1}", Run("{\"method\":\"m\",\"id\":1}"));
133135
}
134136

‎AustinHarris.JsonRpcTestN/DiLifetimeTests.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ public void Arguments_AreChecked()
640640
Assert.Throws<ArgumentNullException>(() => ServiceBinder.BindService(_session, (object)null));
641641
Assert.Throws<ArgumentException>(() => ServiceBinder.BindService(_session, typeof(List<>), c => null));
642642
var method = typeof(TaggedService).GetMethod(nameof(TaggedService.Tag));
643-
var ex = Assert.Throws<ArgumentException>(() => AustinHarris.JsonRpc.Invocation.RpcMethod.FromMethod("fb.tag", method, typeof(string), c => null));
643+
var ex = Assert.Throws<ArgumentException>(() => AustinHarris.JsonRpc.Invocation.RpcMethod.FromMethodInfo("fb.tag", method, typeof(string), c => null));
644644
StringAssert.Contains(typeof(TaggedService).FullName, ex.Message);
645645
}
646646
}

‎AustinHarris.JsonRpcTestN/DispatchHardeningTests.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ public void BindServices()
154154
public void DestroySessions()
155155
{
156156
Handler.DestroySession(Session);
157+
#pragma warning disable CS0618
157158
Handler.DefaultHandler.UnRegisterFunction("dh.whichSession");
159+
#pragma warning restore CS0618
158160
}
159161

160162
private static string Run(string json, object context = null, JsonRpcSerializer serializer = null, string session = Session)

‎AustinHarris.JsonRpcTestN/InterfaceBindingTests.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public void Include_ReadsHostAttributeForEveryAlias()
261261
var seen = new List<RpcInterfaceMethod>();
262262
using var binding = ServiceBinder.BindInterface<IAliases>(Session, new Aliases(), new RpcInterfaceBindingOptions
263263
{
264-
Include = method => { seen.Add(method); return method.Method.IsDefined(typeof(ExportAttribute), false); }
264+
Include = method => { seen.Add(method); return method.MethodInfo.IsDefined(typeof(ExportAttribute), false); }
265265
});
266266
Assert.AreEqual(3, seen.Count);
267267
CollectionAssert.AreEquivalent(new[] { "ALIAS", "OtherAlias" }, binding.Methods);

‎AustinHarris.JsonRpcTestN/NewtonsoftTests.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ public void Settings_PerSession_OverridesGlobal()
9393
try
9494
{
9595
var h = Handler.GetSessionHandler(sessionId);
96+
#pragma warning disable CS0618
9697
h.RegisterFuction("echo", new System.Collections.Generic.Dictionary<string, Type> { { "s", typeof(string) }, { "returns", typeof(string) } }, null, new Func<string, string>(s => s));
98+
#pragma warning restore CS0618
9799
h.Serializer = new NewtonsoftJsonRpcSerializer(new JsonSerializerSettings { Converters = { new ShoutingStringConverter() } });
98100
// four arguments on purpose: ProcessSync(sessionId, json, null) binds to the (jsonRpc, context, serializer) overload
99101
var result = JsonRpcProcessor.ProcessSync(sessionId, "{\"method\":\"echo\",\"params\":[\"abc\"],\"id\":1}", null, null);

‎AustinHarris.JsonRpcTestN/SessionAndConfigTests.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,10 @@ public void JsonRpcService_AutoBindFalse_BindsNowhere_UntilBoundExplicitly()
250250
}
251251
finally
252252
{
253+
#pragma warning disable CS0618
253254
Handler.DefaultHandler.UnRegisterFunction("sc.bound");
254255
Handler.GetSessionHandler(Session).UnRegisterFunction("sc.unbound");
256+
#pragma warning restore CS0618
255257
}
256258
}
257259
}

‎AustinHarris.JsonRpcTestN/Test.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ public void TestCanCreateAndRemoveSession()
9595
Tuple.Create ("sooper", typeof(string)),
9696
Tuple.Create ("returns", typeof(string))
9797
}.ToDictionary(x => x.Item1, x => x.Item2);
98+
#pragma warning disable CS0618
9899
h.RegisterFuction("workie", metadata, new System.Collections.Generic.Dictionary<string, object>(),new Func<string, string>(x => "workie ... " + x));
100+
#pragma warning restore CS0618
99101

100102
string request = @"{""method"":""workie"",""params"":{""sooper"":""good""},""id"":1}";
101103
string expectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"workie ... good\",\"id\":1}";
@@ -1612,7 +1614,9 @@ public void TestPreProcessOnSession()
16121614
Tuple.Create ("sooper", typeof(string)),
16131615
Tuple.Create ("returns", typeof(string))
16141616
}.ToDictionary(x => x.Item1, x => x.Item2);
1617+
#pragma warning disable CS0618
16151618
h.RegisterFuction("workie", metadata, new System.Collections.Generic.Dictionary<string, object>(),new Func<string, string>(x => "workie ... " + x));
1619+
#pragma warning restore CS0618
16161620

16171621
string request = @"{""method"":""workie"",""params"":{""sooper"":""good""},""id"":1}";
16181622
string expectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"workie ... good\",\"id\":1}";
@@ -1852,7 +1856,9 @@ public void TestPostProcessOnSession()
18521856
Tuple.Create ("sooper", typeof(string)),
18531857
Tuple.Create ("returns", typeof(string))
18541858
}.ToDictionary(x => x.Item1, x => x.Item2);
1859+
#pragma warning disable CS0618
18551860
h.RegisterFuction("workie", metadata, new System.Collections.Generic.Dictionary<string, object>(), new Func<string, string>(x => "workie ... " + x));
1861+
#pragma warning restore CS0618
18561862

18571863
string request = @"{""method"":""workie"",""params"":{""sooper"":""good""},""id"":1}";
18581864
string expectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"workie ... good\",\"id\":1}";

‎CHANGELOG.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ behaviour: a breaking change to either means a new major version.
2929

3030
### Changed
3131

32+
- `RpcMethod.FromMethod` is `RpcMethod.FromMethodInfo`; `RpcInterfaceMethod.Method` is `RpcInterfaceMethod.MethodInfo`. A `MethodInfo` is always spelled out; "method" means the JSON-RPC method.
33+
- The session parameter is spelled `sessionId` on every overload (`BindService`, `Handler.RegisterInstance` and the `JsonRpcService` constructor used `sessionID`).
34+
- `Handler.RegisterFuction` and `UnRegisterFunction` are obsolete; use `ServiceBinder.BindMethod` and `UnbindMethod` (which throw on a duplicate name instead of replacing it).
3235
- The core no longer depends on Json.NET.
3336
- `ProcessAsync` no longer serializes the process on one lock per document. Each thread now caches one async scratch (input copy, reader, staged output) in front of the shared pool, which handles only misses and overflow. At 16 workers, the inline rows went from about 4 M to 22.2 M to 32.1 M RPC/s across the registrations, and the row with a real suspension from 3.9 M to 8.96 M (one run per row, 2026-09-25). The library retains one scratch per thread that has run `ProcessAsync` plus 64 shared, with buffers at most 64 KiB each.
3437
- The request path looks sessions up without creating them. A request for a session id that was never registered answers `-32601` for every call and leaves the registry untouched; sessions are created by binding and by the per-session `Config` setters. Registration adds the session before publishing the registry version, so a thread that misses its snapshot consults the master registry and cannot answer `-32601` for a session that exists.

0 commit comments

Comments
 (0)