Chromium Code Reviews| Index: common/prpc/timeout.go |
| diff --git a/server/prpc/timeout.go b/common/prpc/timeout.go |
| similarity index 51% |
| rename from server/prpc/timeout.go |
| rename to common/prpc/timeout.go |
| index 9811395ff985f533ca6a1d928e5715b37bb040f6..25d3aec9c05c004518f6af56b07cea340cadda87 100644 |
| --- a/server/prpc/timeout.go |
| +++ b/common/prpc/timeout.go |
| @@ -10,10 +10,6 @@ import ( |
| "time" |
| ) |
| -// headerTimeout is HTTP header used to set pRPC request timeout. |
| -// The single value should match regexp `\d+[HMSmun]`. |
| -const headerTimeout = "X-Prpc-Timeout" |
| - |
| // The rest of this file is adapted from |
| // https://github.com/grpc/grpc-go/blob/6a026b9f108b49838491178e5d9bf7a4dcf32cf2/transport/http_util.go#L295 |
| @@ -47,7 +43,8 @@ func timeoutUnitToDuration(u timeoutUnit) (d time.Duration, ok bool) { |
| return |
| } |
| -func decodeTimeout(s string) (time.Duration, error) { |
| +// DecodeTimeout decodes a gRPC/pRPC timeout header string into a time.Duration. |
| +func DecodeTimeout(s string) (time.Duration, error) { |
| size := len(s) |
| if size < 2 { |
| return 0, fmt.Errorf("too short: %q", s) |
| @@ -63,3 +60,39 @@ func decodeTimeout(s string) (time.Duration, error) { |
| } |
| return d * time.Duration(t), nil |
| } |
| + |
| +const maxTimeoutValue int64 = 100000000 - 1 |
| + |
| +// div does integer division and round-up the result. Note that this is |
| +// equivalent to (d+r-1)/r but has less chance to overflow. |
| +func div(d, r time.Duration) int64 { |
| + if m := d % r; m > 0 { |
| + return int64(d/r + 1) |
| + } |
| + return int64(d / r) |
| +} |
| + |
| +// EncodeTimeout encodes a gRPC/pRPC timeout into a timeout header |
| +// time.Duration. |
| +// |
| +// This rounds the time.Duration to the smallest time unit that can represent |
| +// it. |
| +func EncodeTimeout(t time.Duration) string { |
|
iannucci
2016/01/27 02:55:50
EncodeRPCTimeout?
dnj (Google)
2016/01/27 03:24:26
I dunno, there's only one timeout encoding so this
|
| + if d := div(t, time.Nanosecond); d <= maxTimeoutValue { |
| + return strconv.FormatInt(d, 10) + "n" |
| + } |
| + if d := div(t, time.Microsecond); d <= maxTimeoutValue { |
| + return strconv.FormatInt(d, 10) + "u" |
| + } |
| + if d := div(t, time.Millisecond); d <= maxTimeoutValue { |
| + return strconv.FormatInt(d, 10) + "m" |
| + } |
| + if d := div(t, time.Second); d <= maxTimeoutValue { |
| + return strconv.FormatInt(d, 10) + "S" |
| + } |
| + if d := div(t, time.Minute); d <= maxTimeoutValue { |
| + return strconv.FormatInt(d, 10) + "M" |
| + } |
| + // Note that maxTimeoutValue * time.Hour > MaxInt64. |
| + return strconv.FormatInt(div(t, time.Hour), 10) + "H" |
| +} |