Skip to content

🐛 bug: pin Context() not canceled on graceful shutdown - #4599

Open
RubenPari wants to merge 1 commit into
gofiber:mainfrom
RubenPari:fix/3431-shutdown-context-docs
Open

🐛 bug: pin Context() not canceled on graceful shutdown#4599
RubenPari wants to merge 1 commit into
gofiber:mainfrom
RubenPari:fix/3431-shutdown-context-docs

Conversation

@RubenPari

Copy link
Copy Markdown
Contributor

Summary

Pins and documents the v3 behavior for #3431: c.Context() is not canceled when graceful shutdown starts (default is context.Background() unless you SetContext). By contrast, c.RequestCtx().Done() is closed when fasthttp begins shutdown.

In-flight handlers that pass c.Context() to DB/clients can finish during graceful shutdown.

Changes

  • Integration regression test during ShutdownWithTimeout
  • Docs note on Context() vs RequestCtx

Linked issue

Closes #3431

Checklist

  • make format
  • make lint — 0 issues
  • targeted tests pass

Document and regression-test that c.Context() is not canceled when the
server shuts down, while RequestCtx.Done() is.

Closes gofiber#3431
@RubenPari
RubenPari requested a review from a team as a code owner August 9, 2026 20:50
@RubenPari
RubenPari requested review from ReneWerner87, efectn, gaby and sixcolors and a lite review from Copilot and removed request for Copilot August 9, 2026 20:50
@ReneWerner87 ReneWerner87 added this to v3 Aug 9, 2026
@ReneWerner87 ReneWerner87 added this to the v3 milestone Aug 9, 2026
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The change documents that Ctx.Context() remains usable during graceful shutdown while RequestCtx.Done() is canceled. An integration test validates this behavior for an in-flight request and confirms that shutdown completes successfully.

Changes

Graceful shutdown context behavior

Layer / File(s) Summary
Context contract and shutdown validation
docs/api/ctx.md, app_test.go
The documentation describes cancellation behavior for Context() and RequestCtx. The integration test verifies the behavior during an in-flight request and graceful shutdown.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: renewerner87

Poem

A rabbit watched the shutdown light,
While request paths stayed calm and bright.
Context() helped the work go on,
RequestCtx closed when drain began.
The final response hopped out right.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the graceful-shutdown context behavior and matches the primary change.
Description check ✅ Passed The description includes the problem, issue reference, changes, documentation impact, and validation checklist, with only optional template details omitted.
Linked Issues check ✅ Passed The test and documentation support issue #3431 by preserving c.Context() for in-flight work while documenting RequestCtx cancellation during shutdown.
Out of Scope Changes check ✅ Passed The regression test and documentation changes are directly related to the graceful-shutdown context behavior described in issue #3431.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app_test.go`:
- Around line 1526-1544: Update the test around app.Listener and the client
goroutine to replace the fixed 50 ms sleep with a ListenConfig.BeforeServeFunc
readiness signal, and report both goroutine errors through channels. Wait for
listener readiness before dialing, then join both goroutines after
ShutdownWithTimeout so connection, copy, close, and listener errors are asserted
before the test exits.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8d8db549-e837-47a6-9b63-07a7e5cce576

📥 Commits

Reviewing files that changed from the base of the PR and between a2a6d29 and aff7340.

📒 Files selected for processing (2)
  • app_test.go
  • docs/api/ctx.md

Comment thread app_test.go
Comment on lines +1526 to +1544
ln := fasthttputil.NewInmemoryListener()
go func() {
assert.NoError(t, app.Listener(ln))
}()
time.Sleep(50 * time.Millisecond)

go func() {
conn, err := ln.Dial()
assert.NoError(t, err)
_, err = conn.Write([]byte("GET /slow HTTP/1.1\r\nHost: example.com\r\n\r\n"))
assert.NoError(t, err)
// Drain response so the connection can finish cleanly.
_, copyErr := io.Copy(io.Discard, conn)
assert.NoError(t, copyErr)
assert.NoError(t, conn.Close())
}()

<-handlerStarted
require.NoError(t, app.ShutdownWithTimeout(2*time.Second))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Synchronize and join the listener and client goroutines.

The fixed 50 ms delay does not prove that app.Listener is ready. If ln.Dial() fails, handlerStarted never closes and the test blocks indefinitely. The client goroutine is also not joined, so its assertions can run after the test returns.

Use a listener-ready signal, such as ListenConfig.BeforeServeFunc, and return listener and client errors through channels. Wait for both goroutines before the test exits.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app_test.go` around lines 1526 - 1544, Update the test around app.Listener
and the client goroutine to replace the fixed 50 ms sleep with a
ListenConfig.BeforeServeFunc readiness signal, and report both goroutine errors
through channels. Wait for listener readiness before dialing, then join both
goroutines after ShutdownWithTimeout so connection, copy, close, and listener
errors are asserted before the test exits.

@codecov

codecov Bot commented Aug 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.43%. Comparing base (3f59010) to head (aff7340).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4599      +/-   ##
==========================================
- Coverage   93.47%   93.43%   -0.05%     
==========================================
  Files         140      140              
  Lines       14983    14983              
==========================================
- Hits        14006    14000       -6     
- Misses        608      613       +5     
- Partials      369      370       +1     
Flag Coverage Δ
unittests 93.43% <ø> (-0.05%) ⬇️

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.

@gaby

gaby commented Aug 10, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aff734065d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app_test.go
select {
case <-c.Context().Done():
contextErr <- c.Context().Err()
case <-time.After(500 * time.Millisecond):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Synchronize on shutdown before testing Context

If shutdown reaches fasthttp between the 500 ms timeout here and the subsequent RequestCtx.Done() check, both assertions pass even if c.Context() is incorrectly canceled at exactly the same time as RequestCtx. This can produce a false-positive regression test under scheduling delays; wait for RequestCtx.Done() as the shutdown-start barrier first, then check that c.Context() remains uncanceled.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

🐛 [Bug]: Request Context Cancelled on Graceful Shutdown

3 participants