• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_PYTHON_OPENCENSUS_RPC_ENCODING_H
16 #define GRPC_PYTHON_OPENCENSUS_RPC_ENCODING_H
17 
18 #include <grpc/support/port_platform.h>
19 #include <stdint.h>
20 #include <string.h>
21 
22 #include "absl/base/internal/endian.h"
23 #include "absl/strings/string_view.h"
24 
25 namespace grpc_observability {
26 
27 // TODO(xuanwn): Reuse c++ rpc_encoding file.
28 // RpcServerStatsEncoding encapsulates the logic for encoding and decoding of
29 // rpc server stats messages. Rpc server stats consists of a uint64_t time
30 // value (server latency in nanoseconds).
31 class RpcServerStatsEncoding {
32  public:
33   // Size of encoded RPC server stats.
34   static constexpr size_t kRpcServerStatsSize = 10;
35   // Error value.
36   static constexpr size_t kEncodeDecodeFailure = 0;
37 
38   // Deserializes rpc server stats from the incoming 'buf' into *time.  Returns
39   // number of bytes decoded. If the buffer is of insufficient size (it must be
40   // at least kRpcServerStatsSize bytes) or the encoding version or field ID are
41   // unrecognized, *time will be set to 0 and it will return
42   // kEncodeDecodeFailure. Inlined for performance reasons.
Decode(absl::string_view buf,uint64_t * time)43   static size_t Decode(absl::string_view buf, uint64_t* time) {
44     if (buf.size() < kRpcServerStatsSize) {
45       *time = 0;
46       return kEncodeDecodeFailure;
47     }
48 
49     uint8_t version = buf[kVersionIdOffset];
50     uint32_t fieldID = buf[kServerElapsedTimeOffset];
51     if (version != kVersionId || fieldID != kServerElapsedTimeField) {
52       *time = 0;
53       return kEncodeDecodeFailure;
54     }
55     *time = absl::little_endian::Load64(
56         &buf[kServerElapsedTimeOffset + kFieldIdSize]);
57     return kRpcServerStatsSize;
58   }
59 
60   // Serializes rpc server stats into the provided buffer.  It returns the
61   // number of bytes written to the buffer. If the buffer is smaller than
62   // kRpcServerStatsSize bytes it will return kEncodeDecodeFailure. Inlined for
63   // performance reasons.
Encode(uint64_t time,char * buf,size_t buf_size)64   static size_t Encode(uint64_t time, char* buf, size_t buf_size) {
65     if (buf_size < kRpcServerStatsSize) {
66       return kEncodeDecodeFailure;
67     }
68 
69     buf[kVersionIdOffset] = kVersionId;
70     buf[kServerElapsedTimeOffset] = kServerElapsedTimeField;
71     absl::little_endian::Store64(&buf[kServerElapsedTimeOffset + kFieldIdSize],
72                                  time);
73     return kRpcServerStatsSize;
74   }
75 
76  private:
77   // Size of Version ID.
78   static constexpr size_t kVersionIdSize = 1;
79   // Size of Field ID.
80   static constexpr size_t kFieldIdSize = 1;
81 
82   // Offset and value for currently supported version ID.
83   static constexpr size_t kVersionIdOffset = 0;
84   static constexpr size_t kVersionId = 0;
85 
86   enum FieldIdValue {
87     kServerElapsedTimeField = 0,
88   };
89 
90   enum FieldSize {
91     kServerElapsedTimeSize = 8,
92   };
93 
94   enum FieldIdOffset {
95     kServerElapsedTimeOffset = kVersionIdSize,
96   };
97 
98   RpcServerStatsEncoding() = delete;
99   RpcServerStatsEncoding(const RpcServerStatsEncoding&) = delete;
100   RpcServerStatsEncoding(RpcServerStatsEncoding&&) = delete;
101   RpcServerStatsEncoding operator=(const RpcServerStatsEncoding&) = delete;
102   RpcServerStatsEncoding operator=(RpcServerStatsEncoding&&) = delete;
103 };
104 
105 }  // namespace grpc_observability
106 
107 #endif  // GRPC_PYTHON_OPENCENSUS_RPC_ENCODING_H
108