Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions v3/UNRELEASED_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ After processing, the content will be moved to the main changelog and this file

## Changed
<!-- Changes in existing functionality -->
- Use exponential backoff when waiting for the frontend dev server to become reachable, extending the total retry window to ~32 s and preventing premature failures when dev servers are slow to start (#5504)

## Fixed
<!-- Bug fixes -->
Expand Down
50 changes: 29 additions & 21 deletions v3/pkg/application/application_dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,39 @@ import (

var devMode = false

// preRun is called before the application starts. In dev mode it waits for the
// frontend dev server to become reachable, retrying up to 10 times with
// exponential backoff (250 ms base, capped at 5 s per attempt).
func (a *App) preRun() error {
// Check for frontend server url
frontendURL := assetserver.GetDevServerURL()
if frontendURL != "" {
devMode = true
// We want to check if the frontend server is running by trying to http get the url
// and if it is not, we wait 500ms and try again for a maximum of 10 times. If it is
// still not available, we return an error.
// This is to allow the frontend server to start up before the backend server.
client := http.Client{}
a.Logger.Info("Waiting for frontend dev server to start...", "url", frontendURL)
for i := 0; i < 10; i++ {
_, err := client.Get(frontendURL)
if err == nil {
a.Logger.Info("Connected to frontend dev server!")
return nil
}
// Wait 500ms
time.Sleep(500 * time.Millisecond)
if i%2 == 0 {
a.Logger.Info("Retrying...")
}
if frontendURL == "" {
return nil
}

devMode = true
a.Logger.Info("Waiting for frontend dev server to start...", "url", frontendURL)

const (
maxRetries = 10
maxDelay = 5 * time.Second
)
client := http.DefaultClient
delay := 250 * time.Millisecond

for i := range maxRetries {
_, err := client.Get(frontendURL)
if err == nil {
a.Logger.Info("Connected to frontend dev server!")
return nil
}
a.Logger.Info("Retrying...", "attempt", i+1, "next_delay", delay)
time.Sleep(delay)
if delay *= 2; delay > maxDelay {
delay = maxDelay
}
a.fatal("unable to connect to frontend server. Please check it is running - FRONTEND_DEVSERVER_URL='%s'", frontendURL)
}

a.fatal("unable to connect to frontend server. Please check it is running - FRONTEND_DEVSERVER_URL='%s'", frontendURL)
return nil
}

Expand Down