cubefs
1/*
2*
3* Copyright 2020 gRPC authors.
4*
5* Licensed under the Apache License, Version 2.0 (the "License");
6* you may not use this file except in compliance with the License.
7* You may obtain a copy of the License at
8*
9* http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS,
13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14* See the License for the specific language governing permissions and
15* limitations under the License.
16*
17*/
18
19package grpcutil20
21import (22"strconv"23"time"24)
25
26const maxTimeoutValue int64 = 100000000 - 127
28// div does integer division and round-up the result. Note that this is
29// equivalent to (d+r-1)/r but has less chance to overflow.
30func div(d, r time.Duration) int64 {31if d%r > 0 {32return int64(d/r + 1)33}34return int64(d / r)35}
36
37// EncodeDuration encodes the duration to the format grpc-timeout header
38// accepts.
39//
40// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
41func EncodeDuration(t time.Duration) string {42// TODO: This is simplistic and not bandwidth efficient. Improve it.43if t <= 0 {44return "0n"45}46if d := div(t, time.Nanosecond); d <= maxTimeoutValue {47return strconv.FormatInt(d, 10) + "n"48}49if d := div(t, time.Microsecond); d <= maxTimeoutValue {50return strconv.FormatInt(d, 10) + "u"51}52if d := div(t, time.Millisecond); d <= maxTimeoutValue {53return strconv.FormatInt(d, 10) + "m"54}55if d := div(t, time.Second); d <= maxTimeoutValue {56return strconv.FormatInt(d, 10) + "S"57}58if d := div(t, time.Minute); d <= maxTimeoutValue {59return strconv.FormatInt(d, 10) + "M"60}61// Note that maxTimeoutValue * time.Hour > MaxInt64.62return strconv.FormatInt(div(t, time.Hour), 10) + "H"63}
64