Repository navigation
Native AOT: the async daemon, cursor paging and the remaining reflection-serializing paths (#412) - #421
Merged
Conversation
…ion-serializing paths (#412) smoke/aot-consumer now runs, in the native image, the async daemon over an async Snapshot<T> and a multi-stream projection, a keyset cursor walk, Include() by a strong-typed id, full-text relevance ordering, a DateOnly comparison, and both projection step-through methods. - The async daemon needed no Fisher change: it ran natively as soon as it was measured. - CursorPagination writes the cursor with a fixed-shape Utf8JsonWriter and reads it with JsonDocument. The v1: payload is byte-identical to the old JsonSerializer output, pinned by cursor_encoding against a string captured from the old implementation over every key type. A strong-typed identity is now carried as its inner value; the old {"Value":...} shape could never be decoded, so the second page of any walk over a wrapper-keyed document failed. - IncludePlan builds a statically closed Enumerable.Contains<object> instead of closing Contains and Array.CreateInstance over the member's runtime type. That threw natively over a strong-typed id ("TicketId[] is missing native code"). - OrderByRelevance and its siblings, and Include's marker, take their closed MethodInfo from a delegate rather than MakeGenericMethod by name. - DateMember renders through options.GetTypeInfo(type). - Projection step-through renders state through the store's serializer, where RunProjectionByNameAsync used JsonSerializer's default options (PascalCase, and reflection a native image disables). It no longer reads step properties by reflection. Its MakeGenericMethod moved into a non-generic helper, because the old spelling crashed ILC 10.0.1 with IndexOutOfRangeException once either step-through method was reachable. Item 1 of #412, strong-typed aggregate identities, stays blocked on jasperfx#942, and its refusal is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jeremydmiller
force-pushed
the
fisher-412-aot-remaining-paths
branch
from
October 4, 2026 18:33
ea44826 to
28ef953
Compare
jeremydmiller
marked this pull request as ready for review
October 4, 2026 18:33
This was referenced Oct 4, 2026
Merged
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.
Part of #412 — items 2 and 3. Item 1 (strong-typed aggregate identities) stays blocked on jasperfx#942, so this does not close the issue.
What changed
Item 2, the async daemon: no Fisher change was needed.
smoke/aot-consumernow runs an asyncSnapshot<Ledger>and aMultiStreamProjection<PortVisits, string>underBuildProjectionDaemonAsync/StartAllAsync/WaitForNonStaleData, natively, and asserts both documents. (The hostedAddAsyncDaemon()path isn't exercised; the smoke has no host.)Item 3, the reflection-serializing paths:
CursorPagination: fixed-shapeUtf8JsonWriterto encode,JsonDocumentto decode. Thev1:payload is byte-identical to the oldJsonSerializeroutput;cursor_encodingpins a string captured from the old implementation over every key type. Any other key type is now refused by name.{"Value":…}and couldn't be decoded. It's now carried as its inner value (paged_queries.a_cursor_walk_over_a_strong_typed_identity, which failed before the fix).IncludePlan: a statically closedEnumerable.Contains<object>. The oldArray.CreateInstancethrew natively over a strong-typed id ("TicketId[]is missing native code").FullTextSearchExtensionsand Include's marker: the closedMethodInfocomes from a delegate, notMakeGenericMethodby name.DateMember: serializes throughoptions.GetTypeInfo(type).IndexOutOfRangeExceptioninMakeGenericMethodSite) once step-through was reachable.RunProjectionByNameAsyncused to render state withJsonSerializer's defaults (PascalCase). It now renders through the store's serializer, which is camelCase by default.Verification (macOS arm64, ILC 10.0.1)
OK:and exits 0.TicketId[]missing native code). The old step-through doesn't produce a binary at all. The FullTextSearch and DateMember changes only remove analyzer warnings; the smoke passes either way, and CLAUDE.md says so.check_scoreboard.pyagrees for both TFMs; leak check clean.🤖 Generated with Claude Code