![JAR search and dependency download from the Maven repository](/logo.png)
io.nextop.wire.Pipe Maven / Gradle / Ivy
package io.nextop.wire;
import io.nextop.Wire;
import io.nextop.Wires;
import rx.Observable;
import rx.subjects.BehaviorSubject;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Queue;
// provides two wire factories, a and b, such that a wire created in a produces an available wire in b (and vice-versa)
// the pair of wires write to each other, via a buffer of similar size to a tcp window (65k)
public final class Pipe {
final Object mutex = new Object();
final PairedWireFactory a;
final PairedWireFactory b;
final BehaviorSubject aSubject;
final BehaviorSubject bSubject;
public Pipe() {
aSubject = BehaviorSubject.create();
bSubject = BehaviorSubject.create();
a = new PairedWireFactory(mutex);
b = new PairedWireFactory(mutex);
a.pair = b;
a.pairSubject = bSubject;
b.pair = a;
b.pairSubject = aSubject;
}
public Wire.Factory getA() {
return a;
}
public Wire.Factory getB() {
return b;
}
// published whenever a wire is available on A
// create() is not guaranteed to return; but with careful planning it will
public Observable observeA() {
return aSubject;
}
public Observable observeB() {
return bSubject;
}
static final class PairedWireFactory implements Wire.Factory {
final Object mutex;
final Queue wireQueue = new LinkedList();
PairedWireFactory pair;
BehaviorSubject pairSubject;
PairedWireFactory(Object mutex) {
this.mutex = mutex;
}
@Override
public Wire create(@Nullable Wire replace) throws InterruptedException, NoSuchElementException {
Wire wire;
synchronized (mutex) {
// 1. check if the pair created one
wire = wireQueue.poll();
if (null != wire) {
return wire;
}
// 2. create a pair
Wire a = Wires.transfer();
Wire b = Wires.transfer();
wire = new PairWire(a, b);
pair.wireQueue.add(new PairWire(b, a));
}
pairSubject.onNext(pair);
return wire;
}
}
static final class PairWire implements Wire {
private final Wire in;
private final Wire out;
PairWire(Wire in, Wire out) {
this.in = in;
this.out = out;
}
@Override
public void close() throws IOException {
try {
in.close();
} finally {
out.close();
}
}
@Override
public void read(byte[] buffer, int offset, int length, int messageBoundary) throws IOException {
in.read(buffer, offset, length, messageBoundary);
}
@Override
public void skip(long n, int messageBoundary) throws IOException {
in.skip(n, messageBoundary);
}
@Override
public void write(byte[] buffer, int offset, int length, int messageBoundary) throws IOException {
out.write(buffer, offset, length, messageBoundary);
}
@Override
public void flush() throws IOException {
out.flush();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy