F# codegen: Marten document slice — runnable sample + compile-gate (GH-2969)#2984
Merged
Merged
Conversation
…-2969) Second store-specific slice of the F# code-generation audit: a runnable F# Wolverine + Marten document app and a compile-gate proving its handler chain emits valid F# through Wolverine's static codegen path. Marten document frame F# emit (both in Wolverine.Marten/Codegen): - OpenMartenSessionFrame -> `use session = factory.OpenSession(context)` (`await using var` becomes F# `use`; the task { } CE disposes the IAsyncDisposable session at block end). Covers the no-context / tenant-id branches too. - CreateDocumentSessionFrame -> the create-session + eager-idempotency branches (`use session = …`, `do! context.AssertEagerIdempotencyAsync(ct)`). SaveChangesAsync + the outbox flush are MethodCall/already-F# frames. Runnable sample (src/Samples/WolverineMartenFSharpSample): - F# Product/CreateProductCommand/ProductCreated + a [<Transactional>] CreateProductHandler storing through an injected IDocumentSession. - Marten as both the document store and (via IntegrateWithWolverine) the durable message store; Postgres-backed (the *static* F# story is the compile-gate's job). Runs via dynamic codegen (Wolverine.RuntimeCompilation + UseRuntimeCompilation, GH-2876). Verified end-to-end: "Created a Product through the F# Wolverine + Marten handler." Compile-gate (src/Testing/Wolverine.Marten.FSharp{Tests,Fixture}): - Renders the sample's real CreateProductCommand chain to F# via the no-host HandlerGraph/AssembleTypes/GenerateFSharpCode path and dotnet-builds the fixture. Wire-up: sample + gate added to wolverine_fsharp.slnx; fsharp.yml runs the Marten gate as its own sequential step. No JasperFx release needed (both frames are Wolverine-side). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced May 29, 2026
Merged
This was referenced Jun 1, 2026
Merged
This was referenced Jun 4, 2026
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 the F# code-generation audit (#2969), following the EF Core slice (#2983). This is the second store-specific slice: Marten document persistence, with its own runnable F# sample + compile-gate.
Marten document frame F# emit
Both in
Wolverine.Marten/Codegen— and no JasperFx release needed this time (both are Wolverine-side):OpenMartenSessionFrame→use session = factory.OpenSession(context). C#await using varbecomes F#use— inside thetask { }CE that disposes theIAsyncDisposablesession at block end. Covers the no-context (native Marten) and tenant-id branches too.CreateDocumentSessionFrame→ the create-session + eager-idempotency branches (use session = …,do! context.AssertEagerIdempotencyAsync(ct)).SaveChangesAsyncand the outbox flush areMethodCall/already-F# frames.Generated F# (from the gate):
Runnable sample —
src/Samples/WolverineMartenFSharpSampleF#
Product/CreateProductCommand/ProductCreated+ a[<Transactional>]CreateProductHandlerstoring through an injectedIDocumentSession. Marten is both the document store and (viaIntegrateWithWolverine) the durable message store backing the transactional outbox. Postgres-backed — not infra-free (the static F# story is the compile-gate's job). Runs via dynamic codegen (Wolverine.RuntimeCompilation+opts.UseRuntimeCompilation(), #2876). Verified end-to-end: printsCreated a Product through the F# Wolverine + Marten handler.Compile-gate —
src/Testing/Wolverine.Marten.FSharp{Tests,Fixture}Renders the sample's real
CreateProductCommandchain to F# via the no-hostHandlerGraph→AssembleTypes→GenerateFSharpCodepath, thendotnet builds the checked-in fixture (FS0193/lock retry). Mirrors the Core/Http/EfCore gates.Wire-up
wolverine_fsharp.slnx.fsharp.ymlruns the Marten document gate as its own sequential step.Verification
dotnet build wolverine.slnx -c Releaseclean (per CLAUDE.md the slim build isn't sufficient).Next slice: the Marten event-sourced aggregate (
MartenOps.StartStream,[Aggregate]loading) — the heaviest frame set.🤖 Generated with Claude Code