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

io.jsync.streams.Pump Maven / Gradle / Ivy

There is a newer version: 1.10.13
Show newest version
/*
 * Copyright (c) 2011-2013 The original author or authors
 * ------------------------------------------------------
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution.
 *
 *     The Eclipse Public License is available at
 *     http://www.eclipse.org/legal/epl-v10.html
 *
 *     The Apache License v2.0 is available at
 *     http://www.opensource.org/licenses/apache2.0.php
 *
 * You may elect to redistribute this code under either of these licenses.
 */

package io.jsync.streams;

import io.jsync.Handler;
import io.jsync.buffer.Buffer;

/**
 * Pumps data from a {@link ReadStream} to a {@link 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 ReadStream} and write them to a {@link WriteStream}. If data * can be read faster than it can be written this could result in the write queue of the {@link 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 * WriteStream} is full, and if so, the {@link ReadStream} is paused, and a {@code drainHandler} is set on the * {@link WriteStream}. When the {@link WriteStream} has processed half of its backlog, the {@code drainHandler} will be * called, which results in the pump resuming the {@link ReadStream}.

* This class can be used to pump from any {@link ReadStream} to any {@link WriteStream}, * e.g. from an {@link io.jsync.http.HttpServerRequest} to an {@link io.jsync.file.AsyncFile}, * or from {@link io.jsync.net.NetSocket} to a {@link io.jsync.http.WebSocket}.

*

* Instances of this class are not thread-safe.

* * @author Tim Fox */ public class Pump { private final ReadStream readStream; private final WriteStream writeStream; private final Handler drainHandler = new Handler() { public void handle(Void v) { readStream.resume(); } }; private int pumped; private final Handler dataHandler = new Handler() { public void handle(Buffer buffer) { writeStream.write(buffer); pumped += buffer.length(); if (writeStream.writeQueueFull()) { readStream.pause(); writeStream.drainHandler(drainHandler); } } }; /** * 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} */ private Pump(ReadStream rs, WriteStream ws, int maxWriteQueueSize) { this(rs, ws); this.writeStream.setWriteQueueMaxSize(maxWriteQueueSize); } private Pump(ReadStream rs, WriteStream ws) { this.readStream = rs; this.writeStream = ws; } /** * Create a new {@code Pump} with the given {@code ReadStream} and {@code WriteStream} */ public static Pump createPump(ReadStream rs, WriteStream ws) { return new Pump(rs, ws); } /** * Create a new {@code Pump} with the given {@code ReadStream} and {@code WriteStream} and * {@code writeQueueMaxSize} */ public static Pump createPump(ReadStream rs, WriteStream ws, int writeQueueMaxSize) { return new Pump(rs, ws, writeQueueMaxSize); } /** * Set the write queue max size to {@code maxSize} */ public Pump setWriteQueueMaxSize(int maxSize) { this.writeStream.setWriteQueueMaxSize(maxSize); return this; } /** * Start the Pump. The Pump can be started and stopped multiple times. */ public Pump start() { readStream.dataHandler(dataHandler); return this; } /** * Stop the Pump. The Pump can be started and stopped multiple times. */ public Pump stop() { writeStream.drainHandler(null); readStream.dataHandler(null); return this; } /** * Return the total number of bytes pumped by this pump. */ public int bytesPumped() { return pumped; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy