use of co.paralleluniverse.strands.channels.Channel in project quasar by puniverse.
the class PipelineTest method testPipeline.
@Test
public void testPipeline() throws Exception {
final Channel<Integer> i = newChannel();
final Channel<Integer> o = newChannel();
final Pipeline<Integer, Integer> p = new Pipeline<>(i, o, new SuspendableAction2<Integer, Channel<Integer>>() {
@Override
public void call(final Integer i, final Channel<Integer> out) throws SuspendExecution, InterruptedException {
out.send(i + 1);
out.close();
}
}, parallelism);
final Fiber<Long> pf = new Fiber("pipeline", scheduler, p).start();
final Fiber receiver = new Fiber("receiver", scheduler, new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
final Integer m1 = o.receive();
final Integer m2 = o.receive();
final Integer m3 = o.receive();
final Integer m4 = o.receive();
assertThat(m1, notNullValue());
assertThat(m2, notNullValue());
assertThat(m3, notNullValue());
assertThat(m4, notNullValue());
assertThat(ImmutableSet.of(m1, m2, m3, m4), equalTo(ImmutableSet.of(2, 3, 4, 5)));
try {
pf.join();
} catch (ExecutionException ex) {
// It should never happen
throw new AssertionError(ex);
}
// This is needed, else `isClosed` could return false
assertNull(o.tryReceive());
// Can be used reliably only in owner (receiver)
assertTrue(o.isClosed());
}
}).start();
i.send(1);
i.send(2);
i.send(3);
i.send(4);
i.close();
// Join pipeline
long transferred = pf.get();
assertThat(transferred, equalTo(p.getTransferred()));
assertThat(transferred, equalTo(4l));
receiver.join();
}
use of co.paralleluniverse.strands.channels.Channel in project quasar by puniverse.
the class Pipeline method parallelTransfer.
private void parallelTransfer() throws SuspendExecution, InterruptedException {
// 1) Fire workers
for (int i = 0; i < parallelism; i++) {
strandFactory.newStrand(SuspendableUtils.runnableToCallable(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
// Get first job
Pair<S, Channel<Channel<T>>> job = jobs.receive();
while (job != null) {
// Build result channel
final Channel<T> res = resultChannelBuilder.run();
// Process
transformer.call(job.getFirst(), res);
final Channel<Channel<T>> resWrapper = job.getSecond();
// Send result asynchronously
strandFactory.newStrand(SuspendableUtils.runnableToCallable(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
resWrapper.send(res);
}
})).start();
// Get next job
job = jobs.receive();
}
// No more jobs, close results channel and quit worker
results.close();
}
})).start();
}
// 2) Send jobs asynchronously
strandFactory.newStrand(SuspendableUtils.runnableToCallable(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
// Get first input
S s = from.receive();
while (s != null) {
final Channel<Channel<T>> resultWrapper = Channels.newChannel(1, Channels.OverflowPolicy.BLOCK, true, true);
jobs.send(new Pair<>(s, resultWrapper));
results.send(resultWrapper);
// Get next input
s = from.receive();
}
// No more inputs, close jobs channel and quit
jobs.close();
}
})).start();
// 3) Collect and transfer results asynchronously
try {
final Strand collector = strandFactory.newStrand(SuspendableUtils.runnableToCallable(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
// Get first result
Channel<Channel<T>> resWrapper = results.receive();
while (resWrapper != null) {
// Get wrapper
Channel<T> res = resWrapper.receive();
// Get first actual result
T out = res.receive();
while (out != null) {
// Send to output channel
to.send(out);
// Increment counter
transferred.incrementAndGet();
// Get next result
out = res.receive();
}
resWrapper = results.receive();
}
// No more results, quit
}
})).start();
// TODO solve nasty instrumentation problems on Strand.join()
if (collector.isFiber()) {
Fiber f = (Fiber) collector.getUnderlying();
f.join();
} else
collector.join();
} catch (ExecutionException ee) {
throw new AssertionError(ee);
}
}
Aggregations