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:
Johan Andrén 2016-02-11 16:39:25 +01:00
parent 8f3c5aa17f
commit 737991c01c
103 changed files with 1136 additions and 4749 deletions

View file

@ -5,15 +5,11 @@ package docs.stream.javadsl.cookbook;
import akka.NotUsed;
import akka.actor.ActorSystem;
import akka.stream.ActorMaterializer;
import akka.stream.Materializer;
import akka.stream.*;
import akka.stream.javadsl.Flow;
import akka.stream.javadsl.Sink;
import akka.stream.javadsl.Source;
import akka.stream.stage.Context;
import akka.stream.stage.PushPullStage;
import akka.stream.stage.PushStage;
import akka.stream.stage.SyncDirective;
import akka.stream.stage.*;
import akka.testkit.JavaTestKit;
import akka.util.ByteString;
import org.junit.AfterClass;
@ -24,6 +20,7 @@ import scala.Tuple2;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
@ -31,19 +28,21 @@ import static org.junit.Assert.assertTrue;
public class RecipeByteStrings extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeByteStrings");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
final Source<ByteString, NotUsed> rawBytes = Source.from(Arrays.asList(
ByteString.fromArray(new byte[] { 1, 2 }),
@ -57,42 +56,77 @@ public class RecipeByteStrings extends RecipeTest {
final int CHUNK_LIMIT = 2;
//#bytestring-chunker
class Chunker extends PushPullStage<ByteString, ByteString> {
class Chunker extends GraphStage<FlowShape<ByteString, ByteString>> {
private final int chunkSize;
private ByteString buffer = ByteString.empty();
public Inlet<ByteString> in = Inlet.<ByteString>create("Chunker.in");
public Outlet<ByteString> out = Outlet.<ByteString>create("Chunker.out");
private FlowShape<ByteString, ByteString> shape = FlowShape.of(in, out);
public Chunker(int chunkSize) {
this.chunkSize = chunkSize;
}
@Override
public SyncDirective onPush(ByteString elem, Context<ByteString> ctx) {
buffer = buffer.concat(elem);
return emitChunkOrPull(ctx);
public FlowShape<ByteString, ByteString> shape() {
return shape;
}
@Override
public SyncDirective onPull(Context<ByteString> ctx) {
return emitChunkOrPull(ctx);
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new GraphStageLogic(shape) {
private ByteString buffer = ByteString.empty();
{
setHandler(out, new AbstractOutHandler(){
@Override
public void onPull() throws Exception {
if (isClosed(in)) emitChunk();
else pull(in);
}
});
setHandler(in, new AbstractInHandler() {
@Override
public void onPush() throws Exception {
ByteString elem = grab(in);
buffer = buffer.concat(elem);
emitChunk();
}
@Override
public void onUpstreamFinish() throws Exception {
if (buffer.isEmpty()) completeStage();
// elements left in buffer, keep accepting downstream pulls
// and push from buffer until buffer is emitted
}
});
}
private void emitChunk() {
if (buffer.isEmpty()) {
if (isClosed(in)) completeStage();
else pull(in);
} else {
Tuple2<ByteString, ByteString> split = buffer.splitAt(chunkSize);
ByteString chunk = split._1();
buffer = split._2();
push(out, chunk);
}
}
};
}
public SyncDirective emitChunkOrPull(Context<ByteString> ctx) {
if (buffer.isEmpty()) {
return ctx.pull();
} else {
Tuple2<ByteString, ByteString> split = buffer.splitAt(chunkSize);
ByteString emit = split._1();
buffer = split._2();
return ctx.push(emit);
}
}
}
//#bytestring-chunker
{
//#bytestring-chunker2
Source<ByteString, NotUsed> chunksStream =
rawBytes.transform(() -> new Chunker(CHUNK_LIMIT));
rawBytes.via(new Chunker(CHUNK_LIMIT));
//#bytestring-chunker2
CompletionStage<List<ByteString>> chunksFuture = chunksStream.limit(10).runWith(Sink.seq(), mat);
@ -119,22 +153,49 @@ public class RecipeByteStrings extends RecipeTest {
final int SIZE_LIMIT = 9;
//#bytes-limiter
class ByteLimiter extends PushStage<ByteString, ByteString> {
class ByteLimiter extends GraphStage<FlowShape<ByteString, ByteString>> {
final long maximumBytes;
private int count = 0;
public Inlet<ByteString> in = Inlet.<ByteString>create("ByteLimiter.in");
public Outlet<ByteString> out = Outlet.<ByteString>create("ByteLimiter.out");
private FlowShape<ByteString, ByteString> shape = FlowShape.of(in, out);
public ByteLimiter(long maximumBytes) {
this.maximumBytes = maximumBytes;
}
@Override
public SyncDirective onPush(ByteString chunk, Context<ByteString> ctx) {
count += chunk.size();
if (count > maximumBytes) {
return ctx.fail(new IllegalStateException("Too much bytes"));
} else {
return ctx.push(chunk);
}
public FlowShape<ByteString, ByteString> shape() {
return shape;
}
@Override
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new GraphStageLogic(shape) {
private int count = 0;
{
setHandler(out, new AbstractOutHandler() {
@Override
public void onPull() throws Exception {
pull(in);
}
});
setHandler(in, new AbstractInHandler() {
@Override
public void onPush() throws Exception {
ByteString chunk = grab(in);
count += chunk.size();
if (count > maximumBytes) {
failStage(new IllegalStateException("Too much bytes"));
} else {
push(out, chunk);
}
}
});
}
};
}
}
//#bytes-limiter
@ -142,7 +203,7 @@ public class RecipeByteStrings extends RecipeTest {
{
//#bytes-limiter2
Flow<ByteString, ByteString, NotUsed> limiter =
Flow.of(ByteString.class).transform(() -> new ByteLimiter(SIZE_LIMIT));
Flow.of(ByteString.class).via(new ByteLimiter(SIZE_LIMIT));
//#bytes-limiter2
final Source<ByteString, NotUsed> bytes1 = Source.from(Arrays.asList(
@ -167,11 +228,12 @@ public class RecipeByteStrings extends RecipeTest {
boolean thrown = false;
try {
bytes2.via(limiter).limit(10).runWith(Sink.seq(), mat).toCompletableFuture().get(3, TimeUnit.SECONDS);
} catch (IllegalStateException ex) {
} catch (ExecutionException ex) {
assertEquals(ex.getCause().getClass(), IllegalStateException.class);
thrown = true;
}
assertTrue("Expected IllegalStateException to be thrown", thrown);
}
};
}
@ -187,7 +249,7 @@ public class RecipeByteStrings extends RecipeTest {
ByteString.fromArray(new byte[] { 7, 8, 9 })));
//#compacting-bytestrings
Source<ByteString, NotUsed> compacted = rawBytes.map(bs -> bs.compact());
Source<ByteString, NotUsed> compacted = rawBytes.map(ByteString::compact);
//#compacting-bytestrings
List<ByteString> got = compacted.limit(10).runWith(Sink.seq(), mat).toCompletableFuture().get(3, TimeUnit.SECONDS);

View file

@ -5,14 +5,10 @@ package docs.stream.javadsl.cookbook;
import akka.NotUsed;
import akka.actor.ActorSystem;
import akka.stream.ActorMaterializer;
import akka.stream.Materializer;
import akka.stream.*;
import akka.stream.javadsl.Sink;
import akka.stream.javadsl.Source;
import akka.stream.stage.Context;
import akka.stream.stage.PushPullStage;
import akka.stream.stage.SyncDirective;
import akka.stream.stage.TerminationDirective;
import akka.stream.stage.*;
import akka.testkit.JavaTestKit;
import akka.util.ByteString;
import org.junit.AfterClass;
@ -21,6 +17,7 @@ import org.junit.Test;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
@ -28,54 +25,84 @@ import static org.junit.Assert.assertEquals;
public class RecipeDigest extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeDigest");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
//#calculating-digest
class DigestCalculator extends GraphStage<FlowShape<ByteString, ByteString>> {
private final String algorithm;
public Inlet<ByteString> in = Inlet.<ByteString>create("DigestCalculator.in");
public Outlet<ByteString> out = Outlet.<ByteString>create("DigestCalculator.out");
private FlowShape<ByteString, ByteString> shape = FlowShape.of(in, out);
public DigestCalculator(String algorithm) {
this.algorithm = algorithm;
}
@Override
public FlowShape<ByteString, ByteString> shape() {
return shape;
}
@Override
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new GraphStageLogic(shape) {
final MessageDigest digest;
{
try {
digest = MessageDigest.getInstance(algorithm);
} catch(NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
setHandler(out, new AbstractOutHandler() {
@Override
public void onPull() throws Exception {
pull(in);
}
});
setHandler(in, new AbstractInHandler() {
@Override
public void onPush() throws Exception {
ByteString chunk = grab(in);
digest.update(chunk.toArray());
pull(in);
}
@Override
public void onUpstreamFinish() throws Exception {
// If the stream is finished, we need to emit the digest
// before completing
emit(out, ByteString.fromArray(digest.digest()));
completeStage();
}
});
}
};
}
}
//#calculating-digest
@Test
public void work() throws Exception {
new JavaTestKit(system) {
//#calculating-digest
public PushPullStage<ByteString, ByteString> digestCalculator(String algorithm)
throws NoSuchAlgorithmException {
return new PushPullStage<ByteString, ByteString>() {
final MessageDigest digest = MessageDigest.getInstance(algorithm);
@Override
public SyncDirective onPush(ByteString chunk, Context<ByteString> ctx) {
digest.update(chunk.toArray());
return ctx.pull();
}
@Override
public SyncDirective onPull(Context<ByteString> ctx) {
if (ctx.isFinishing()) {
return ctx.pushAndFinish(ByteString.fromArray(digest.digest()));
} else {
return ctx.pull();
}
}
@Override
public TerminationDirective onUpstreamFinish(Context<ByteString> ctx) {
// If the stream is finished, we need to emit the last element in the onPull block.
// It is not allowed to directly emit elements from a termination block
// (onUpstreamFinish or onUpstreamFailure)
return ctx.absorbTermination();
}
};
}
//#calculating-digest
{
Source<ByteString, NotUsed> data = Source.from(Arrays.asList(
@ -84,7 +111,7 @@ public class RecipeDigest extends RecipeTest {
//#calculating-digest2
final Source<ByteString, NotUsed> digest = data
.transform(() -> digestCalculator("SHA-256"));
.via(new DigestCalculator("SHA-256"));
//#calculating-digest2
ByteString got = digest.runWith(Sink.head(), mat).toCompletableFuture().get(3, TimeUnit.SECONDS);

View file

@ -20,20 +20,21 @@ import java.util.concurrent.CompletionStage;
public class RecipeDroppyBroadcast extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeLoggingElements");
system = ActorSystem.create("RecipeDroppyBroadcast");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
@Test
public void work() throws Exception {
new JavaTestKit(system) {

View file

@ -22,20 +22,21 @@ import static org.junit.Assert.assertEquals;
public class RecipeFlattenList extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeFlattenList");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
@Test
public void workWithMapConcat() throws Exception {
new JavaTestKit(system) {

View file

@ -32,20 +32,21 @@ import static junit.framework.TestCase.assertTrue;
public class RecipeGlobalRateLimit extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeGlobalRateLimit");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
static
//#global-limiter-actor
public class Limiter extends AbstractActor {

View file

@ -5,20 +5,17 @@ package docs.stream.javadsl.cookbook;
import akka.actor.ActorSystem;
import akka.japi.Pair;
import akka.stream.ActorMaterializer;
import akka.stream.Materializer;
import akka.stream.*;
import akka.stream.javadsl.Keep;
import akka.stream.javadsl.Sink;
import akka.stream.javadsl.Source;
import akka.stream.stage.DetachedContext;
import akka.stream.stage.DetachedStage;
import akka.stream.stage.DownstreamDirective;
import akka.stream.stage.UpstreamDirective;
import akka.stream.stage.*;
import akka.stream.testkit.TestPublisher;
import akka.stream.testkit.TestSubscriber;
import akka.stream.testkit.javadsl.TestSink;
import akka.stream.testkit.javadsl.TestSource;
import akka.testkit.JavaTestKit;
import akka.util.ByteString;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -28,64 +25,112 @@ import java.util.concurrent.TimeUnit;
public class RecipeHold extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeMultiGroupBy");
system = ActorSystem.create("RecipeHold");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
//#hold-version-1
class HoldWithInitial<T> extends DetachedStage<T, T> {
private T currentValue;
class HoldWithInitial<T> extends GraphStage<FlowShape<T, T>> {
public Inlet<T> in = Inlet.<T>create("HoldWithInitial.in");
public Outlet<T> out = Outlet.<T>create("HoldWithInitial.out");
private FlowShape<T, T> shape = FlowShape.of(in, out);
private final T initial;
public HoldWithInitial(T initial) {
currentValue = initial;
this.initial = initial;
}
@Override
public UpstreamDirective onPush(T elem, DetachedContext<T> ctx) {
currentValue = elem;
return ctx.pull();
public FlowShape<T, T> shape() {
return shape;
}
@Override
public DownstreamDirective onPull(DetachedContext<T> ctx) {
return ctx.push(currentValue);
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new GraphStageLogic(shape) {
private T currentValue = initial;
{
setHandler(in, new AbstractInHandler() {
@Override
public void onPush() throws Exception {
currentValue = grab(in);
pull(in);
}
});
setHandler(out, new AbstractOutHandler() {
@Override
public void onPull() throws Exception {
push(out, currentValue);
}
});
}
@Override
public void preStart() {
pull(in);
}
};
}
}
//#hold-version-1
//#hold-version-2
class HoldWithWait<T> extends DetachedStage<T, T> {
private T currentValue = null;
private boolean waitingFirstValue = true;
class HoldWithWait<T> extends GraphStage<FlowShape<T, T>> {
public Inlet<T> in = Inlet.<T>create("HoldWithInitial.in");
public Outlet<T> out = Outlet.<T>create("HoldWithInitial.out");
private FlowShape<T, T> shape = FlowShape.of(in, out);
@Override
public UpstreamDirective onPush(T elem, DetachedContext<T> ctx) {
currentValue = elem;
waitingFirstValue = false;
if (ctx.isHoldingDownstream()) {
return ctx.pushAndPull(currentValue);
} else {
return ctx.pull();
}
public FlowShape<T, T> shape() {
return shape;
}
@Override
public DownstreamDirective onPull(DetachedContext<T> ctx) {
if (waitingFirstValue) {
return ctx.holdDownstream();
} else {
return ctx.push(currentValue);
}
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new GraphStageLogic(shape) {
private T currentValue = null;
private boolean waitingFirstValue = true;
{
setHandler(in, new AbstractInHandler() {
@Override
public void onPush() throws Exception {
currentValue = grab(in);
if (waitingFirstValue) {
waitingFirstValue = false;
if (isAvailable(out)) push(out, currentValue);
}
pull(in);
}
});
setHandler(out, new AbstractOutHandler() {
@Override
public void onPull() throws Exception {
if (!waitingFirstValue) push(out, currentValue);
}
});
}
@Override
public void preStart() {
pull(in);
}
};
}
}
//#hold-version-2
@ -98,7 +143,7 @@ public class RecipeHold extends RecipeTest {
final Sink<Integer, TestSubscriber.Probe<Integer>> sink = TestSink.probe(system);
Pair<TestPublisher.Probe<Integer>, TestSubscriber.Probe<Integer>> pubSub =
source.transform(() -> new HoldWithInitial<>(0)).toMat(sink, Keep.both()).run(mat);
source.via(new HoldWithInitial<>(0)).toMat(sink, Keep.both()).run(mat);
TestPublisher.Probe<Integer> pub = pubSub.first();
TestSubscriber.Probe<Integer> sub = pubSub.second();
@ -126,7 +171,7 @@ public class RecipeHold extends RecipeTest {
final Sink<Integer, TestSubscriber.Probe<Integer>> sink = TestSink.probe(system);
Pair<TestPublisher.Probe<Integer>, TestSubscriber.Probe<Integer>> pubSub =
source.transform(() -> new HoldWithWait<>()).toMat(sink, Keep.both()).run(mat);
source.via(new HoldWithWait<>()).toMat(sink, Keep.both()).run(mat);
TestPublisher.Probe<Integer> pub = pubSub.first();
TestSubscriber.Probe<Integer> sub = pubSub.second();

View file

@ -18,20 +18,21 @@ import java.util.concurrent.TimeUnit;
public class RecipeKeepAlive extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeKeepAlive");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
class Tick {}
public final Tick TICK = new Tick();

View file

@ -25,20 +25,21 @@ import java.util.Arrays;
public class RecipeLoggingElements extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeLoggingElements", ConfigFactory.parseString("akka.loglevel=DEBUG\nakka.loggers = [akka.testkit.TestEventListener]"));
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
@Test
public void workWithPrintln() throws Exception {
new JavaTestKit(system) {

View file

@ -22,20 +22,21 @@ import java.util.concurrent.TimeUnit;
public class RecipeManualTrigger extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeKeepAlive");
system = ActorSystem.create("RecipeManualTrigger");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
class Trigger {
}

View file

@ -29,20 +29,21 @@ import java.util.concurrent.TimeUnit;
public class RecipeMissedTicks extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeMultiGroupBy");
system = ActorSystem.create("RecipeMissedTicks");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
@Test
public void work() throws Exception {
new JavaTestKit(system) {

View file

@ -31,20 +31,21 @@ import static junit.framework.TestCase.assertTrue;
public class RecipeMultiGroupByTest extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeMultiGroupBy");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
static class Topic {
private final String name;

View file

@ -22,20 +22,21 @@ import java.util.concurrent.TimeUnit;
public class RecipeParseLines extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeLoggingElements");
system = ActorSystem.create("RecipeParseLines");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
@Test
public void parseLines() throws Exception {
final Source<ByteString, NotUsed> rawData = Source.from(Arrays.asList(

View file

@ -31,20 +31,21 @@ import java.util.stream.Collectors;
public class RecipeReduceByKeyTest extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeLoggingElements");
system = ActorSystem.create("RecipeReduceByKey");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
@Test
public void work() throws Exception {
new JavaTestKit(system) {

View file

@ -24,20 +24,20 @@ import java.util.concurrent.TimeUnit;
public class RecipeSeq extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeLoggingElements");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
@Test
public void drainSourceToList() throws Exception {
new JavaTestKit(system) {

View file

@ -25,20 +25,21 @@ import java.util.concurrent.TimeUnit;
public class RecipeSimpleDrop extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeSimpleDrop");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
@Test
public void work() throws Exception {
new JavaTestKit(system) {

View file

@ -1,6 +1,8 @@
package docs.stream.javadsl.cookbook;
public class RecipeTest {
import docs.AbstractJavaTest;
public abstract class RecipeTest extends AbstractJavaTest {
final class Message {
public final String msg;

View file

@ -24,20 +24,21 @@ import static org.junit.Assert.assertTrue;
public class RecipeWorkerPool extends RecipeTest {
static ActorSystem system;
static Materializer mat;
@BeforeClass
public static void setup() {
system = ActorSystem.create("RecipeWorkerPool");
mat = ActorMaterializer.create(system);
}
@AfterClass
public static void tearDown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
mat = null;
}
final Materializer mat = ActorMaterializer.create(system);
//#worker-pool
public static <In, Out> Flow<In, Out, NotUsed> balancer(
Flow<In, Out, NotUsed> worker, int workerCount) {