You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: networking/dynamic-request-routing.html.markerb
+57Lines changed: 57 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -33,6 +33,8 @@ Your app can add a `fly-replay` header to its response. The `fly-replay` header
33
33
|`app` | The name of another app to route to |
34
34
|`state` | Optional string included in `fly-replay-src` header on replay |
35
35
|`elsewhere` | If `true`, excludes responding Machine from next load-balance |
36
+
|`timeout` | Duration to attempt the replay before giving up (e.g. `10s`, `800ms`) |
37
+
|`fallback` | If the replay fails, route back to the original Machine. `force_self` or `prefer_self` (see [Replay Timeout and Fallback](#replay-timeout-and-fallback)) |
36
38
37
39
### Example Usage
38
40
@@ -70,6 +72,11 @@ You can combine multiple fields:
70
72
fly-replay: region="sjc,any";app=target-app
71
73
```
72
74
75
+
Route to another app with a timeout and fallback to the original Machine:
**Note**: A comma-separated list of regions must be quoted.
75
82
</div>
@@ -87,6 +94,23 @@ When replaying to a region, you can use geographic aliases like `us`, `eu`, or `
87
94
| `us`, `usa` | United States |
88
95
| `any` | Earth |
89
96
97
+
### Replay Timeout and Fallback
98
+
99
+
You can set a `timeout` and `fallback` on a replay to handle cases where the replay target is unreachable.
100
+
101
+
**`timeout`** sets how long the proxy tries to reach the replay target. The actual duration may slightly exceed this value. Accepts duration strings like `10s`, `500ms`. Without `fallback`, a timeout makes the replay error faster instead of waiting for the default error timeout.
102
+
103
+
**`fallback`** tells the proxy to route the request back to the Machine that issued the replay if the replay fails due to timeout, exhausted retries, or no available candidate:
104
+
105
+
- `force_self`: Route back to the exact Machine that issued the replay. Returns a proxy error if that Machine is no longer available.
106
+
- `prefer_self`: Try the original Machine first, but fall back to any Machine in the original app if it is unavailable.
107
+
108
+
When a fallback triggers, the original Machine receives the request again with a [`fly-replay-failed`](#the-fly-replay-failed-header) request header containing details about the failed replay attempt. Since this is still the original request, your app can respond with a useful error instead of the client receiving a generic proxy error.
Your app can set the response content-type to `application/vnd.fly.replay+json` and include replay instructions in the response body.
@@ -104,6 +128,8 @@ The `application/vnd.fly.replay+json` replay body accepts the following fields:
104
128
|`app` | The name of another app to route to |
105
129
|`state` | Optional string included in `fly-replay-src` header on replay |
106
130
|`elsewhere` | If `true`, excludes responding Machine from next load-balance |
131
+
|`timeout` | Duration to attempt the replay before giving up (e.g. `"10s"`, `"800ms"`) |
132
+
|`fallback` | If the replay fails, route back to the original Machine. `"force_self"` or `"prefer_self"` (see [Replay Timeout and Fallback](#replay-timeout-and-fallback)) |
107
133
|`transform.path` | Rewrite the path and query parameters of the request |
108
134
|`transform.delete_headers` | Delete headers from the request, hiding them from the replay target |
109
135
|`transform.set_headers` | Set new headers on the request, overwriting headers of the same name |
@@ -130,6 +156,16 @@ Route to another app, and modify the request:
130
156
}
131
157
```
132
158
159
+
Route to another app with a timeout and fallback:
160
+
161
+
```json
162
+
{
163
+
"app": "my-worker",
164
+
"timeout": "10s",
165
+
"fallback": "force_self"
166
+
}
167
+
```
168
+
133
169
## Replay Caching
134
170
135
171
Replay caching allows Fly Proxy to remember and reuse replay decisions, reducing both load on your application and the latency of replayed requests. There are two types of replay caching:
@@ -286,6 +322,7 @@ For `fly-replay-cache`, the following limitations apply:
286
322
- Transformations for the headers or path cannot be defined.
287
323
- The TTL needs to be a minimum of 10 seconds
288
324
- Only one step of lookup is performed in the cache; as such, if the target app issues another `fly-replay-cache`, the caching behavior in this case is undefined
325
+
- The `timeout` and `fallback` fields cannot be set in the `fly-replay` intended to be cached
289
326
- The `fly-replay-src` header (described below) will _not_ be set for requests replayed through the cache
290
327
291
328
### The fly-replay-src Header
@@ -309,6 +346,26 @@ If you replay with `prefer_instance` set, Fly Proxy will attempt to route to thi
309
346
310
347
In these cases, the request will be delivered to a different Machine that matches the remaining fields in your replay. Along with the other Fly.io-specific headers, a `fly-preferred-instance-unavailable` header will be set containing the ID of the instance that could not be reached.
311
348
349
+
### The fly-replay-failed Header
350
+
351
+
When a replay [fallback](#replay-timeout-and-fallback) triggers, Fly Proxy delivers the request back to the original Machine with a `fly-replay-failed` request header. This header contains semicolon-separated metadata about the failed replay attempt:
352
+
353
+
|Field |Description |
354
+
|---|---|
355
+
|`instance` | ID of Machine the replay was targeting |
356
+
|`app` | App the replay was targeting |
357
+
|`region` | Region the replay was targeting |
358
+
|`replay_source` | ID of the Machine that originally issued the replay |
359
+
|`reason` | Why the replay failed: `timeout`, `retries_exhausted`, or `no_candidate` |
360
+
|`elapsed_ms` | Time in milliseconds spent attempting the replay |
Your app can use this header to detect that a fallback occurred and respond accordingly, for example by serving a helpful error to the client.
368
+
312
369
### Web Socket Considerations
313
370
314
371
It is worth noting that an application returning `fly-replay` headers should not negotiate a web socket upgrade itself. Some frameworks automatically handle this process. Instead, the application or instance receiving the requests should handle the upgrade.
0 commit comments