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

com.arangodb.shaded.vertx.core.streams.impl.PumpImpl Maven / Gradle / Ivy

There is a newer version: 7.8.0
Show newest version
/*
 * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 * which is available at https://www.apache.org/licenses/LICENSE-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 */

package com.arangodb.shaded.vertx.core.streams.impl;

import com.arangodb.shaded.vertx.core.Handler;
import com.arangodb.shaded.vertx.core.streams.Pump;
import com.arangodb.shaded.vertx.core.streams.ReadStream;
import com.arangodb.shaded.vertx.core.streams.WriteStream;

import java.util.Objects;

/**
 * Pumps data from a {@link com.arangodb.shaded.vertx.core.streams.ReadStream} to a {@link com.arangodb.shaded.vertx.core.streams.WriteStream} and performs flow control where necessary to
 * prevent the write stream buffer from getting overfull.

* Instances of this class read bytes from a {@link com.arangodb.shaded.vertx.core.streams.ReadStream} and write them to a {@link com.arangodb.shaded.vertx.core.streams.WriteStream}. If data * can be read faster than it can be written this could result in the write queue of the {@link com.arangodb.shaded.vertx.core.streams.WriteStream} growing * without bound, eventually causing it to exhaust all available RAM.

* To prevent this, after each write, instances of this class check whether the write queue of the {@link * com.arangodb.shaded.vertx.core.streams.WriteStream} is full, and if so, the {@link com.arangodb.shaded.vertx.core.streams.ReadStream} is paused, and a {@code drainHandler} is set on the * {@link com.arangodb.shaded.vertx.core.streams.WriteStream}. When the {@link com.arangodb.shaded.vertx.core.streams.WriteStream} has processed half of its backlog, the {@code drainHandler} will be * called, which results in the pump resuming the {@link com.arangodb.shaded.vertx.core.streams.ReadStream}.

* This class can be used to pump from any {@link com.arangodb.shaded.vertx.core.streams.ReadStream} to any {@link com.arangodb.shaded.vertx.core.streams.WriteStream}, * e.g. from an {@link com.arangodb.shaded.vertx.core.http.HttpServerRequest} to an {@link com.arangodb.shaded.vertx.core.file.AsyncFile}, * or from {@link com.arangodb.shaded.vertx.core.net.NetSocket} to a {@link com.arangodb.shaded.vertx.core.http.WebSocket}.

* * Instances of this class are not thread-safe.

* * @author Tim Fox */ public class PumpImpl implements Pump { private final ReadStream readStream; private final WriteStream writeStream; private final Handler dataHandler; private final Handler drainHandler; private int pumped; /** * Create a new {@code Pump} with the given {@code ReadStream} and {@code WriteStream}. Set the write queue max size * of the write stream to {@code maxWriteQueueSize} */ public PumpImpl(ReadStream rs, WriteStream ws, int maxWriteQueueSize) { this(rs, ws); this.writeStream.setWriteQueueMaxSize(maxWriteQueueSize); } public PumpImpl(ReadStream rs, WriteStream ws) { Objects.requireNonNull(rs); Objects.requireNonNull(ws); this.readStream = rs; this.writeStream = ws; drainHandler = v-> readStream.resume(); dataHandler = data -> { writeStream.write(data); incPumped(); if (writeStream.writeQueueFull()) { readStream.pause(); writeStream.drainHandler(drainHandler); } }; } /** * Set the write queue max size to {@code maxSize} */ @Override public PumpImpl setWriteQueueMaxSize(int maxSize) { writeStream.setWriteQueueMaxSize(maxSize); return this; } /** * Start the Pump. The Pump can be started and stopped multiple times. */ @Override public PumpImpl start() { readStream.handler(dataHandler); return this; } /** * Stop the Pump. The Pump can be started and stopped multiple times. */ @Override public PumpImpl stop() { writeStream.drainHandler(null); readStream.handler(null); return this; } /** * Return the total number of elements pumped by this pump. */ @Override public synchronized int numberPumped() { return pumped; } // Note we synchronize as numberPumped can be called from a different thread however incPumped will always // be called from the same thread so we benefit from bias locked optimisation which should give a very low // overhead private synchronized void incPumped() { pumped++; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy