Skip to content
Permalink
Browse files

remove retries, refactor crash recovery, and add in-flight request ti…

…meouts.

Related:
  - #688
  - #338
  • Loading branch information...
tj committed Jul 11, 2018
1 parent 5f16b7f commit 921e818860bb3995d3d963b62cf0b746cc14c708
Showing with 90 additions and 516 deletions.
  1. +3 −45 config/relay.go
  2. +2 −35 docs/04-configuration.md
  3. +54 −185 http/relay/relay.go
  4. +26 −191 http/relay/relay_test.go
  5. +5 −60 http/relay/testdata/basic/app.js
@@ -9,27 +9,11 @@ type Relay struct {
// Command run to start your server.
Command string `json:"command"`

// Backoff configuration.
Backoff Backoff `json:"backoff"`

// Retry enables idempotent request retries. Enabled by default.
Retry *bool `json:"retry"`

// Timeout in seconds to wait for a response.
// This is also taken into account when performing
// retries, as to not exceed the limit.
Timeout int `json:"timeout"`

// ListenTimeout in seconds when waiting for
// the application to bind to PORT.
// ListenTimeout in seconds when waiting for the app to bind to PORT.
ListenTimeout int `json:"listen_timeout"`

// ShutdownTimeout in seconds to wait after
// sending a SIGINT before sending a SIGKILL.
ShutdownTimeout int `json:"shutdown_timeout"`

// platform is a currently unexported designation of the target deploy platform for this Relay
platform string
}

// Default implementation.
@@ -46,22 +30,6 @@ func (r *Relay) Default() error {
r.ListenTimeout = 15
}

if r.ShutdownTimeout == 0 {
r.ShutdownTimeout = 15
}

if err := r.Backoff.Default(); err != nil {
return errors.Wrap(err, ".backoff")
}

if r.Retry != nil && !*r.Retry {
r.Backoff.Attempts = 0
}

if r.platform == "" {
r.platform = "lambda"
}

return nil
}

@@ -72,31 +40,21 @@ func (r *Relay) Validate() error {
return errors.Wrap(err, ".command")
}

if r.platform != "lambda" {
err := errors.New("internal consistency error, platform should be lambda")
return errors.Wrap(err, ".platform")
}

if r.ListenTimeout <= 0 {
err := errors.New("should be greater than 0")
return errors.Wrap(err, ".listen_timeout")
}

if r.platform == "lambda" && r.ListenTimeout > 25 {
if r.ListenTimeout > 25 {
err := errors.New("should be <= 25")
return errors.Wrap(err, ".listen_timeout")
}

if r.platform == "lambda" && r.Timeout > 25 {
if r.Timeout > 25 {
err := errors.New("should be <= 25")
return errors.Wrap(err, ".timeout")
}

if r.ShutdownTimeout < 0 {
err := errors.New("should be greater than 0")
return errors.Wrap(err, ".shutdown_timeout")
}

return nil
}

@@ -548,19 +548,15 @@ The following settings are available:
- When `package.json` is detected `npm start` is used
- When `app.js` is detected `node app.js` is used
- When `app.py` is detected `python app.py` is used
- `backoff` – Backoff configuration object described in "Crash Recovery"
- `retry` – Retry idempotent requests upon server crashes. (Default `true`)
- `timeout` – Timeout in seconds per request (Default `15`, Max `25`)
- `listen_timeout` – Timeout in seconds Up will wait for your app to boot and listen on `PORT` (Default `15`, Max `25`)
- `shutdown_timeout` – Timeout in seconds Up will wait after sending a SIGINT to your server, before sending a SIGKILL (Default `15`)

```json
{
"proxy": {
"command": "node app.js",
"timeout": 10,
"listen_timeout": 5,
"shutdown_timeout": 5
"listen_timeout": 5
}
}
```
@@ -569,36 +565,7 @@ Lambda's function timeout is implied from the `.proxy.timeout` setting.

### Crash Recovery

Another benefit of using Up as a reverse proxy is performing crash recovery. Up will retry idempotent requests upon failure, and upon crash it will restart your server and re-attempt before responding to the client.

By default the back-off is configured as:

- `min` – Minimum time before retrying (Default `100ms`)
- `max` – Maximum time before retrying (Default `500ms`)
- `factor` – Factor applied to each attempt (Default `2`)
- `attempts` – Attempts made before failing (Default `3`)
- `jitter` – Apply jitter (Default `false`)

By default a total of 3 consecutive attempts will be made before responding with an error, in the default case this will be a total of 700ms for the three attempts.

Here's an example tweaking the default behaviour:

```json
{
"proxy": {
"command": "node app.js",
"backoff": {
"min": 500,
"max": 1500,
"factor": 1.5,
"attempts": 5,
"jitter": true
}
}
}
```

Since Up's purpose is to proxy your http traffic, Up will treat network errors as a crash. When Up detects this, it will allow the server to cleanly close by sending a SIGINT, it the server does not close within `proxy.shutdown_timeout` seconds, it will forcibly close it with a SIGKILL.
Another benefit of using Up as a reverse proxy is performing crash recovery. Up will attempt to restart your application if the process crashes to continue serving subsequent requests.

## DNS Zones & Records

Oops, something went wrong.

0 comments on commit 921e818

Please sign in to comment.
You can’t perform that action at this time.