Skip to content

Commit 73d727a

Browse files
authored
GEP-2257: Gateway API Duration Format (#2258)
* GEP-1898 Signed-off-by: [email protected] * Ugh, 1898 was a placeholder. Put the real number in, and tweak graduation requirements. Signed-off-by: [email protected] * Address review feedback. Signed-off-by: [email protected] * Review feedback Signed-off-by: [email protected] * Don't include a trailing "." in the link to the time.ParseDuration docs. Sigh. Signed-off-by: [email protected] * Add language about standard forms. Signed-off-by: [email protected] * Further clarification around the formatting requirements Signed-off-by: [email protected] --------- Signed-off-by: [email protected]
1 parent 64f329b commit 73d727a

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

geps/gep-2257.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# GEP-2257: Gateway API Duration Format
2+
3+
* Issue: [#2257](https://github.com/kubernetes-sigs/gateway-api/issues/2257)
4+
* Status: Experimental
5+
6+
## TL;DR
7+
8+
As we extend the Gateway API to have more functionality, we need a standard
9+
way to represent duration values. The first instance is the [HTTPRoute
10+
Timeouts GEP][GEP-1742]; doubtless others will arise.
11+
12+
[GEP-1742]:/geps/gep-1742
13+
14+
## Gateway API Duration Format
15+
16+
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
17+
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
18+
interpreted as described in [RFC 8174].
19+
20+
[RFC 8174]:https://datatracker.ietf.org/doc/html/rfc8174
21+
22+
A _Gateway API Duration_ or _GEP-2257 Duration_ is a string value that:
23+
24+
- MUST match the regular expression `^([0-9]{1,5}(h|m|s|ms)){1,4}$` and
25+
- MUST be interpreted as specified by [Golang's `time.ParseDuration`][gotime].
26+
27+
Since both of these conditions MUST be true, the effect is that GEP-2257
28+
Durations are a subset of what `time.ParseDuration` supports:
29+
30+
- A GEP-2257 Duration MUST be one to four _components_, each of which consists
31+
of an integer _value_ followed immediately by a _unit_. For example, `1h`,
32+
`5m`, `1h5m`, and `1h30m30s500ms` are all valid GEP-2257 Durations.
33+
34+
- For each component, the value MUST be one to five decimal digits. Floating
35+
point is not allowed. Leading zeroes do not mean octal; the value MUST
36+
always be interpreted as a decimal integer. For example, `1h`, `60m`, `01h`,
37+
and `00060m` are all equivalent GEP-2257 Durations.
38+
39+
- For each component, the unit MUST be one of `h` (hour), `m` (minute), `s`
40+
(second), or `ms` (millisecond). No units larger than hours or smaller than
41+
milliseconds are supported.
42+
43+
- The total duration expressed by a GEP-2257 Duration string is the sum of
44+
each of its components. For example, `1h30m` would be a 90-minute duration,
45+
and `1s500ms` would be a 1.5-second duration.
46+
47+
- There is no requirement that all units must be used. A GEP-2257 Duration of
48+
`1h500ms` is supported (although probably not terribly useful).
49+
50+
- Units MAY be repeated, although users SHOULD NOT rely on this support since
51+
this GEP is Experimental, and future revisions may remove support for
52+
repeated units. If units are repeated, the total duration remains the sum of
53+
all components: a GEP-2257 duration of `1h2h20m10m` is a duration of 3 hours
54+
30 minutes.
55+
56+
- Since the value and the unit are both required within a component, `0` is
57+
not a valid GEP-2257 duration string (though `0s` is). Likewise the empty
58+
string is not a valid GEP-2257 duration.
59+
60+
- Users SHOULD represent the zero duration as `0s`, although they MAY use any
61+
of `0h`, `0m`, etc. Implementations formatting a GEP-2257 Duration for
62+
output MUST render the zero duration as `0s`.
63+
64+
- The “standard” form of a GEP-2257 Duration uses descending, nonrepeating
65+
units, using the largest unit possible for each component (so `1h` rather
66+
than `60m` or `30m1800s`, and `1h30m` rather than either `90m` or `30m1h`).
67+
Users SHOULD use this standard form when writing GEP-2257 Durations.
68+
Implementations formatting GEP-2257 Durations MUST render them using this
69+
standard form.
70+
71+
- **Note**: Implementations of Kubernetes APIs MUST NOT modify user input.
72+
For example, implementations MUST NOT normalize `30m1800s` to `1h` in a
73+
CRD `spec`. This "standard form" requirement is limited to instances
74+
where an implementation needs to format a GEP-2257 Duration value for
75+
output.
76+
77+
A GEP-2257 Duration parser can be easily implemented by doing a regex-match
78+
check before calling a parser equivalent to Go's `time.ParseDuration`. Such
79+
parsers are readily available in (at least) [Go itself][gotime], [Rust's
80+
`kube_core` crate from `kube-rs`][kube-core], and [Python's
81+
`durationpy`][durationpy] package. We expect that these three languages cover
82+
the vast majority of the Kubernetes ecosystem.
83+
84+
[gotime]:https://pkg.go.dev/time#ParseDuration
85+
[kube-core]:https://docs.rs/kube-core/latest/kube_core/duration/struct.Duration.html
86+
[durationpy]:https://github.com/icholy/durationpy
87+
88+
## Alternatives
89+
90+
We considered three main alternatives:
91+
92+
- Raw Golang `time.ParseDuration` format. This is very widely used in the Go
93+
ecosystem -- however, it is a very open-ended specification and, in
94+
particular, its support for floating-point values and negative durations
95+
makes it difficult to validate.
96+
97+
- Golang `strfmt.ParseDuration` as used in the APIServer's OpenAPI validation
98+
code. It turns out that `strfmt.ParseDuration` is a superset of
99+
`time.ParseDuration`, so all the problems in validation are still present.
100+
Additionally, `strfmt.ParseDuration` supports day and week units, requiring
101+
discussion of leap seconds.
102+
103+
- ISO8601/RFC3339 durations. These are considerably less user-friendly than
104+
our proposal: `PT0.5S` is simply not as immediately clear as "500ms".
105+
106+
There is (a lot) more discussion in [PR 2155].
107+
108+
[PR 2155]:https://github.com/kubernetes-sigs/gateway-api/pull/2155
109+
110+
## Graduation Criteria
111+
112+
To graduate GEP-2257 to Standard channel, we need to meet the following
113+
criteria:
114+
115+
- Publish a set of test vectors for the GEP-2257 duration format.
116+
117+
- Have Go, Rust, and Python implementations of the parser, with a test suite
118+
covering all the test vectors.
119+
120+
- Have a custom CEL validator for GEP-2257 Duration fields.
121+
122+
- Have support for GEP-2257 Durations in standard Kubernetes libraries.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ nav:
106106
- geps/gep-957.md
107107
- geps/gep-713.md
108108
- geps/gep-1709.md
109+
- geps/gep-2257.md
109110
- Standard:
110111
- geps/gep-1364.md
111112
- geps/gep-1323.md

0 commit comments

Comments
 (0)