# Phase 6: Initial Porting Port Go code to .NET 10 C#, working through the dependency graph bottom-up. This is the main implementation phase where the actual code is written. ## Objective Implement every non-N/A module, feature, and test in the porting database. Work from leaf nodes (items with no unported dependencies) upward through the dependency graph. Keep the database current as work progresses. ## Prerequisites - Phase 5 complete: all mappings verified, no collisions, naming validated - .NET solution structure created: - `dotnet/src/ZB.MOM.NatsNet.Server/ZB.MOM.NatsNet.Server.csproj` - `dotnet/src/ZB.MOM.NatsNet.Server.Host/ZB.MOM.NatsNet.Server.Host.csproj` - `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ZB.MOM.NatsNet.Server.Tests.csproj` - `dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj` - Library dependencies (NuGet packages) added per Phase 3 mappings - Verify readiness: `dotnet run --project tools/NatsNet.PortTracker -- phase check 5 --db porting.db` ## Source and Target Locations - **Go source code** is located in the `golang/` folder (specifically `golang/nats-server/`) - **.NET ported version** is located in the `dotnet/` folder ## Porting Workflow This is the core loop. Repeat until all items are complete. ### Step 1: Find ready items Query for items whose dependencies are all ported (status `complete`, `verified`, or `n_a`): ```bash dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db ``` This returns modules and features that have no unported dependencies. Start with these. ### Step 2: Pick an item and mark as stub Choose an item from the ready list. Mark it as `stub` to signal work has begun: ```bash dotnet run --project tools/NatsNet.PortTracker -- feature update --status stub --db porting.db ``` ### Step 3: Create the skeleton In the .NET project, create the class and method skeleton based on the mapping: 1. Look up the mapping: `dotnet run --project tools/NatsNet.PortTracker -- feature show --db porting.db` 2. Create the file at the correct path under `dotnet/src/ZB.MOM.NatsNet.Server/` following the namespace hierarchy 3. Add the class declaration, method signature, and a `throw new NotImplementedException()` body For batch scaffolding of an entire module: ```bash dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub \ --all-in-module --db porting.db ``` ### Step 4: Implement the logic Reference the Go source code. The database stores the Go file path and line number for each feature: ```bash dotnet run --project tools/NatsNet.PortTracker -- feature show --db porting.db ``` The output includes `Go File`, `Go Line`, and `Go LOC` fields. Open the Go source at those coordinates and translate the logic to C#. Key translation patterns: | Go pattern | .NET equivalent | |-----------|-----------------| | `goroutine` + `channel` | `Task` + `Channel` or `async/await` | | `sync.Mutex` | `lock` statement or `SemaphoreSlim` | | `sync.RWMutex` | `ReaderWriterLockSlim` | | `sync.WaitGroup` | `Task.WhenAll` or `CountdownEvent` | | `defer` | `try/finally` or `using`/`IDisposable` | | `interface{}` / `any` | `object` or generics | | `[]byte` | `byte[]`, `ReadOnlySpan`, or `ReadOnlyMemory` | | `map[K]V` | `Dictionary` or `ConcurrentDictionary` | | `error` return | Exceptions or `Result` pattern | | `panic/recover` | Exceptions (avoid `Environment.FailFast` for recoverable cases) | | `select` on channels | `Task.WhenAny` or `Channel` reader patterns | | `context.Context` | `CancellationToken` | | `io.Reader/Writer` | `Stream`, `PipeReader/PipeWriter` | ### Step 5: Mark complete Once the implementation compiles and the basic logic is in place: ```bash dotnet run --project tools/NatsNet.PortTracker -- feature update --status complete --db porting.db ``` ### Step 6: Run targeted tests If tests exist for this feature, run them: ```bash dotnet test --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol" \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ ``` Fix any failures before moving on. ### Step 7: Check what is now unblocked Completing items may unblock others that depend on them: ```bash dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db ``` Return to Step 2 with the newly available items. ## DB Update Discipline The porting database must stay current. Update status at every transition: ```bash # Starting work on a feature dotnet run --project tools/NatsNet.PortTracker -- feature update 42 --status stub --db porting.db # Feature implemented dotnet run --project tools/NatsNet.PortTracker -- feature update 42 --status complete --db porting.db # Batch scaffolding for all features in a module dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub \ --all-in-module 3 --db porting.db # Module fully ported (all its features are complete) dotnet run --project tools/NatsNet.PortTracker -- module update 3 --status complete --db porting.db # Check progress dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db ``` Status transitions follow this progression: ``` not_started -> stub -> complete -> verified (Phase 7) \-> n_a (if determined during porting) ``` Never skip `stub` -- it signals that work is in progress and prevents duplicate effort. ## Porting Order Strategy ### Start with leaf modules Leaf modules have no dependencies on other unported modules. They are safe to port first because nothing they call is missing. ```bash # These are the leaves — port them first dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db ``` Typical leaf modules include: - Utility/helper code (string manipulation, byte buffer pools) - Constants and enums - Configuration types (options, settings) - Error types and codes ### Then work upward After leaves are done, modules that depended only on those leaves become ready. Continue up the dependency graph: ``` Leaf utilities -> Protocol types -> Parser -> Connection handler -> Server ``` ### Port tests alongside features When porting a feature, also port its associated tests in the same pass. This provides immediate validation: ```bash # List tests for a feature dotnet run --project tools/NatsNet.PortTracker -- test list --module --db porting.db # After porting a test dotnet run --project tools/NatsNet.PortTracker -- test update --status complete --db porting.db ``` ## Progress Tracking Check overall progress regularly: ```bash # Summary stats dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db # What is still blocked dotnet run --project tools/NatsNet.PortTracker -- dependency blocked --db porting.db # Phase-level check dotnet run --project tools/NatsNet.PortTracker -- phase check 6 --db porting.db ``` ## Handling Discoveries During Porting During implementation, you may find: ### Items that should be N/A If a feature turns out to be unnecessary in .NET (discovered during implementation): ```bash dotnet run --project tools/NatsNet.PortTracker -- feature set-na \ --reason "Go-specific memory management, handled by .NET GC" --db porting.db ``` ### Missing dependencies If the Go analyzer missed a dependency: ```bash # The dependency is tracked in the DB via the dependencies table # For now, just ensure the target is ported before continuing dotnet run --project tools/NatsNet.PortTracker -- dependency show feature --db porting.db ``` ### Design changes If the .NET design needs to differ from the original mapping (e.g., splitting a large Go function into multiple .NET methods), update the mapping: ```bash dotnet run --project tools/NatsNet.PortTracker -- feature map \ --class "NewClassName" \ --method "NewMethodName" \ --db porting.db ``` ## Tips 1. **Keep the build green.** The solution should compile after each feature is completed. Do not leave unresolved references. 2. **Write idiomatic C#.** Do not transliterate Go line-by-line. Use .NET patterns (async/await, LINQ, Span, dependency injection) where they produce cleaner code. 3. **Use `CancellationToken` everywhere.** The Go code uses `context.Context` pervasively -- mirror this with `CancellationToken` parameters. 4. **Prefer `ReadOnlySpan` for hot paths.** The NATS parser processes bytes at high throughput. Use spans and avoid allocations in the critical path. 5. **Do not port Go comments verbatim.** Translate the intent into C# XML doc comments where appropriate. 6. **Run `dotnet build` frequently.** Catch compile errors early rather than accumulating them. ## Completion Criteria - All non-N/A modules have status `complete` or better - All non-N/A features have status `complete` or better - All non-N/A tests have status `complete` or better - The solution compiles without errors: `dotnet build` - `dependency blocked` returns no items (or only items waiting for Phase 7 verification) - `report summary` shows the expected completion counts ## Related Documentation - [Phase 5: Mapping Verification](phase-5-mapping-verification.md) -- the verified mappings this phase implements - [Phase 7: Porting Verification](phase-7-porting-verification.md) -- targeted testing of the ported code