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_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_PING_RATE_POLICY_H 16 #define GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_PING_RATE_POLICY_H 17 18 #include <grpc/support/port_platform.h> 19 #include <stddef.h> 20 21 #include <iosfwd> 22 #include <string> 23 24 #include "absl/types/variant.h" 25 #include "src/core/lib/channel/channel_args.h" 26 #include "src/core/util/time.h" 27 28 namespace grpc_core { 29 30 class Chttp2PingRatePolicy { 31 public: 32 explicit Chttp2PingRatePolicy(const ChannelArgs& args, bool is_client); 33 34 static void SetDefaults(const ChannelArgs& args); 35 36 struct SendGranted { 37 bool operator==(const SendGranted&) const { return true; } 38 }; 39 struct TooManyRecentPings { 40 bool operator==(const TooManyRecentPings&) const { return true; } 41 }; 42 struct TooSoon { 43 Duration next_allowed_ping_interval; 44 Timestamp last_ping; 45 Duration wait; 46 bool operator==(const TooSoon& other) const { 47 return next_allowed_ping_interval == other.next_allowed_ping_interval && 48 last_ping == other.last_ping && wait == other.wait; 49 } 50 }; 51 using RequestSendPingResult = 52 absl::variant<SendGranted, TooManyRecentPings, TooSoon>; 53 54 // Request that one ping be sent. 55 // Returns: 56 // - SendGranted if a ping can be sent. 57 // - TooManyRecentPings if too many pings have been sent recently and we 58 // should wait for some future write. 59 // - TooSoon if we should wait for some time before sending the ping. 60 RequestSendPingResult RequestSendPing(Duration next_allowed_ping_interval, 61 size_t inflight_pings) const; 62 // Notify the policy that one ping has been sent. 63 void SentPing(); 64 // Notify the policy that some data has been sent and so we should no longer 65 // block pings on that basis. 66 void ResetPingsBeforeDataRequired(); 67 // Notify the policy that we've received some data. 68 void ReceivedDataFrame(); 69 std::string GetDebugString() const; 70 TestOnlyMaxPingsWithoutData()71 int TestOnlyMaxPingsWithoutData() const { 72 return max_pings_without_data_sent_; 73 } 74 75 private: 76 const int max_pings_without_data_sent_; 77 const int max_inflight_pings_; 78 int pings_before_data_sending_required_ = 0; 79 Timestamp last_ping_sent_time_ = Timestamp::InfPast(); 80 }; 81 82 std::ostream& operator<<(std::ostream& out, 83 const Chttp2PingRatePolicy::RequestSendPingResult& r); 84 85 } // namespace grpc_core 86 87 #endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_PING_RATE_POLICY_H 88