Skip to content

feat: add SafeContext()/SetSafeContext() for concurrency-safe user-defined context - #760

Merged
panjf2000 merged 5 commits into
panjf2000:devfrom
gunli:safe-context
Jul 3, 2026
Merged

panjf2000 merged 5 commits into
panjf2000:devfrom
gunli:safe-context

Conversation

@gunli

@gunli gunli commented Jul 2, 2026 •

Copy link
Copy Markdown
Contributor

add SafeContext() and SetSafeContext() to support concurrency-safe user-defined context

1. Are you opening this pull request for bug-fix, optimization or new feature?

New feature.

2. Please describe how these code changes achieve your intention.

  1. Add SafeContext() (ctx any) and SetSafeContext(ctx any) to Conn;
  2. Add a field safeCtx atomic.Pointer[any] to conn and implement SafeContext() (ctx any) and SetSafeContext(ctx any) in connection_unix.go and connection_windows.go;
  3. Reset both ctx and safeCtx when conn is released;
  4. Init both ctx and safeCtx in client_unix.go and eventloop_unix.go.

3. Please link to the relevant issues (if any).

4. What documentation changes (if any) need to be made/updated because of this PR?

No

4. Checklist

  • I have squashed all insignificant commits.
  • I have commented my code for explaining package types, values, functions, and non-obvious lines.
  • I have written unit tests and verified that all tests passes (if needed).
  • I have documented feature info on the README (only when this PR is adding a new feature).
  • (optional) I am willing to help maintain this change if there are issues with it later.

@codecov

codecov Bot commented Jul 3, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.43%. Comparing base (f424318) to head (728bcd1).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #760      +/-   ##
==========================================
+ Coverage   84.38%   84.43%   +0.04%     
==========================================
  Files          22       22              
  Lines        2402     2422      +20     
==========================================
+ Hits         2027     2045      +18     
- Misses        255      257       +2     
  Partials      120      120              
Flag Coverage Δ
unittests 84.43% <100.00%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

panjf2000 and others added 4 commits July 3, 2026 12:38
- TestSafeContext in gnet_test.go: verifies initial nil state, round-trip
  correctness across rotating concrete types (including nil) driven by
  OnTraffic, concurrent background-goroutine safety, non-interference
  with Context(), and safety when called from OnClose before release().
- TestClientSafeContext in client_test.go: verifies DialContext's ctx
  argument is immediately reflected by both Context() and SafeContext(),
  plus the same rotating-type/concurrent-access pattern on the client
  side.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Port 10000 is used by netdisk_s (ndmp) on some macOS systems, causing
spurious bind: address already in use failures. Switch the four
affected tests (TestDisconnectedAsyncWrite, TestUDPSendtoServer,
TestStreamProxyServer, TestUDPProxyServer) to port 19999 instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Reference Context()/SetContext() directly when describing the
  concurrency-safe SafeContext()/SetSafeContext() variants.
- Note that LocalAddr()/RemoteAddr() return values must be copied via
  net.Addr.String() if used outside of EventHandler methods.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- TestClientSafeContext: assert Context()/SafeContext() reflect the
  dial-time ctx directly inside OnOpen (guaranteed to run before any
  OnTraffic mutates it), instead of racily checking from the test
  goroutine after DialContext returns. Also verify SafeContext()
  becomes nil once the connection is released.
- TestSafeContext: verify SafeContext() becomes nil once the
  connection is released, in addition to the existing OnOpen check
  that it starts out nil before the first SetSafeContext call.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@panjf2000 panjf2000 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@panjf2000 panjf2000 added enhancement New feature or request pending merged This PR has been reviewed and approved optimization Some small optimizations proposal accepted Proposal has been accepted new feature docs labels Jul 3, 2026
@panjf2000 panjf2000 added this to the v2.10.0 milestone Jul 3, 2026
@panjf2000 panjf2000 changed the title feat: add SafeContext() and SetSafeContext() to support concurrency-safe user-defined context feat: add SafeContext()/SetSafeContext() for concurrency-safe user-defined context Jul 3, 2026
@panjf2000
panjf2000 merged commit 441457f into panjf2000:dev Jul 3, 2026
33 checks passed
panjf2000 added a commit that referenced this pull request Jul 3, 2026
* feat: add SafeContext()/SetSafeContext() for concurrency-safe user-defined context (#760)

Add SafeContext() and SetSafeContext(ctx any) to the Conn interface,
backed by atomic.Pointer[any], allowing goroutines other than the
owning event-loop to safely read/write a connection's user-defined
context without racing against Context()/SetContext(), which remain
event-loop-only.

- Implement safeCtx atomic.Pointer[any] field and accessors in
  connection_unix.go/connection_windows.go; wire up initial context on
  Windows via SetSafeContext at connection construction; reset safeCtx
  to nil in release().
- Clarify Conn interface doc comments for SafeContext/SetSafeContext
  (reference Context/SetContext directly) and for LocalAddr/RemoteAddr
  (note callers must copy the returned net.Addr via String() if used
  outside EventHandler).
- Add TestSafeContext (gnet_test.go) and TestClientSafeContext
  (client_test.go) covering: nil before first SetSafeContext, rotating
  concrete types (including nil) via OnTraffic, concurrent SafeContext
  reads from a background goroutine, no interference with
  Context()/SetContext(), correctness immediately after Dial/OnOpen,
  safety when called from OnClose, and reset to nil after release().
- Avoid port 10000 in existing tests (conflicts with a common local
  service on some machines), switching to 19999.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: gunli <gunli@tencent.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs enhancement New feature or request new feature optimization Some small optimizations pending merged This PR has been reviewed and approved proposal accepted Proposal has been accepted

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants