Documentation improvements
* Re enabling Java tests in akka-docs (they were not run before) * Fixed bug #19764 * #19735 Rewrote every sample using the deprecated PushPullStage and friends using GraphStage * Pruned old unused graph images * Added missing graffle file for new graph images
This commit is contained in:
parent
8f3c5aa17f
commit
737991c01c
103 changed files with 1136 additions and 4749 deletions
|
|
@ -11,6 +11,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import akka.NotUsed;
|
||||
import akka.stream.javadsl.GraphDSL;
|
||||
import docs.AbstractJavaTest;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
|
@ -30,23 +31,24 @@ import scala.concurrent.duration.Duration;
|
|||
import scala.concurrent.duration.FiniteDuration;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
public class BidiFlowDocTest {
|
||||
public class BidiFlowDocTest extends AbstractJavaTest {
|
||||
|
||||
private static ActorSystem system;
|
||||
static ActorSystem system;
|
||||
static Materializer mat;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
system = ActorSystem.create("FlowDocTest");
|
||||
system = ActorSystem.create("FlowDocTest");
|
||||
mat = ActorMaterializer.create(system);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() {
|
||||
JavaTestKit.shutdownActorSystem(system);
|
||||
system = null;
|
||||
JavaTestKit.shutdownActorSystem(system);
|
||||
system = null;
|
||||
mat = null;
|
||||
}
|
||||
|
||||
final Materializer mat = ActorMaterializer.create(system);
|
||||
|
||||
//#codec
|
||||
static interface Message {}
|
||||
static class Ping implements Message {
|
||||
|
|
@ -132,58 +134,77 @@ public class BidiFlowDocTest {
|
|||
.append(bytes)
|
||||
.result();
|
||||
}
|
||||
|
||||
public static class FrameParser extends PushPullStage<ByteString, ByteString> {
|
||||
// this holds the received but not yet parsed bytes
|
||||
private ByteString stash = ByteString.empty();
|
||||
// this holds the current message length or -1 if at a boundary
|
||||
private int needed = -1;
|
||||
|
||||
|
||||
public static class FrameParser extends GraphStage<FlowShape<ByteString, ByteString>> {
|
||||
public Inlet<ByteString> in = Inlet.create("FrameParser.in");
|
||||
public Outlet<ByteString> out = Outlet.create("FrameParser.out");
|
||||
private FlowShape<ByteString, ByteString> shape = FlowShape.of(in, out);
|
||||
|
||||
@Override
|
||||
public SyncDirective onPull(Context<ByteString> ctx) {
|
||||
return run(ctx);
|
||||
public FlowShape<ByteString, ByteString> shape() {
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncDirective onPush(ByteString bytes, Context<ByteString> ctx) {
|
||||
stash = stash.concat(bytes);
|
||||
return run(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TerminationDirective onUpstreamFinish(Context<ByteString> ctx) {
|
||||
if (stash.isEmpty()) return ctx.finish();
|
||||
else return ctx.absorbTermination(); // we still have bytes to emit
|
||||
}
|
||||
|
||||
private SyncDirective run(Context<ByteString> ctx) {
|
||||
if (needed == -1) {
|
||||
// are we at a boundary? then figure out next length
|
||||
if (stash.size() < 4) return pullOrFinish(ctx);
|
||||
else {
|
||||
needed = stash.iterator().getInt(ByteOrder.LITTLE_ENDIAN);
|
||||
stash = stash.drop(4);
|
||||
return run(ctx); // cycle back to possibly already emit the next chunk
|
||||
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
|
||||
return new GraphStageLogic(shape) {
|
||||
|
||||
// this holds the received but not yet parsed bytes
|
||||
private ByteString stash = ByteString.empty();
|
||||
// this holds the current message length or -1 if at a boundary
|
||||
private int needed = -1;
|
||||
|
||||
{
|
||||
setHandler(in, new AbstractInHandler() {
|
||||
@Override
|
||||
public void onPush() throws Exception {
|
||||
ByteString bytes = grab(in);
|
||||
stash = stash.concat(bytes);
|
||||
run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpstreamFinish() throws Exception {
|
||||
if (stash.isEmpty()) completeStage();
|
||||
// wait with completion and let run() complete when the
|
||||
// rest of the stash has been sent downstream
|
||||
}
|
||||
});
|
||||
|
||||
setHandler(out, new AbstractOutHandler() {
|
||||
@Override
|
||||
public void onPull() throws Exception {
|
||||
if (isClosed(in)) run();
|
||||
else pull(in);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (stash.size() < needed) {
|
||||
// we are in the middle of a message, need more bytes
|
||||
return pullOrFinish(ctx);
|
||||
} else {
|
||||
// we have enough to emit at least one message, so do it
|
||||
final ByteString emit = stash.take(needed);
|
||||
stash = stash.drop(needed);
|
||||
needed = -1;
|
||||
return ctx.push(emit);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* After having called absorbTermination() we cannot pull any more, so if we need
|
||||
* more data we will just have to give up.
|
||||
*/
|
||||
private SyncDirective pullOrFinish(Context<ByteString> ctx) {
|
||||
if (ctx.isFinishing()) return ctx.finish();
|
||||
else return ctx.pull();
|
||||
|
||||
private void run() {
|
||||
if (needed == -1) {
|
||||
// are we at a boundary? then figure out next length
|
||||
if (stash.size() < 4) {
|
||||
if (isClosed(in)) completeStage();
|
||||
else pull(in);
|
||||
} else {
|
||||
needed = stash.iterator().getInt(ByteOrder.LITTLE_ENDIAN);
|
||||
stash = stash.drop(4);
|
||||
run(); // cycle back to possibly already emit the next chunk
|
||||
}
|
||||
} else if (stash.size() < needed) {
|
||||
// we are in the middle of a message, need more bytes
|
||||
// or in is already closed and we cannot pull any more
|
||||
if (isClosed(in)) completeStage();
|
||||
else pull(in);
|
||||
} else {
|
||||
// we have enough to emit at least one message, so do it
|
||||
final ByteString emit = stash.take(needed);
|
||||
stash = stash.drop(needed);
|
||||
needed = -1;
|
||||
push(out, emit);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -192,7 +213,7 @@ public class BidiFlowDocTest {
|
|||
final FlowShape<ByteString, ByteString> top =
|
||||
b.add(Flow.of(ByteString.class).map(BidiFlowDocTest::addLengthHeader));
|
||||
final FlowShape<ByteString, ByteString> bottom =
|
||||
b.add(Flow.of(ByteString.class).transform(() -> new FrameParser()));
|
||||
b.add(Flow.of(ByteString.class).via(new FrameParser()));
|
||||
return BidiShape.fromFlows(top, bottom);
|
||||
}));
|
||||
//#framing
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue