Skip to content

fix: add graceful shutdown to UI server#1747

Open
AmanGIT07 wants to merge 3 commits into
mainfrom
fix/ui-server-graceful-shutdown
Open

fix: add graceful shutdown to UI server#1747
AmanGIT07 wants to merge 3 commits into
mainfrom
fix/ui-server-graceful-shutdown

Conversation

@AmanGIT07

Copy link
Copy Markdown
Contributor

Summary

The UI server now shuts down gracefully on the process stop signal,
draining in-flight requests within the grace period.

Changes

  • ServeUI builds a dedicated http.Server instead of calling the
    package-level http.ListenAndServe, and shuts it down when the
    context is cancelled.
  • UI routes register on a local http.ServeMux instead of the global
    DefaultServeMux, so the UI port serves only its own routes.
  • Flattened a redundant else block (the branch above it returns).
  • Added tests for shutdown on context cancel and the disabled-port case.

Technical Details

ListenAndServe runs in a goroutine reporting into a buffered channel;
the main flow selects between server failure and context cancellation.
On cancellation it calls Shutdown bounded by the existing grace
period, so ServeUI returns only after in-flight requests finish. A
startup failure logs and returns, and the app keeps running since the
UI is optional.

Test Plan

  • Added TestServeUIReturnsAfterShutdownOnContextCancel (starts the
    real server, polls /configs, cancels, asserts clean return)
  • Added TestServeUIReturnsWhenPortNotConfigured
  • go test -race ./pkg/server/... passes
  • golangci-lint run pkg/server/ reports 0 issues

🤖 Generated with Claude Code

The UI server ignored the shutdown signal and had no way to stop: it
used the package-level http.ListenAndServe, which offers no Shutdown.
Build a dedicated http.Server on a local mux, watch the context, and
drain requests within the grace period. The local mux also keeps
routes registered by other packages off the UI port.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview, Comment Jul 10, 2026 12:18pm

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c53c92d6-f187-40e7-8e52-9b24fd0e3d0c

📥 Commits

Reviewing files that changed from the base of the PR and between bcfcf0f and 98fa948.

📒 Files selected for processing (1)
  • pkg/server/server.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/server/server.go

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved UI server shutdown so it exits promptly when its context is canceled.
    • UI startup now returns quickly when no UI port is configured.
    • UI routing is handled by an isolated request handler, with graceful shutdown behavior that won’t affect other HTTP handlers.
  • Tests
    • Added tests covering shutdown behavior on context cancel and prompt return when the UI port is not configured.

Walkthrough

Changes

ServeUI lifecycle

Layer / File(s) Summary
Dedicated server and graceful shutdown
pkg/server/server.go
ServeUI uses a dedicated mux and HTTP server, registers UI and proxy routes, runs asynchronously, and performs graceful shutdown on context cancellation.
Lifecycle test coverage
pkg/server/serve_ui_test.go
Tests verify the configs endpoint, prompt return after cancellation, and prompt return when no port is configured; UI asset-dependent coverage is skipped when assets are unavailable.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

🧹 Nitpick comments (1)
pkg/server/server.go (1)

107-110: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add ReadHeaderTimeout to the UI HTTP server.

The newly constructed http.Server has no read, write, or idle timeouts, leaving it vulnerable to Slowloris-style resource exhaustion. Setting at least ReadHeaderTimeout bounds how long the server waits for request headers. Consider adding WriteTimeout and IdleTimeout as well, bearing in mind that overly aggressive write timeouts can interrupt large SPA asset responses.

🛡️ Proposed fix
 	server := &http.Server{
 		Addr:    fmt.Sprintf(":%d", uiConfig.Port),
 		Handler: mux,
+		ReadHeaderTimeout: 10 * time.Second,
 	}

Source: Linters/SAST tools


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5d952878-b233-4d10-88a7-f499119869dc

📥 Commits

Reviewing files that changed from the base of the PR and between cd6b070 and a5f9b4a.

📒 Files selected for processing (2)
  • pkg/server/serve_ui_test.go
  • pkg/server/server.go

Comment thread pkg/server/server.go
The dist folder is gitignored except for a placeholder, so in CI the
embedded assets are empty and ServeUI exits before listening. Skip the
shutdown test in that case, matching the condition ServeUI itself
checks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coveralls

coveralls commented Jul 10, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 29092121671

Coverage decreased (-0.009%) to 44.867%

Details

  • Coverage decreased (-0.009%) from the base build.
  • Patch coverage: 49 uncovered changes across 1 file (0 of 49 lines covered, 0.0%).
  • 5 coverage regressions across 1 file.

Uncovered Changes

File Changed Covered %
pkg/server/server.go 49 0 0.0%

Coverage Regressions

5 previously-covered lines in 1 file lost coverage.

File Lines Losing Coverage Coverage
pkg/server/server.go 5 2.91%

Coverage Stats

Coverage Status
Relevant Lines: 37665
Covered Lines: 16899
Line Coverage: 44.87%
Coverage Strength: 12.53 hits per line

💛 - Coveralls

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants