/* * Copyright (C) 2015 Typesafe Inc. */ package docs.stream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.DoubleStream; import java.util.stream.Stream; import akka.NotUsed; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; import akka.actor.ActorSystem; import akka.japi.Pair; import akka.japi.tuple.Tuple3; import akka.stream.*; import akka.stream.javadsl.*; 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.testkit.TestLatch; import scala.collection.Iterator; import scala.concurrent.Await; import scala.concurrent.Future; import scala.concurrent.duration.Duration; import scala.util.Random; public class RateTransformationDocTest { private static ActorSystem system; @BeforeClass public static void setup() { system = ActorSystem.create("RateTransformationDocTest"); } @AfterClass public static void tearDown() { JavaTestKit.shutdownActorSystem(system); system = null; } final Materializer mat = ActorMaterializer.create(system); final Random r = new Random(); @Test public void conflateShouldSummarize() throws Exception { //#conflate-summarize final Flow, NotUsed> statsFlow = Flow.of(Double.class) .conflate(elem -> Collections.singletonList(elem), (acc, elem) -> { return Stream .concat(acc.stream(), Collections.singletonList(elem).stream()) .collect(Collectors.toList()); }) .map(s -> { final Double mean = s.stream().mapToDouble(d -> d).sum() / s.size(); final DoubleStream se = s.stream().mapToDouble(x -> Math.pow(x - mean, 2)); final Double stdDev = Math.sqrt(se.sum() / s.size()); return new Tuple3<>(stdDev, mean, s.size()); }); //#conflate-summarize final Future>> fut = Source.repeat(0).map(i -> r.nextGaussian()) .via(statsFlow) .grouped(10) .runWith(Sink.head(), mat); final Duration timeout = Duration.create(100, TimeUnit.MILLISECONDS); Await.result(fut, timeout); } @Test public void conflateShouldSample() throws Exception { //#conflate-sample final Double p = 0.01; final Flow sampleFlow = Flow.of(Double.class) .conflate(elem -> Collections.singletonList(elem), (acc, elem) -> { if (r.nextDouble() < p) { return Stream .concat(acc.stream(), Collections.singletonList(elem).stream()) .collect(Collectors.toList()); } return acc; }) .mapConcat(d -> d); //#conflate-sample final Future fut = Source.from(new ArrayList(Collections.nCopies(1000, 1.0))) .via(sampleFlow) .runWith(Sink.fold(0.0, (agg, next) -> agg + next), mat); final Duration timeout = Duration.create(1, TimeUnit.SECONDS); final Double count = Await.result(fut, timeout); } @Test public void expandShouldRepeatLast() throws Exception { //#expand-last final Flow lastFlow = Flow.of(Double.class) .expand(in -> Stream.iterate(in, i -> i).iterator()); //#expand-last final Pair, Future>> probeFut = TestSource. probe(system) .via(lastFlow) .grouped(10) .toMat(Sink.head(), Keep.both()) .run(mat); final TestPublisher.Probe probe = probeFut.first(); final Future> fut = probeFut.second(); probe.sendNext(1.0); final Duration timeout = Duration.create(1, TimeUnit.SECONDS); final List expanded = Await.result(fut, timeout); assertEquals(expanded.size(), 10); assertEquals(expanded.stream().mapToDouble(d -> d).sum(), 10, 0.1); } @Test public void expandShouldTrackDrift() throws Exception { @SuppressWarnings("unused") //#expand-drift final Flow, NotUsed> driftFlow = Flow.of(Double.class) .expand(d -> Stream.iterate(0, i -> i + 1).map(i -> new Pair<>(d, i)).iterator()); //#expand-drift final TestLatch latch = new TestLatch(2, system); final Flow, NotUsed> realDriftFlow = Flow.of(Double.class) .expand(d -> { latch.countDown(); return Stream.iterate(0, i -> i + 1).map(i -> new Pair<>(d, i)).iterator(); }); final Pair, TestSubscriber.Probe>> pubSub = TestSource. probe(system) .via(realDriftFlow) .toMat(TestSink.> probe(system), Keep.both()) .run(mat); final TestPublisher.Probe pub = pubSub.first(); final TestSubscriber.Probe> sub = pubSub.second(); sub.request(1); pub.sendNext(1.0); sub.expectNext(new Pair<>(1.0, 0)); sub.requestNext(new Pair<>(1.0, 1)); sub.requestNext(new Pair<>(1.0, 2)); pub.sendNext(2.0); Await.ready(latch, Duration.create(1, TimeUnit.SECONDS)); sub.requestNext(new Pair<>(2.0, 0)); } }