Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions openspec/IMPLEMENTATION_ORDER.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,31 @@ Captured on `dev` branch (commit 467cbb510), .NET 10.0, Release, ServerGC, Linux

---

### Milestone 2: `serializer-v2` (Spec 4)
### Milestone 2: `serializer-v2` (Spec 4) — foundation only

**Branch**: `feature/spec4-serializer-v2` (off Milestone 1's merged branch)
**OpenSpec change**: `openspec/changes/serializer-v2/`
**Tasks file**: `openspec/changes/serializer-v2/tasks.md`

**What it does**: Add SerializerV2 base class, SerializerV1Adapter, MessagePackSerializer, modify Serialization.cs infrastructure, mechanical port of simple internal Protobuf serializers.
**What it does**: Establish the `SerializerV2` foundation — base class, V1 adapter, `Serialization.cs` / `MessageSerializer.cs` infrastructure changes, and V2 ports of `ByteArraySerializer` and `PrimitiveSerializers` as the reference implementation. Add a standalone transport-envelope benchmark that simulates `EndpointWriter`'s round trip on the V2 API and compares V2-direct against the V1-bridge baseline.

**Note**: This was originally planned as parallel with Milestone 1 but is sequenced after it to avoid merge conflicts in Serialization.cs and MessageSerializer.cs. The ByteString removal in Milestone 1 also affects serializer code paths.
**Note**: This was originally planned as parallel with Milestone 1 but is sequenced after it to avoid merge conflicts in `Serialization.cs` and `MessageSerializer.cs`. The ByteString removal in Milestone 1 also affects serializer code paths.

**Scope changed (2026-05-10)**: MessagePack codec, `AkkaWriter` / `AkkaReader`, `[AkkaSerializable]` / `[AkkaField]` / `[AkkaSerializer]` attributes, the `Akka.Serialization.V2` NuGet package, the Roslyn source generator, and the mechanical port of remaining Protobuf-based internal serializers (`ClusterMessageSerializer`, `SystemMessageSerializer`, the four `WrappedPayloadSupport` serializers) all moved out of this milestone and into a future change (`serializer-v2-codegen`). Reason: the runtime codec API stands or falls with the source generator that makes it ergonomic; locking in surface area before codegen requirements are in hand would force redesign churn.

**Completion criteria**:
- SerializerV2, SerializerV1Adapter exist in `src/core/Akka/Serialization/`
- Akka.Serialization.V2 package exists with MessagePackSerializer, AkkaWriter, AkkaReader
- `Serialization.cs` uses SerializerV2 internally, auto-wraps V1
- `FindSerializerFor()` returns SerializerV2
- Hand-written MessagePack serializer round-trips through full pipeline

- `SerializerV2`, `SerializerV1Adapter` exist in `src/core/Akka/Serialization/`
- `Serialization.cs` uses `SerializerV2` internally, auto-wraps V1 on registration
- `FindSerializerFor()` returns `SerializerV2`
- `MessageSerializer.cs` (Akka.Remote) uses V2 dispatch (calls `Manifest()` directly)
- `ByteArraySerializer` and `PrimitiveSerializers` ported to `SerializerV2` (same IDs, byte-identical wire format, all primitive paths covered: string / int32 / int64 / byte[])
- Transport-envelope benchmark exists in `src/benchmark/` and reports V2-direct vs V1-bridge allocations and throughput across the reference serializer paths
- All existing serialization tests pass (V1 auto-wrapped)
- Simple internal Protobuf serializers ported to V2 base (same IDs, same wire format)
- All Akka.Persistence tests pass (V1-persisted data still readable)
- `dotnet test -c Release --framework net10.0` passes

**After completion**: Review with human. Archive via `openspec archive serializer-v2`.
**After completion**: Review with human, including benchmark results. Archive via `openspec archive serializer-v2`.

---

Expand Down Expand Up @@ -129,6 +133,18 @@ Captured on `dev` branch (commit 467cbb510), .NET 10.0, Release, ServerGC, Linux

**After completion**: Review with human. Archive via `openspec archive transport-performance`.

---

## Unscheduled / Future Changes

### `serializer-v2-codegen` (spawned 2026-05-10 from Milestone 2 scope split)

**OpenSpec change**: `openspec/changes/serializer-v2-codegen/`

**What it will do**: Pick up the user-facing codec story that was deferred out of Milestone 2 — `MessagePackSerializer : SerializerV2`, sealed `AkkaWriter` / `AkkaReader`, `[AkkaSerializable]` / `[AkkaField]` / `[AkkaSerializer]` attributes, the `Akka.Serialization.V2` NuGet package, the Roslyn source generator, and the mechanical port of remaining Protobuf-based internal serializers.

**Sequencing**: Not on the critical path for the 1.6 transport epic. Can be scheduled independently once Milestone 2 is archived and the V2 API has been validated by its benchmark and downstream consumption from Spec 3.

## Orchestration

Each milestone is executed by an OpenProse orchestrator that:
Expand Down
3 changes: 3 additions & 0 deletions openspec/changes/serializer-v2-codegen/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
schema: spec-driven
created: 2026-05-10
status: placeholder
52 changes: 52 additions & 0 deletions openspec/changes/serializer-v2-codegen/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
## Status: Placeholder

This change captures work that was originally part of `serializer-v2` (Milestone 2 of the 1.6 transport epic) and was split out on 2026-05-10. It is **not yet specified in detail** — the runtime API surface depends on the source generator's requirements, and we deliberately want to design both together rather than locking in the runtime first and then redesigning it once codegen lands.

This file exists so that:

- The deferred work has a stable home in the openspec tree
- `serializer-v2`'s proposal can refer to it by name
- A future planning session can flesh it out without reconstructing context

## Why

Akka.NET end users need an ergonomic way to define their own V2 serializers. Hand-rolling a serializer against the `SerializerV2` buffer API (writing `Serialize(IBufferWriter<byte>, object)` and `Deserialize(ReadOnlySequence<byte>, string)` directly) is acceptable for internal serializers but is not the workflow we expect end users to adopt. The user story is: annotate a record/class with `[AkkaSerializable]`, mark a serializer class with `[AkkaSerializer]`, and have a Roslyn source generator emit the `Write` / `Read` methods that drive `AkkaWriter` / `AkkaReader` over MessagePack.

The runtime layer (`MessagePackSerializer`, `AkkaWriter`, `AkkaReader`, the attributes, the `Akka.Serialization.V2` package) and the codegen layer must be designed together, because the runtime API surface is the codegen's emission target — if the runtime API has the wrong shape for what the generator wants to emit, we redesign both. Better to do it once.

## What this change will cover (sketch)

The detailed proposal will be written when the change is scheduled. Anticipated scope:

- `Akka.Serialization.V2` NuGet package (separate from core Akka)
- `MessagePackSerializer : SerializerV2` intermediate base class
- `MessagePackSerializer<TProtocol>` generic variant for protocol scoping
- Sealed `AkkaWriter` / `AkkaReader` classes wrapping MessagePack-CSharp
- `[AkkaSerializable]` attribute on user message types
- `[AkkaField(index)]` attribute for stable field indexing
- `[AkkaSerializer]` attribute marking a partial serializer class as a codegen target
- Roslyn incremental source generator emitting the `Write` / `Read` overrides
- MSBuild integration so end-user projects pick up the generator transparently
- Mechanical port of remaining Protobuf-based internal serializers to `SerializerV2`:
- `ClusterMessageSerializer`
- `SystemMessageSerializer`
- The four `WrappedPayloadSupport` serializers (Sharding, PubSub, ReliableDelivery, Misc) — these need additional design for the nested-payload zero-copy path

## Why not ship the runtime layer alone first?

Considered and rejected. Shipping `Akka.Serialization.V2` with `AkkaWriter` / `AkkaReader` / attributes but no codegen means:

- Public surface area gets locked in before we know what the generator wants to emit against
- End users either hand-roll codecs (poor ergonomics, no real adopters) or wait for the generator anyway
- Any redesign of `AkkaWriter` to fit codegen is a breaking change to a published package

Source generator-only without the runtime is impossible — they're two halves of the same feature.

## Predecessors

- `serializer-v2` — establishes the `SerializerV2` foundation, V1 adapter, infrastructure, and the V2 reference implementations (`ByteArraySerializer`, `PrimitiveSerializers`). Must be archived before this change starts.

## Anticipated successors / dependencies on this change

- The full performance story for `WrappedPayloadSupport` serializers depends on this change shipping (nested-payload zero copy needs the V2 buffer API on the inner serializer)
- The user-facing migration guide for "how to write a V2 serializer in Akka.NET 1.6" depends on the codegen ergonomics being in place
Loading
Loading