io.servicetalk.http.netty.H2KeepAlivePolicies Maven / Gradle / Ivy
Show all versions of servicetalk-http-netty Show documentation
/*
* Copyright © 2020 Apple Inc. and the ServiceTalk project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.servicetalk.http.netty;
import io.servicetalk.http.netty.H2ProtocolConfig.KeepAlivePolicy;
import java.time.Duration;
import static io.servicetalk.utils.internal.DurationUtils.ensureNonNegative;
import static io.servicetalk.utils.internal.DurationUtils.ensurePositive;
import static java.time.Duration.ofSeconds;
import static java.util.Objects.requireNonNull;
/**
* A factory to create {@link KeepAlivePolicy} instances.
*/
public final class H2KeepAlivePolicies {
static final Duration DEFAULT_IDLE_DURATION = ofSeconds(30);
static final Duration DEFAULT_ACK_TIMEOUT = ofSeconds(5);
private static final KeepAlivePolicy DISABLE_KEEP_ALIVE =
new DefaultKeepAlivePolicy(Duration.ZERO, DEFAULT_ACK_TIMEOUT, false);
private H2KeepAlivePolicies() {
// no instances.
}
/**
* Returns a {@link KeepAlivePolicy} that disables all keep alive behaviors.
*
* @return A {@link KeepAlivePolicy} that disables all keep alive behaviors.
*/
public static KeepAlivePolicy disabled() {
return DISABLE_KEEP_ALIVE;
}
/**
* Returns a {@link KeepAlivePolicy} that sends a
* ping if the channel is idle for the passed {@code idleDuration}. Default values are used for other parameters
* of the returned {@link KeepAlivePolicy}.
*
* @param idleDuration {@link Duration} of idleness on a connection after which a
* ping is sent.
* @return A {@link KeepAlivePolicy} that sends a
* ping if the channel is idle for the passed {@code idleDuration}.
* @see KeepAlivePolicy#idleDuration()
*/
public static KeepAlivePolicy whenIdleFor(final Duration idleDuration) {
ensureNonNegative(idleDuration, "idleDuration");
if (idleDuration.isZero()) {
return disabled();
}
return new KeepAlivePolicyBuilder().idleDuration(idleDuration).build();
}
/**
* Returns a {@link KeepAlivePolicy} that sends a
* ping if the channel is idle for the passed {@code idleDuration} and waits for {@code ackTimeout} for an ack
* for that ping. Default values are used for other
* parameters of the returned {@link KeepAlivePolicy}.
*
* @param idleDuration {@link Duration} of idleness on a connection after which a
* ping is sent.
* This value is recommended to be greater than or equal to {@code ackTimeout}.
* @param ackTimeout {@link Duration} to wait for an acknowledgment of a previously sent
* ping.
* This value is recommended to be less than or equal to {@code idleDuration}.
* @return A {@link KeepAlivePolicy} that sends a
* ping if the channel is idle for the passed {@code idleDuration} and waits for {@code ackTimeout} for an ack
* for that ping
* @see KeepAlivePolicy#idleDuration()
* @see KeepAlivePolicy#ackTimeout()
*/
public static KeepAlivePolicy whenIdleFor(final Duration idleDuration, final Duration ackTimeout) {
return new KeepAlivePolicyBuilder().idleDuration(idleDuration).ackTimeout(ackTimeout).build();
}
/**
* A builder of {@link KeepAlivePolicy}.
*/
public static final class KeepAlivePolicyBuilder {
private Duration idleDuration = DEFAULT_IDLE_DURATION;
private Duration ackTimeout = DEFAULT_ACK_TIMEOUT;
private boolean withoutActiveStreams;
/**
* Set the {@link Duration} of idleness on a connection after which a
* ping is sent.
*
* Too short ping durations can be used for testing but may cause unnecessarily high network traffic in real
* environments. {@link Duration#ZERO} disables keep-alive {@code PING} frames.
*
* @param idleDuration {@link Duration} of idleness on a connection after which a
* ping is sent or {@link Duration#ZERO} to
* disable keep-alive {@code PING} frames.
* @return {@code this}.
* @see KeepAlivePolicy#idleDuration()
*/
public KeepAlivePolicyBuilder idleDuration(final Duration idleDuration) {
this.idleDuration = ensureNonNegative(idleDuration, "idleDuration");
return this;
}
/**
* Set the maximum {@link Duration} to wait for an acknowledgment of a previously sent
* ping. If no acknowledgment is received, within
* the configured timeout, a connection will be closed.
*
* This duration must be positive. Too short ack timeout can cause undesirable connection closures. Too long ack
* timeout can add unnecessary delay when the remote peer is unresponsive or the network connection is broken,
* because under normal circumstances {@code PING} frames ara acknowledged immediately.
*
* @param ackTimeout {@link Duration} to wait for an acknowledgment of a previously sent
* ping.
* @return {@code this}.
* @see KeepAlivePolicy#ackTimeout()
*/
public KeepAlivePolicyBuilder ackTimeout(final Duration ackTimeout) {
this.ackTimeout = ensurePositive(ackTimeout, "ackTimeout");
return this;
}
/**
* Allow/disallow sending pings even
* when no streams are active.
*
* @param withoutActiveStreams {@code true} if
* pings are expected when no streams are
* active.
* @return {@code this}.
* @see KeepAlivePolicy#withoutActiveStreams()
*/
public KeepAlivePolicyBuilder withoutActiveStreams(final boolean withoutActiveStreams) {
this.withoutActiveStreams = withoutActiveStreams;
return this;
}
/**
* Build a new {@link KeepAlivePolicy}.
*
* @return new {@link KeepAlivePolicy}.
*/
public KeepAlivePolicy build() {
return new DefaultKeepAlivePolicy(idleDuration, ackTimeout, withoutActiveStreams);
}
}
static KeepAlivePolicy validateKeepAlivePolicy(final KeepAlivePolicy keepAlivePolicy) {
requireNonNull(keepAlivePolicy, "keepAlivePolicy");
ensureNonNegative(keepAlivePolicy.idleDuration(), "idleDuration");
ensurePositive(keepAlivePolicy.ackTimeout(), "ackTimeout");
return keepAlivePolicy;
}
}