-
Notifications
You must be signed in to change notification settings - Fork 468
suggestion: without exponential backoff #1970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
da5ac03
924056e
9922f4a
32e649c
ba28ea0
e93a6a9
9e60ac0
6cc1ea6
6642773
db8297c
d4f26bb
7af4f80
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,7 @@ | ||
| <?php | ||
|
|
||
| $fail = random_int(1, 100) < 10; | ||
| $wait = random_int(1000 * 100, 1000 * 500); // wait 100ms - 500ms | ||
|
|
||
| usleep($wait); | ||
| if ($fail) { | ||
| exit(1); | ||
| if (rand(1, 100) <= 50) { | ||
| throw new Exception('this exception is expected to fail the worker'); | ||
| } | ||
|
|
||
| while (frankenphp_handle_request(function () { | ||
| echo "ok"; | ||
| })) { | ||
| $fail = random_int(1, 100) < 10; | ||
| if ($fail) { | ||
| exit(1); | ||
| } | ||
| } | ||
| // frankenphp_handle_request() has not been reached (also a failure) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,7 +10,6 @@ import ( | |
| "time" | ||
| "unsafe" | ||
|
|
||
| "github.com/dunglas/frankenphp/internal/backoff" | ||
| "github.com/dunglas/frankenphp/internal/state" | ||
| ) | ||
|
|
||
|
|
@@ -23,7 +22,6 @@ type workerThread struct { | |
| worker *worker | ||
| dummyContext *frankenPHPContext | ||
| workerContext *frankenPHPContext | ||
| backoff *backoff.ExponentialBackoff | ||
| isBootingScript bool // true if the worker has not reached frankenphp_handle_request yet | ||
| } | ||
|
|
||
|
|
@@ -32,11 +30,6 @@ func convertToWorkerThread(thread *phpThread, worker *worker) { | |
| state: thread.state, | ||
| thread: thread, | ||
| worker: worker, | ||
| backoff: &backoff.ExponentialBackoff{ | ||
| MaxBackoff: 1 * time.Second, | ||
| MinBackoff: 100 * time.Millisecond, | ||
| MaxConsecutiveFailures: worker.maxConsecutiveFailures, | ||
| }, | ||
| }) | ||
| worker.attachThread(thread) | ||
| } | ||
|
|
@@ -92,7 +85,6 @@ func (handler *workerThread) name() string { | |
| } | ||
|
|
||
| func setupWorkerScript(handler *workerThread, worker *worker) { | ||
| handler.backoff.Wait() | ||
| metrics.StartWorker(worker.name) | ||
|
|
||
| if handler.state.Is(state.Ready) { | ||
|
|
@@ -132,7 +124,6 @@ func tearDownWorkerScript(handler *workerThread, exitStatus int) { | |
| // on exit status 0 we just run the worker script again | ||
| if exitStatus == 0 && !handler.isBootingScript { | ||
| metrics.StopWorker(worker.name, StopReasonRestart) | ||
| handler.backoff.RecordSuccess() | ||
| logger.LogAttrs(ctx, slog.LevelDebug, "restarting", slog.String("worker", worker.name), slog.Int("thread", handler.thread.threadIndex), slog.Int("exit_status", exitStatus)) | ||
|
|
||
| return | ||
|
|
@@ -148,16 +139,25 @@ func tearDownWorkerScript(handler *workerThread, exitStatus int) { | |
| return | ||
| } | ||
|
|
||
| logger.LogAttrs(ctx, slog.LevelError, "worker script has not reached frankenphp_handle_request()", slog.String("worker", worker.name), slog.Int("thread", handler.thread.threadIndex)) | ||
|
|
||
| // panic after exponential backoff if the worker has never reached frankenphp_handle_request | ||
| if handler.backoff.RecordFailure() { | ||
| if !watcherIsEnabled && !handler.state.Is(state.Ready) { | ||
| logger.LogAttrs(ctx, slog.LevelError, "too many consecutive worker failures", slog.String("worker", worker.name), slog.Int("thread", handler.thread.threadIndex), slog.Int("failures", handler.backoff.FailureCount())) | ||
| panic("too many consecutive worker failures") | ||
| if !watcherIsEnabled && !handler.state.Is(state.Ready) { | ||
| select { | ||
| case startupFailChan <- fmt.Errorf("worker failure: script %s has not reached frankenphp_handle_request()", worker.fileName): | ||
| handler.thread.state.Set(state.ShuttingDown) | ||
| return | ||
| } | ||
| logger.LogAttrs(ctx, slog.LevelWarn, "many consecutive worker failures", slog.String("worker", worker.name), slog.Int("thread", handler.thread.threadIndex), slog.Int("failures", handler.backoff.FailureCount())) | ||
| } | ||
|
|
||
| if !watcherIsEnabled { | ||
| // rare case where worker script has failed on a restart during normal operation | ||
| // this can happen if startup success depends on external resources | ||
| logger.LogAttrs(ctx, slog.LevelError, "worker script has failed on restart", slog.String("worker", worker.name), slog.Int("thread", handler.thread.threadIndex)) | ||
| } else { | ||
| // worker script has probably failed due to script changes while watcher is enabled | ||
| logger.LogAttrs(ctx, slog.LevelWarn, "(watcher enabled) worker script has not reached frankenphp_handle_request()", slog.String("worker", worker.name), slog.Int("thread", handler.thread.threadIndex)) | ||
| } | ||
|
|
||
| // wait a bit and try again | ||
| time.Sleep(time.Millisecond * 250) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't it better to use an exponential back off strategy here? 😅
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. makes sense, I'll add a minimal version
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking about it, I'm not sure if having an exponential wait backoff will help with either script failures when watching or external resource failures. In both cases the time-to-resolution would probably be in the range of seconds. I'm not against keeping it though
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For external services, exponential backoff prevent these services from being flooded with requests when they are up again. Sometimes (see recent AWS issues), these issues take hours to be fixed. |
||
| } | ||
|
|
||
| // waitForWorkerRequest is called during frankenphp_handle_request in the php worker script. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.