Skip to content
Open
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
3 changes: 3 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@
## 2026-07-28 - [Validating Context Cancellation for Blocking OS Executions]
**Learning:** Functions that wrap long-running system operations (such as `exec.CommandContext` or `net.DialContext`) generally handle context cancellation automatically, but early aborts for network calls need explicit testing. Merely relying on lower-level Go standard library propagation does not automatically guarantee zero side-effects if the cancellation happens before execution logic completes in consumer boundaries.
**Action:** Always include fine-grained tests that explicitly pass a pre-cancelled context to network discovery and connection routines (e.g. Ping, LookupAddr) to definitively prove zero leakage of OS processes or goroutines on early aborts.
## YYYY-MM-DD - Fix Goroutine Leak in ScanPorts on Context Cancellation
**Learning:** Worker goroutines can leak when sending on an unbuffered channel (`out <- p`) if the consumer prematurely stops reading due to context cancellation.
**Action:** Wrap channel send operations in a `select` statement with `ctx.Done()` to prevent goroutines from blocking indefinitely when the consumer aborts.
6 changes: 5 additions & 1 deletion pkg/ports/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ func ScanPorts(ctx context.Context, ip string, ports []int, timeoutMs int) <-cha
conn, err := dialer.DialContext(ctx, "tcp", address)
if err == nil {
conn.Close()
out <- p
select {
case <-ctx.Done():
return
case out <- p:
}
}
}
}()
Expand Down
Loading