All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.rsocket.core.Resume Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2015-2020 the original author or 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
 *
 *      https://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.rsocket.core;

import io.netty.buffer.ByteBuf;
import io.rsocket.frame.ResumeFrameCodec;
import io.rsocket.resume.InMemoryResumableFramesStore;
import io.rsocket.resume.ResumableFramesStore;
import java.time.Duration;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.util.retry.Retry;

/**
 * Simple holder of configuration settings for the RSocket Resume capability. This can be used to
 * configure an {@link RSocketConnector} or an {@link RSocketServer} except for {@link
 * #retry(Retry)} and {@link #token(Supplier)} which apply only to the client side.
 */
public class Resume {
  private static final Logger logger = LoggerFactory.getLogger(Resume.class);

  private Duration sessionDuration = Duration.ofMinutes(2);

  /* Storage */
  private boolean cleanupStoreOnKeepAlive;
  private Function storeFactory;
  private Duration streamTimeout = Duration.ofSeconds(10);

  /* Client only */
  private Supplier tokenSupplier = ResumeFrameCodec::generateResumeToken;
  private Retry retry =
      Retry.backoff(Long.MAX_VALUE, Duration.ofSeconds(1))
          .maxBackoff(Duration.ofSeconds(16))
          .jitter(1.0)
          .doBeforeRetry(signal -> logger.debug("Connection error", signal.failure()));

  public Resume() {}

  /**
   * The maximum time for a client to keep trying to reconnect. During this time client and server
   * continue to store unsent frames to keep the session warm and ready to resume.
   *
   * 

By default this is set to 2 minutes. * * @param sessionDuration the max duration for a session * @return the same instance for method chaining */ public Resume sessionDuration(Duration sessionDuration) { this.sessionDuration = Objects.requireNonNull(sessionDuration); return this; } /** * When this property is enabled, hints from {@code KEEPALIVE} frames about how much data has been * received by the other side, is used to proactively clean frames from the {@link * #storeFactory(Function) store}. * *

By default this is set to {@code false} in which case information from {@code KEEPALIVE} is * ignored and old frames from the store are removed only when the store runs out of space. * * @return the same instance for method chaining */ public Resume cleanupStoreOnKeepAlive() { this.cleanupStoreOnKeepAlive = true; return this; } /** * Configure a factory to create the storage for buffering (or persisting) a window of frames that * may need to be sent again to resume after a dropped connection. * *

By default {@link InMemoryResumableFramesStore} is used with its cache size set to 100,000 * bytes. When the cache fills up, the oldest frames are gradually removed to create space for new * ones. * * @param storeFactory the factory to use to create the store * @return the same instance for method chaining */ public Resume storeFactory( Function storeFactory) { this.storeFactory = storeFactory; return this; } /** * A {@link reactor.core.publisher.Flux#timeout(Duration) timeout} value to apply to the resumed * session stream obtained from the {@link #storeFactory(Function) store} after a reconnect. The * resume stream must not take longer than the specified time to emit each frame. * *

By default this is set to 10 seconds. * * @param streamTimeout the timeout value for resuming a session stream * @return the same instance for method chaining */ public Resume streamTimeout(Duration streamTimeout) { this.streamTimeout = Objects.requireNonNull(streamTimeout); return this; } /** * Configure the logic for reconnecting. This setting is for use with {@link * RSocketConnector#resume(Resume)} on the client side only. * *

By default this is set to: * *

{@code
   * Retry.backoff(Long.MAX_VALUE, Duration.ofSeconds(1))
   *     .maxBackoff(Duration.ofSeconds(16))
   *     .jitter(1.0)
   * }
* * @param retry the {@code Retry} spec to use when attempting to reconnect * @return the same instance for method chaining */ public Resume retry(Retry retry) { this.retry = retry; return this; } /** * Customize the generation of the resume identification token used to resume. This setting is for * use with {@link RSocketConnector#resume(Resume)} on the client side only. * *

By default this is {@code ResumeFrameFlyweight::generateResumeToken}. * * @param supplier a custom generator for a resume identification token * @return the same instance for method chaining */ public Resume token(Supplier supplier) { this.tokenSupplier = supplier; return this; } // Package private accessors Duration getSessionDuration() { return sessionDuration; } boolean isCleanupStoreOnKeepAlive() { return cleanupStoreOnKeepAlive; } Function getStoreFactory(String tag) { return storeFactory != null ? storeFactory : token -> new InMemoryResumableFramesStore(tag, token, 100_000); } Duration getStreamTimeout() { return streamTimeout; } Retry getRetry() { return retry; } Supplier getTokenSupplier() { return tokenSupplier; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy