dubbo.apache.org/dubbo-go/v3@v3.1.1/xds/utils/grpcutil/encode_duration.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   * contributor license agreements.  See the NOTICE file distributed with
     4   * this work for additional information regarding copyright ownership.
     5   * The ASF licenses this file to You under the Apache License, Version 2.0
     6   * (the "License"); you may not use this file except in compliance with
     7   * the License.  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  /*
    19   *
    20   * Copyright 2020 gRPC authors.
    21   *
    22   */
    23  
    24  package grpcutil
    25  
    26  import (
    27  	"strconv"
    28  	"time"
    29  )
    30  
    31  const maxTimeoutValue int64 = 100000000 - 1
    32  
    33  // div does integer division and round-up the result. Note that this is
    34  // equivalent to (d+r-1)/r but has less chance to overflow.
    35  func div(d, r time.Duration) int64 {
    36  	if d%r > 0 {
    37  		return int64(d/r + 1)
    38  	}
    39  	return int64(d / r)
    40  }
    41  
    42  // EncodeDuration encodes the duration to the format grpc-timeout header
    43  // accepts.
    44  //
    45  // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
    46  func EncodeDuration(t time.Duration) string {
    47  	// TODO: This is simplistic and not bandwidth efficient. Improve it.
    48  	if t <= 0 {
    49  		return "0n"
    50  	}
    51  	if d := div(t, time.Nanosecond); d <= maxTimeoutValue {
    52  		return strconv.FormatInt(d, 10) + "n"
    53  	}
    54  	if d := div(t, time.Microsecond); d <= maxTimeoutValue {
    55  		return strconv.FormatInt(d, 10) + "u"
    56  	}
    57  	if d := div(t, time.Millisecond); d <= maxTimeoutValue {
    58  		return strconv.FormatInt(d, 10) + "m"
    59  	}
    60  	if d := div(t, time.Second); d <= maxTimeoutValue {
    61  		return strconv.FormatInt(d, 10) + "S"
    62  	}
    63  	if d := div(t, time.Minute); d <= maxTimeoutValue {
    64  		return strconv.FormatInt(d, 10) + "M"
    65  	}
    66  	// Note that maxTimeoutValue * time.Hour > MaxInt64.
    67  	return strconv.FormatInt(div(t, time.Hour), 10) + "H"
    68  }