SIMD UTF-8 upgrades, i18n test data, MVC disabled - Switch all test/benchmark data to Hungarian UTF-8 strings for i18n coverage - Add AVX-512BW, Vector256, and Vector128 SIMD paths for UTF-8/UTF-16 encode/decode (ASCII and multi-byte) in binary serializer/deserializer - Update WireMode docs for encoding guidance per workload/host - Block-comment and disable MVC formatters and Microsoft.AspNetCore.App reference due to .NET 10 Hybrid client conflict; update docs to reflect temporary state - Update appsettings: replace WaitForFlush with FlushPolicy - Revise BINARY_TODO.md for SIMD transcoder progress and next steps |
||
|---|---|---|
| .. | ||
| README.md | ||
README.md
MVC — AcBinary formatters
⚠️ TEMPORARILY DISABLED — formatter sources block-commented (
/* ... */) andMicrosoft.AspNetCore.AppFrameworkReference removed fromAyCode.Services.csproj(downstream net10.0 Hybrid client conflict onMicrosoft.AspNetCore.Mvcnamespace). Re-enable when split into a separate NuGet package / solution. Description below documents the intended state.
ASP.NET Core MVC InputFormatter / OutputFormatter pair for the AcBinary wire format. Works in controller-based MVC and Minimal API on .NET 9+. The wire payload is the raw byte[] produced by AcBinarySerializer.Serialize(value, opts) — bit-compatible with the single-shot byte[] API; no MVC-specific envelope.
Code:
AyCode.Services/Mvc/(AcBinaryInputFormatter,AcBinaryOutputFormatter,AcBinaryMvcBuilderExtensions) Binary serializer:../../../AyCode.Core/AyCode.Core/docs/BINARY/README.md
Registration
// Program.cs
builder.Services.AddControllers()
.AddAcBinaryFormatters(opts => {
opts.UseGeneratedCode = true;
});
AddAcBinaryFormatters inserts both formatters at index 0 of MvcOptions.InputFormatters / OutputFormatters — AcBinary wins content-negotiation when the client's Accept header allows.
Media Type
application/vnd.acbinary (vendor tree, registered with the IANA pattern but not yet IANA-listed). The same media type is sent on both request (Content-Type) and response.
Override via SupportedMediaTypes.Add(...) on a custom formatter instance if a project-specific type is needed.
Request flow (InputFormatter)
HttpContext.Request.Body (Stream)
→ PipeReader.Create(Body) (PipeReader)
→ drain-loop on calling thread:
while (true) {
result = await reader.ReadAsync(ct);
foreach (segment in result.Buffer) input.Feed(segment.Span);
reader.AdvanceTo(result.Buffer.End);
if (result.IsCompleted) break;
}
input.Complete();
↑ background Task.Run feeds AcBinaryDeserializer.Deserialize(input, ModelType, opts)
→ ModelType instance → InputFormatterResult.Success
The drain-loop is inline in the formatter — the serializer surface ends at AsyncPipeReaderInput. Any I/O-specific draining (PipeReader, NamedPipe, FileStream, custom transport) is the consumer's responsibility.
Response flow (OutputFormatter)
HttpContext.Response.Body (Stream)
→ PipeWriter.Create(Body) (PipeWriter)
→ AcBinarySerializer.SerializeChunked(value, ObjectType, writer, opts)
(raw mode — pure AcBinary bytes, no [201][UINT16] framing)
→ await pipeWriter.CompleteAsync()
SerializeChunked (not SerializeChunkedFramed) — the wire is a single self-contained AcBinary blob, identical to Serialize(value, opts) → byte[]. No multiplexed framing on the HTTP body.
Error model
Deserialization failure → ModelState.TryAddModelError(ModelName, ex.Message) → InputFormatterResult.Failure(). ASP.NET pipeline emits 400 Bad Request with application/problem+json (RFC 7807) — not an AcBinary-encoded error. The client reads the error body as JSON.
OperationCanceledException (when RequestAborted is signalled) is rethrown so the pipeline aborts the response cleanly.
Cancellation
HttpContext.RequestAborted flows into both formatters. The InputFormatter passes it to PipeReader.ReadAsync and Task.Run; the OutputFormatter calls cancellationToken.ThrowIfCancellationRequested() after CompleteAsync. Mid-request abort releases all pooled resources via the using and finally blocks.
What the formatter does NOT include
- No Stream-async API in the binary core —
AcBinarySerializerhas noSerializeAsync(Stream, T)method. The formatter is the wrapper. (SeeBINARY_TODO.md#accore-bin-t-t8k3— parked.) - No options thread-safety guard —
AcBinarySerializerOptionsis currently mutable; if registered as a DI singleton withConfigure<>it is fine becauseConfigureis read-only at runtime, but raw-shared mutable instances across concurrent requests are unsafe. (SeeBINARY_ISSUES.md#accore-bin-i-l8n5andBINARY_TODO.md#accore-bin-t-b7h4.) - No OpenAPI metadata helpers —
Microsoft.AspNetCore.OpenApi/Swashbuckle.AspNetCorepick upSupportedMediaTypesautomatically; no extra integration needed.
Future work
The formatter currently lives in AyCode.Services (alongside the SignalR transport). The intent is to extract it into its own NuGet package — AyCode.AspNetCore.Mvc.Formatters.AcBinary — when the binary serializer is moved to a dedicated solution. No code change required at extraction time; only project-file split.