Skip to content

feat(prefork): delegate to fasthttp/prefork to eliminate code duplication#4210

Draft
ReneWerner87 wants to merge 7 commits intomainfrom
prefork_optimization
Draft

feat(prefork): delegate to fasthttp/prefork to eliminate code duplication#4210
ReneWerner87 wants to merge 7 commits intomainfrom
prefork_optimization

Conversation

@ReneWerner87
Copy link
Copy Markdown
Member

Summary

Replaces previous PR #4037 (accidentally merged via branch tracking misconfiguration).

  • Replace Fiber's own prefork implementation with fasthttp's prefork package
  • Eliminate ~100 lines of duplicated process management logic
  • Add PreforkRecoverThreshold to ListenConfig for configurable child recovery
  • Add PreforkLogger to ListenConfig for configurable prefork logging
  • IsChild() delegates to prefork.IsChild()
  • Callbacks (OnChildSpawn, OnMasterReady, OnChildRecover) integrate Fiber's hooks
  • New prefork_logger.go with PreforkLoggerInterface

Depends on

Test plan

  • All prefork tests pass (child, master, TLS, mTLS, hooks)
  • Full fiber test suite passes (27s)
  • FastHTTP prefork tests pass (20/20)
  • gosec security scan: 0 issues

🤖 Generated with Claude Code

ReneWerner87 and others added 7 commits April 11, 2026 20:09
…tion

Replace Fiber's own prefork implementation with fasthttp's prefork package.
This eliminates duplicated process management logic and adds new features:

- IsChild() now delegates to prefork.IsChild()
- Master process uses fasthttp's recovery loop (RecoverThreshold)
- Callbacks (OnChildSpawn, OnMasterReady, OnChildRecover) integrate
  Fiber's hooks system (OnFork, OnListen, startup message)
- CommandProducer enables clean test injection (replaces testPreforkMaster)
- OnMasterDeath replaces Fiber's watchMaster (now in fasthttp)
- New PreforkRecoverThreshold field in ListenConfig
- prefork_logger.go adapts Fiber's logger to fasthttp's Logger interface
- go.mod uses replace directive for local fasthttp development

Code reduction: ~200 lines of process management removed from Fiber.
All existing tests adapted for recovery behavior (ErrOverRecovery).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ensures deterministic and fast execution regardless of GOMAXPROCS count.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use github.com/ReneWerner87/fasthttp@2802b1a (prefork_optimization branch)
instead of local ../fasthttp path, so CI and other developers can resolve
the dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Includes fix for ListenAndServeTLS parameter order preservation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- prefork_logger.go: use grouped import declaration
- prefork.go: rename unused 'files' parameter to '_'
- prefork.go: wrap external errors from cmd.Start() and ListenAndServe()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move windowsOS constant to constants.go (global consts file)
- Make prefork logger configurable via ListenConfig.PreforkLogger
- Define PreforkLoggerInterface for custom logger implementations
- Use logger.Printf instead of direct log.Warnf in OnChildRecover
- Remove unused log import from prefork.go

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 11, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2283f72d-1ce9-4cac-b56e-50b8aa8f3995

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch prefork_optimization

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 and usage tips.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the preforking mechanism by delegating process management to the fasthttp/prefork package, simplifying the internal implementation and adding support for recovery thresholds and custom loggers. Feedback highlights a security and maintenance risk regarding the use of a personal fork for fasthttp, a bug in the test command producer that starts processes prematurely, and a logic issue where the default recovery threshold could be zero on single-core systems.

gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/valyala/fasthttp => github.com/ReneWerner87/fasthttp v0.0.0-20260411181936-c1055ce62c37
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.

high

The replace directive points to a personal fork of fasthttp (ReneWerner87/fasthttp). Depending on a personal fork for core process management logic in a major framework like Fiber is a significant maintenance and security risk. This change should ideally wait until the required features are merged into the official valyala/fasthttp repository to ensure long-term stability and trust.

Comment on lines +61 to +64
if err := cmd.Start(); err != nil {
return cmd, fmt.Errorf("prefork: failed to start test command: %w", err)
}
return fmt.Errorf("prefork: %w", err)
return cmd, nil
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.

high

Calling cmd.Start() inside the CommandProducer is likely a bug. An *exec.Cmd can only be started once. Since fasthttp/prefork is responsible for managing the child processes, it will almost certainly call Start() on the command returned by this producer. If it does, the second attempt to start the process will fail with an "exec: already started" error. The producer should only configure and return the command, leaving the execution to the manager.

			return cmd, nil

// Determine RecoverThreshold
recoverThreshold := cfg.PreforkRecoverThreshold
if recoverThreshold == 0 {
recoverThreshold = runtime.GOMAXPROCS(0) / 2
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.

medium

The default recoverThreshold calculation (runtime.GOMAXPROCS(0) / 2) results in 0 on systems with a single CPU core. This means that by default, child processes will not be recovered after a crash in single-core environments, which is inconsistent with the behavior on multi-core systems. Consider using a minimum value of at least 1 to ensure consistent recovery behavior across different hardware configurations.

Suggested change
recoverThreshold = runtime.GOMAXPROCS(0) / 2
recoverThreshold = max(1, runtime.GOMAXPROCS(0)/2)

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.

1 participant