Conversation
This was referenced Jan 6, 2018
Collaborator
|
great work 👍 |
Owner
Author
|
Initial tests on my Ubuntu 17 workstation are looking promising.
During this run cpu topped out at ~ 50% cpu utilization. So there should still be some improvements that can be done. |
… of tests failing. Single thread perf ~120k, Taskpool ~170k ??? why is the multithread performace so bad?.
|
Any progress or time frame on this issue? I'm building a .Net Core app (/service) and need to support clean JSON RPC (no headers), and would like to use a library and not roll my own. |
Owner
Author
Nothing recently. I could use a little help reviewing the code, and feedback on if it's ready a beta release. |
Owner
Author
Astn
added a commit
that referenced
this pull request
Sep 23, 2026
…he .NET Standard upgrade from #90) Finishes the .NET Standard upgrade from #90 (issue #89) on top of master and carries it through to a 2.0 release: a serializer-neutral, byte-first core with three serializer packages and a Kestrel host. Targets and packaging: core, Newtonsoft and SystemTextJson packages target netstandard2.0, netstandard2.1, net8.0 and net10.0; AspNetCore targets net8.0 and net10.0; netcoreapp3.1 dropped; SDK pinned by global.json. CI builds the solution, runs the tests on both frameworks and packs all four packages (2.0.0). Core: byte-first pipeline (JsonRpcProcessor.Process over ReadOnlySequence/Memory/Span<byte> into an IBufferWriter<byte>; the string overloads transcode into it). Pluggable JsonRpcSerializer: the built-in dependency-free serializer, AustinHarris.JsonRpc.Newtonsoft and AustinHarris.JsonRpc.SystemTextJson, resolved per call, per session, then global, with one wire format fixed by the core. Parser hardening (depth limit, strict grammar, UTF-8 validation, escaped member names, stable id echo) and dispatch hardening from an independent review (notifications never answered, batches always arrays, pre-hook re-dispatch, per-invocation context, hook error boundary, named-parameter validation, async return types rejected, exception details redacted by default). Config.VersionPolicy for the jsonrpc member. Hosting: AustinHarris.JsonRpc.AspNetCore with MapJsonRpc on PipeReader/BodyWriter and JsonRpcConnectionHandler for raw TCP, Unix-socket and named-pipe connections; samples/WasmHost runs the server inside the browser and benchmarks JSON-RPC against plain Blazor interop, interpreted and AOT. Benchmarks: TestServer_Console gains sync, Task, Kestrel, compare (StreamJsonRpc and gRPC for .NET on the same Kestrel) and sweep (every library and transport by connection count) modes. Charts are rendered in light and dark from benchmarks/charts/benchmarks.json, the one data file behind the README tables, the SVGs and the interactive explorer page (deployed to GitHub Pages); render.py --check keeps them in agreement in CI. simdjson evaluated and rejected. Docs: README rewritten (setup, hosting modes, configuration, benchmarks, upgrading from 1.x), docs/serializers.md, the reviews and their fix passes in docs/reviews/. Closes #89. Supersedes #90.
Astn
added a commit
that referenced
this pull request
Sep 23, 2026
…he .NET Standard upgrade from #90) Finishes the .NET Standard upgrade from #90 (issue #89) on top of master and carries it through to a 2.0 release: a serializer-neutral, byte-first core with three serializer packages and a Kestrel host. Targets and packaging: core, Newtonsoft and SystemTextJson packages target netstandard2.0, netstandard2.1, net8.0 and net10.0; AspNetCore targets net8.0 and net10.0; netcoreapp3.1 dropped; SDK pinned by global.json. CI builds the solution, runs the tests on both frameworks and packs all four packages (2.0.0). Core: byte-first pipeline (JsonRpcProcessor.Process over ReadOnlySequence/Memory/Span<byte> into an IBufferWriter<byte>; the string overloads transcode into it). Pluggable JsonRpcSerializer: the built-in dependency-free serializer, AustinHarris.JsonRpc.Newtonsoft and AustinHarris.JsonRpc.SystemTextJson, resolved per call, per session, then global, with one wire format fixed by the core. Parser hardening (depth limit, strict grammar, UTF-8 validation, escaped member names, stable id echo) and dispatch hardening from an independent review (notifications never answered, batches always arrays, pre-hook re-dispatch, per-invocation context, hook error boundary, named-parameter validation, async return types rejected, exception details redacted by default). Config.VersionPolicy for the jsonrpc member. Hosting: AustinHarris.JsonRpc.AspNetCore with MapJsonRpc on PipeReader/BodyWriter and JsonRpcConnectionHandler for raw TCP, Unix-socket and named-pipe connections; samples/WasmHost runs the server inside the browser and benchmarks JSON-RPC against plain Blazor interop, interpreted and AOT. Benchmarks: TestServer_Console gains sync, Task, Kestrel, compare (StreamJsonRpc and gRPC for .NET on the same Kestrel) and sweep (every library and transport by connection count) modes. Charts are rendered in light and dark from benchmarks/charts/benchmarks.json, the one data file behind the README tables, the SVGs and the interactive explorer page (deployed to GitHub Pages); render.py --check keeps them in agreement in CI. simdjson evaluated and rejected. Docs: README rewritten (setup, hosting modes, configuration, benchmarks, upgrading from 1.x), docs/serializers.md, the reviews and their fix passes in docs/reviews/. Closes #89. Supersedes #90.
Astn
added a commit
that referenced
this pull request
Sep 23, 2026
…he .NET Standard upgrade from #90) Finishes the .NET Standard upgrade from #90 (issue #89) on top of master and carries it through to a 2.0 release: a serializer-neutral, byte-first core with three serializer packages and a Kestrel host. Targets and packaging: core, Newtonsoft and SystemTextJson packages target netstandard2.0, netstandard2.1, net8.0 and net10.0; AspNetCore targets net8.0 and net10.0; netcoreapp3.1 dropped; SDK pinned by global.json. CI builds the solution, runs the tests on both frameworks and packs all four packages (2.0.0). Core: byte-first pipeline (JsonRpcProcessor.Process over ReadOnlySequence/Memory/Span<byte> into an IBufferWriter<byte>; the string overloads transcode into it). Pluggable JsonRpcSerializer: the built-in dependency-free serializer, AustinHarris.JsonRpc.Newtonsoft and AustinHarris.JsonRpc.SystemTextJson, resolved per call, per session, then global, with one wire format fixed by the core. Parser hardening (depth limit, strict grammar, UTF-8 validation, escaped member names, stable id echo) and dispatch hardening from an independent review (notifications never answered, batches always arrays, pre-hook re-dispatch, per-invocation context, hook error boundary, named-parameter validation, async return types rejected, exception details redacted by default). Config.VersionPolicy for the jsonrpc member. Open issues folded in: the request id is readable inside a method (Handler.RpcRequestId / JsonRpcContext.CurrentRequestId, RpcRequestIdKind, RpcRequestIdRaw) from the invocation frame on demand, at no cost to methods that do not ask (#56); a parameter value the serializer cannot convert is -32602 with structured data naming the parameter instead of -32603 (#123); -32601 names the requested method in its data and reaches the error handler on both paths (#145); async void methods are rejected at registration and the synchronous contract is documented with the job-ticket pattern (#147); ServiceBinder.BindMethod registers any delegate without attributes (#6). Hosting: AustinHarris.JsonRpc.AspNetCore with MapJsonRpc on PipeReader/BodyWriter and JsonRpcConnectionHandler for raw TCP, Unix-socket and named-pipe connections; samples/WasmHost runs the server inside the browser and benchmarks JSON-RPC against plain Blazor interop, interpreted and AOT. Benchmarks: TestServer_Console gains sync, Task, Kestrel, compare (StreamJsonRpc and gRPC for .NET on the same Kestrel) and sweep (every library and transport by connection count) modes. Charts are rendered in light and dark from benchmarks/charts/benchmarks.json, the one data file behind the README tables, the SVGs and the interactive explorer page (deployed to GitHub Pages); render.py --check keeps them in agreement in CI. simdjson evaluated and rejected. Docs: README rewritten (setup, hosting modes, configuration, benchmarks, upgrading from 1.x), docs/serializers.md, the reviews and their fix passes in docs/reviews/. Closes #89. Supersedes #90. Closes #56, #123, #145, #147, #6. Closes #117, #68, #140, #131, #125, #10, #9 (already covered by the 2.0 core; verified against this branch).
Astn
added a commit
that referenced
this pull request
Sep 24, 2026
…he .NET Standard upgrade from #90) Finishes the .NET Standard upgrade from #90 (issue #89) on top of master and carries it through to a 2.0 release: a serializer-neutral, byte-first core with three serializer packages and a Kestrel host. Targets and packaging: core, Newtonsoft and SystemTextJson packages target netstandard2.0, netstandard2.1, net8.0 and net10.0; AspNetCore targets net8.0 and net10.0; netcoreapp3.1 dropped; SDK pinned by global.json. CI builds the solution, runs the tests on both frameworks and packs all four packages (2.0.0). Core: byte-first pipeline (JsonRpcProcessor.Process over ReadOnlySequence/Memory/Span<byte> into an IBufferWriter<byte>; the string overloads transcode into it). Pluggable JsonRpcSerializer: the built-in dependency-free serializer, AustinHarris.JsonRpc.Newtonsoft and AustinHarris.JsonRpc.SystemTextJson, resolved per call, per session, then global, with one wire format fixed by the core. Parser hardening (depth limit, strict grammar, UTF-8 validation, escaped member names, stable id echo) and dispatch hardening from an independent review (notifications never answered, batches always arrays, pre-hook re-dispatch, per-invocation context, hook error boundary, named-parameter validation, async void rejected, exception details redacted by default). Config.VersionPolicy for the jsonrpc member. Open issues folded in: the request id is readable inside a method (Handler.RpcRequestId / JsonRpcContext.CurrentRequestId, RpcRequestIdKind, RpcRequestIdRaw) from the invocation frame on demand, at no cost to methods that do not ask (#56); a parameter value the serializer cannot convert is -32602 with structured data naming the parameter instead of -32603 (#123); -32601 names the requested method in its data and reaches the error handler on both paths (#145); ServiceBinder.BindMethod registers any delegate without attributes (#6). Asynchronous invocation (#147): JsonRpcProcessor.ProcessAsync (byte and string overloads) awaits Task, Task<T>, ValueTask and ValueTask<T> methods with typed result writing, sequential ordered batches and cooperative cancellation ([JsonRpcCancellation] receives the processor token). Completed operations run inline and the byte overloads return Task.CompletedTask when the document completes inline. The synchronous Process path is unchanged; it refuses an asynchronous registration with -32603 without invoking it, and async void stays rejected at registration. RpcContextFlow.Flow (default) carries the ambient context, the request id and RpcSetException across awaits; RpcContextFlow.None opts a method out for zero allocation on the completed path. Kestrel gets JsonRpcOptions.EnableAsyncMethods for HTTP and ordered raw connections. Interface binding (#130): ServiceBinder.BindInterface<TInterface>(sessionId, implementation, options) registers an interface contract, including a tree of interface-typed properties, atomically and returns an RpcBinding that unbinds it on Dispose. Names come from the contract ([JsonRpcMethod] aliases, [JsonRpcParam], optional defaults) with Prefix, Separator, camel casing, an Include filter and a NameRule override; implementation-only methods stay private. The tree is flattened and compiled at registration through GetInterfaceMap with the receiver typed as the implementation, so interface-bound methods dispatch at the same cost as class-bound ones. Task and ValueTask members are asynchronous registrations. Hosting: AustinHarris.JsonRpc.AspNetCore with MapJsonRpc on PipeReader/BodyWriter and JsonRpcConnectionHandler for raw TCP, Unix-socket and named-pipe connections; samples/WasmHost runs the server inside the browser and benchmarks JSON-RPC against plain Blazor interop, interpreted and AOT. Benchmarks: TestServer_Console gains sync, Task, Kestrel, compare (StreamJsonRpc and gRPC for .NET on the same Kestrel) and sweep (every library and transport by connection count) modes. Charts are rendered in light and dark from benchmarks/charts/benchmarks.json, the one data file behind the README tables, the SVGs and the interactive explorer page (deployed to GitHub Pages); render.py --check keeps them in agreement in CI. simdjson evaluated and rejected. benchmarks/Micro holds BenchmarkDotNet per-request timings with allocation columns for class-bound, interface-bound and asynchronous dispatch. Docs: README rewritten (setup, hosting modes, configuration, benchmarks, upgrading from 1.x), docs/serializers.md, the reviews and their fix passes in docs/reviews/. Closes #89. Supersedes #90. Closes #56, #123, #145, #147, #130, #6. Closes #117, #68, #140, #131, #125, #10, #9 (already covered by the 2.0 core; verified against this branch).
Astn
added a commit
that referenced
this pull request
Sep 24, 2026
…he .NET Standard upgrade from #90) Finishes the .NET Standard upgrade from #90 (issue #89) on top of master and carries it through to a 2.0 release: a serializer-neutral, byte-first core with three serializer packages and a Kestrel host. Targets and packaging: core, Newtonsoft and SystemTextJson packages target netstandard2.0, netstandard2.1, net8.0 and net10.0; AspNetCore targets net8.0 and net10.0; netcoreapp3.1 dropped; SDK pinned by global.json. CI builds the solution, runs the tests on both frameworks and packs all four packages (2.0.0). Core: byte-first pipeline (JsonRpcProcessor.Process over ReadOnlySequence/Memory/Span<byte> into an IBufferWriter<byte>; the string overloads transcode into it). Pluggable JsonRpcSerializer: the built-in dependency-free serializer, AustinHarris.JsonRpc.Newtonsoft and AustinHarris.JsonRpc.SystemTextJson, resolved per call, per session, then global, with one wire format fixed by the core. Parser hardening (depth limit, strict grammar, UTF-8 validation, escaped member names, stable id echo) and dispatch hardening from an independent review (notifications never answered, batches always arrays, pre-hook re-dispatch, per-invocation context, hook error boundary, named-parameter validation, async void rejected, exception details redacted by default). Config.VersionPolicy for the jsonrpc member. Open issues folded in: the request id is readable inside a method (Handler.RpcRequestId / JsonRpcContext.CurrentRequestId, RpcRequestIdKind, RpcRequestIdRaw) from the invocation frame on demand, at no cost to methods that do not ask (#56); a parameter value the serializer cannot convert is -32602 with structured data naming the parameter instead of -32603 (#123); -32601 names the requested method in its data and reaches the error handler on both paths (#145); ServiceBinder.BindMethod registers any delegate without attributes (#6). Asynchronous invocation (#147): JsonRpcProcessor.ProcessAsync (byte and string overloads) awaits Task, Task<T>, ValueTask and ValueTask<T> methods with typed result writing, sequential ordered batches and cooperative cancellation ([JsonRpcCancellation] receives the processor token). Completed operations run inline and the byte overloads return Task.CompletedTask when the document completes inline. The synchronous Process path is unchanged; it refuses an asynchronous registration with -32603 without invoking it, and async void stays rejected at registration. RpcContextFlow.None (default) keeps the ambient context for the synchronous part of the method and costs nothing extra on the completed path; RpcContextFlow.Flow opts a method in to the context, the request id and RpcSetException across awaits, at a per-invocation allocation. Kestrel gets JsonRpcOptions.EnableAsyncMethods for HTTP and ordered raw connections. Interface binding (#130): ServiceBinder.BindInterface<TInterface>(sessionId, implementation, options) registers an interface contract, including a tree of interface-typed properties, atomically and returns an RpcBinding that unbinds it on Dispose. Names come from the contract ([JsonRpcMethod] aliases, [JsonRpcParam], optional defaults) with Prefix, Separator, camel casing, an Include filter and a NameRule override; implementation-only methods stay private. The tree is flattened and compiled at registration through GetInterfaceMap with the receiver typed as the implementation, so interface-bound methods dispatch at the same cost as class-bound ones. Task and ValueTask members are asynchronous registrations. Hosting: AustinHarris.JsonRpc.AspNetCore with MapJsonRpc on PipeReader/BodyWriter and JsonRpcConnectionHandler for raw TCP, Unix-socket and named-pipe connections; samples/WasmHost runs the server inside the browser and benchmarks JSON-RPC against plain Blazor interop, interpreted and AOT. Benchmarks: TestServer_Console gains sync, Task, Kestrel, compare (StreamJsonRpc and gRPC for .NET on the same Kestrel) and sweep (every library and transport by connection count) modes. Charts are rendered in light and dark from benchmarks/charts/benchmarks.json, the one data file behind the README tables, the SVGs and the interactive explorer page (deployed to GitHub Pages); render.py --check keeps them in agreement in CI. simdjson evaluated and rejected. benchmarks/Micro holds BenchmarkDotNet per-request timings with allocation columns for class-bound, interface-bound and asynchronous dispatch. Docs: README rewritten (setup, hosting modes, configuration, benchmarks, upgrading from 1.x), docs/serializers.md, the reviews and their fix passes in docs/reviews/. Closes #89. Supersedes #90. Closes #56, #123, #145, #147, #130, #6. Closes #117, #68, #140, #131, #125, #10, #9 (already covered by the 2.0 core; verified against this branch).
Astn
added a commit
that referenced
this pull request
Sep 24, 2026
2.0: byte-first core, pluggable serializers, Kestrel host (finishes the .NET Standard upgrade from #90)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is for issue #89
Todo
Feel free to provide a pull request into this branch for any of the below.