@@ -96,19 +96,75 @@ public interface Builder {
9696 //Builder pushEnabled(boolean pushEnabled);
9797
9898 /**
99- * Sets the interval for checking ping frames.
100- * If a ping ACK frame is not received within the configured interval, the connection will be closed.
99+ * Sets the interval for sending HTTP/2 PING frames and receiving ACK responses.
101100 *
102- * <p>Be cautious when setting a very short interval, as it may cause the connection to be closed,
103- * even if the keep-alive setting is enabled.</p>
101+ * <p>
102+ * This method configures the time interval at which PING frames are sent to the peer.
103+ * The interval should be chosen carefully to balance between detecting connection issues
104+ * and minimizing unnecessary network traffic.
105+ * </p>
104106 *
105- * <p>If no interval is specified, no ping frame checking will be performed by default.</p>
107+ * <p>
108+ * If the interval is set too short, it may cause excessive network overhead.
109+ * If set too long, connection failures may not be detected in a timely manner.
110+ * </p>
106111 *
107- * @param pingInterval the duration between sending ping frames. If not specified, ping frame checking is disabled.
108- * @return {@code this}
109- * @since 1.2.3
112+ * @param pingAckTimeout the interval in between consecutive PING frames
113+ * and ACK responses. Must be a positive value.
114+ */
115+ default Builder pingAckTimeout (Duration pingAckTimeout ) {
116+ return this ;
117+ }
118+
119+ /**
120+ * Sets the execution interval for the scheduler that sends HTTP/2 PING frames
121+ * and periodically checks for ACK responses.
122+ *
123+ * <p>
124+ * This method configures the time interval at which the scheduler runs
125+ * to send PING frames and verify if ACK responses are received within
126+ * the expected timeframe.
127+ * Proper tuning of this interval helps in detecting connection issues
128+ * while avoiding unnecessary network overhead.
129+ * </p>
130+ *
131+ * <p>
132+ * If the interval is too short, it may increase network and CPU usage.
133+ * Conversely, setting it too long may delay the detection of connection failures.
134+ * </p>
135+ *
136+ * @param pingScheduleInterval the interval in at which the scheduler executes.
137+ * Must be a positive value.
110138 */
111- default Builder pingInterval (Duration pingInterval ) {
139+ default Builder pingScheduleInterval (Duration pingScheduleInterval ) {
140+ return this ;
141+ }
142+
143+ /**
144+ * Sets the threshold for retrying HTTP/2 PING frame transmissions.
145+ *
146+ * <p>
147+ * This method defines the maximum number of attempts to send a PING frame
148+ * before considering the connection as unresponsive.
149+ * If the threshold is exceeded without receiving an ACK response,
150+ * the connection may be closed or marked as unhealthy.
151+ * </p>
152+ *
153+ * <p>
154+ * A lower threshold can detect connection failures more quickly but may lead
155+ * to premature disconnections. Conversely, a higher threshold allows more retries
156+ * but may delay failure detection.
157+ * </p>
158+ *
159+ * <p>
160+ * If this value is not specified, it defaults to 0, meaning only one attempt to send a PING frame is made without retries.
161+ * </p>
162+ *
163+ * @param pingAckDropThreshold the maximum number of PING transmission attempts.
164+ * Must be a positive integer.
165+ * The default value is 0, meaning no retries will occur and only one PING frame will be sent.
166+ */
167+ default Builder pingAckDropThreshold (Integer pingAckDropThreshold ) {
112168 return this ;
113169 }
114170 }
@@ -195,13 +251,33 @@ public Boolean pushEnabled() {
195251 }
196252
197253 /**
198- * Returns the configured {@code pingInterval} value or null.
254+ * Returns the configured {@code pingAckTimeout} value or null.
255+ *
256+ * @return the configured {@code pingAckTimeout} value or null
257+ */
258+ @ Nullable
259+ public Duration pingAckTimeout () {
260+ return pingAckTimeout ;
261+ }
262+
263+ /**
264+ * Returns the configured {@code pingScheduleInterval} value or null.
199265 *
200- * @return the configured {@code pingInterval } value or null
266+ * @return the configured {@code pingScheduleInterval } value or null
201267 */
202268 @ Nullable
203- public Duration pingInterval () {
204- return pingInterval ;
269+ public Duration pingScheduleInterval () {
270+ return pingScheduleInterval ;
271+ }
272+
273+ /**
274+ * Returns the configured {@code pingAckDropThreshold} value or null.
275+ *
276+ * @return the configured {@code pingAckDropThreshold} value or null
277+ */
278+ @ Nullable
279+ public Integer pingAckDropThreshold () {
280+ return pingAckDropThreshold ;
205281 }
206282
207283 @ Override
@@ -220,7 +296,9 @@ public boolean equals(Object o) {
220296 maxHeaderListSize .equals (that .maxHeaderListSize ) &&
221297 Objects .equals (maxStreams , that .maxStreams ) &&
222298 Objects .equals (pushEnabled , that .pushEnabled ) &&
223- Objects .equals (pingInterval , that .pingInterval );
299+ Objects .equals (pingAckTimeout , that .pingAckTimeout ) &&
300+ Objects .equals (pingScheduleInterval , that .pingScheduleInterval ) &&
301+ Objects .equals (pingAckDropThreshold , that .pingAckDropThreshold );
224302 }
225303
226304 @ Override
@@ -233,7 +311,9 @@ public int hashCode() {
233311 result = 31 * result + (maxHeaderListSize == null ? 0 : Long .hashCode (maxHeaderListSize ));
234312 result = 31 * result + (maxStreams == null ? 0 : Long .hashCode (maxStreams ));
235313 result = 31 * result + (pushEnabled == null ? 0 : Boolean .hashCode (pushEnabled ));
236- result = 31 * result + (pingInterval == null ? 0 : Objects .hashCode (pingInterval ));
314+ result = 31 * result + (pingAckTimeout == null ? 0 : Objects .hashCode (pingAckTimeout ));
315+ result = 31 * result + (pingScheduleInterval == null ? 0 : Objects .hashCode (pingScheduleInterval ));
316+ result = 31 * result + (pingAckDropThreshold == null ? 0 : Integer .hashCode (pingAckDropThreshold ));
237317 return result ;
238318 }
239319
@@ -244,7 +324,9 @@ public int hashCode() {
244324 final Long maxHeaderListSize ;
245325 final Long maxStreams ;
246326 final Boolean pushEnabled ;
247- final Duration pingInterval ;
327+ final Duration pingAckTimeout ;
328+ final Duration pingScheduleInterval ;
329+ final Integer pingAckDropThreshold ;
248330
249331 Http2SettingsSpec (Build build ) {
250332 Http2Settings settings = build .http2Settings ;
@@ -261,12 +343,16 @@ public int hashCode() {
261343 maxHeaderListSize = settings .maxHeaderListSize ();
262344 maxStreams = build .maxStreams ;
263345 pushEnabled = settings .pushEnabled ();
264- pingInterval = build .pingInterval ;
346+ pingAckTimeout = build .pingAckTimeout ;
347+ pingScheduleInterval = build .pingScheduleInterval ;
348+ pingAckDropThreshold = build .pingAckDropThreshold ;
265349 }
266350
267351 static final class Build implements Builder {
268352 Long maxStreams ;
269- Duration pingInterval ;
353+ Duration pingAckTimeout ;
354+ Duration pingScheduleInterval ;
355+ Integer pingAckDropThreshold ;
270356 final Http2Settings http2Settings = Http2Settings .defaultSettings ();
271357
272358 @ Override
@@ -314,8 +400,20 @@ public Builder maxStreams(long maxStreams) {
314400 }
315401
316402 @ Override
317- public Builder pingInterval (Duration pingInterval ) {
318- this .pingInterval = pingInterval ;
403+ public Builder pingAckTimeout (Duration pingAckTimeout ) {
404+ this .pingAckTimeout = pingAckTimeout ;
405+ return this ;
406+ }
407+
408+ @ Override
409+ public Builder pingScheduleInterval (Duration pingScheduleInterval ) {
410+ this .pingScheduleInterval = pingScheduleInterval ;
411+ return this ;
412+ }
413+
414+ @ Override
415+ public Builder pingAckDropThreshold (Integer pingAckDropThreshold ) {
416+ this .pingAckDropThreshold = pingAckDropThreshold ;
319417 return this ;
320418 }
321419
0 commit comments