docs: add phase 4-7 instruction guides
This commit is contained in:
252
docs/plans/phases/phase-6-porting.md
Normal file
252
docs/plans/phases/phase-6-porting.md
Normal file
@@ -0,0 +1,252 @@
|
||||
# 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:
|
||||
- `src/NATS.Server/NATS.Server.csproj`
|
||||
- `src/NATS.Server.Host/NATS.Server.Host.csproj`
|
||||
- `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
- `tests/NATS.Server.IntegrationTests/NATS.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`
|
||||
|
||||
## 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 <id> --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 <id> --db porting.db`
|
||||
2. Create the file at the correct path under `src/NATS.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 <module_id> --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 <id> --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<T>` 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<byte>`, or `ReadOnlyMemory<byte>` |
|
||||
| `map[K]V` | `Dictionary<K,V>` or `ConcurrentDictionary<K,V>` |
|
||||
| `error` return | Exceptions or `Result<T>` pattern |
|
||||
| `panic/recover` | Exceptions (avoid `Environment.FailFast` for recoverable cases) |
|
||||
| `select` on channels | `Task.WhenAny` or `Channel<T>` 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 <id> --status complete --db porting.db
|
||||
```
|
||||
|
||||
### Step 6: Run targeted tests
|
||||
|
||||
If tests exist for this feature, run them:
|
||||
|
||||
```bash
|
||||
dotnet test --filter "FullyQualifiedName~NATS.Server.Tests.Protocol" \
|
||||
tests/NATS.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 <module_id> --db porting.db
|
||||
|
||||
# After porting a test
|
||||
dotnet run --project tools/NatsNet.PortTracker -- test update <id> --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 <id> \
|
||||
--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 <id> --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 <id> \
|
||||
--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<byte>` 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
|
||||
Reference in New Issue
Block a user