Skip to content

Commit

Permalink
Enhance ParseDuration with configurable parsing options
Browse files Browse the repository at this point in the history
Introduce ParseDuration() as the primary and simplest entrypoint for
parsing durations
  • Loading branch information
frobware committed Sep 11, 2023
1 parent 298a36d commit d0db885
Show file tree
Hide file tree
Showing 9 changed files with 1,315 additions and 398 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@

# Go workspace file
go.work
/haproxytimeout
17 changes: 17 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
DATE := $(shell date --iso-8601=seconds)
GOVERSION := $(shell go version)
COMMIT := $(shell git describe --tags --abbrev=8 --dirty --always --long)

PREFIX := main
LDFLAGS := -X '$(PREFIX).buildCommit=$(COMMIT)' -X '$(PREFIX).buildDate=$(DATE)' -X '$(PREFIX).buildGoVersion=$(GOVERSION)'

build: test
go build -ldflags "$(LDFLAGS)" -o ./haproxytimeout ./cmd/haproxytimeout

test:
go test ./...

clean:
$(RM) ./haproxytimeout

.PHONY: build test clean
106 changes: 61 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,78 @@
# parse time durations, with support for days
# Parse time durations, with support for days

This is a Go library that parses duration strings in a format similar
to time.ParseDuration, with the additional capability of handling
duration strings specifying a number of days ("d"). This functionality
is not available in the built-in time.ParseDuration function. It also
differs by not accepting negative values. This package was primarily
created for validating HAProxy timeout values.
A Go library to parse time duration values similar to
time.ParseDuration, but with extended functionality. In addition to
the standard duration units like "h", "m", and "s", it also supports
days (represented as "d"), which are unavailable in the built-in
time.ParseDuration function. All durations parsed by this package are
ensured to be non-negative and won't overflow the time.Duration value
type. Furthermore, the parsed value cannot exceed HAProxy's maximum
timeout value, ensuring compatibility with HAProxy's configuration
constraints.

The CLI utility `haproxy-timeout-checker` is an example of using the
package. It validates the time duration using `ParseDuration` and also
checks to see if the duration exceeds HAProxy's maximum.
The CLI utility `haproxytimeout` is an example of using the package.
The utility parses a duration string, printing the parsed value as a
pair; "human-readable duration" -> "millisecond duration".

```console
$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "9223372036s"
duration 9223372036000ms exceeds HAProxy's maximum value of 2147483647ms
$ go build ./cmd/haproxytimeout
haproxytimeout - Convert human-readable durations to millisecond format

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "2147483647ms"
2147483647
Usage:
haproxytimeout [-m] [-j] <duration>

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "2147483648ms"
duration 2147483648ms exceeds HAProxy's maximum value of 2147483647ms
Options:
-m: Print the maximum duration HAProxy can tolerate and exit.
-j: Print results in JSON format. (e.g., haproxytimeout -j <duration> | jq .milliseconds)

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "1d"
86400000
Input Assumptions:
If the input is a plain number (or a decimal without a unit), it's
assumed to be in milliseconds. For example: 'haproxytimeout 1500'
is assumed to be '1500ms'.

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "1d 1s"
86401000
Output Format:
The output maps the human-readable format to the milliseconds
format. For example: 'haproxytimeout 2h30m' will output '2h30m ->
9000000ms'. The right-hand side is always in milliseconds, making it
suitable for direct use in a haproxy.cfg file.

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "1d 3h 10m 20s 100ms 9999us"
97820109
Available units:
d days
h: hours
m: minutes
s: seconds
ms: milliseconds
us: microseconds

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go 5000
5000
Examples:
haproxytimeout 2h30m -> Convert 2 hours 30 minutes to milliseconds
haproxytimeout 1500ms -> Convert 1500 milliseconds to a human-readable format
haproxytimeout -j 1h17m -> Get JSON output for 1h 17minutes
haproxytimeout -m -> Show the maximum duration HAProxy can tolerate
```

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "5000 999999ms"
5000 999999ms
^
error: invalid unit order
## Examples

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "1d 1f"
1d 1f
^
error: invalid unit
```sh
$ ./haproxytimeout 30m
30m -> 1800000ms
```

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "1d 1d"
1d 1d
^
error: invalid unit order
```sh
$ ./haproxytimeout 1d12h
1d12h -> 129600000ms
```

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "1d 5m 1230ms"
86701230
```sh
# Print maximum value allowed by HAProxy.
$ ./haproxytimeout -m
24d20h31m23s647ms -> 2147483647ms
```

# Note: Spaces are optional.
$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "1d5m"
86700000
```sh
% ./haproxytimeout -j 17m
{"human_readable":"17m","milliseconds":1020000}

$ go run cmd/haproxy-timeout-checker/haproxy-timeout-checker.go "9223372037s"
9223372037s
^
error: underflow
% ./haproxytimeout -j 17m | jq .milliseconds
1020000
```
34 changes: 0 additions & 34 deletions cmd/haproxy-timeout-checker/haproxy-timeout-checker.go

This file was deleted.

Loading

0 comments on commit d0db885

Please sign in to comment.