diff --git a/akka-docs/build.sbt b/akka-docs/build.sbt index 807216f9a7..550b6d1943 100644 --- a/akka-docs/build.sbt +++ b/akka-docs/build.sbt @@ -32,7 +32,8 @@ paradoxProperties ++= Map( "google.analytics.account" -> "UA-21117439-1", "google.analytics.domain.name" -> "akka.io", "snip.code.base_dir" -> (sourceDirectory in Test).value.getAbsolutePath, - "snip.akka.base_dir" -> ((baseDirectory in Test).value / "..").getAbsolutePath + "snip.akka.base_dir" -> ((baseDirectory in Test).value / "..").getAbsolutePath, + "fiddle.code.base_dir" -> (sourceDirectory in Test).value.getAbsolutePath ) paradoxGroups := Map("Languages" -> Seq("Scala", "Java")) diff --git a/akka-docs/src/main/paradox/scala/actors.md b/akka-docs/src/main/paradox/scala/actors.md index 3e095b23f2..22dcee3cc5 100644 --- a/akka-docs/src/main/paradox/scala/actors.md +++ b/akka-docs/src/main/paradox/scala/actors.md @@ -78,6 +78,12 @@ for cases when the actor constructor takes value classes as arguments. @@@ +@@@ note { title=DIY } + +@@fiddle [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #fiddle_code height=400px extraParams=theme=light&layout=v75 cssStyle=width:100%; } + +@@@ + #### Dangerous Variants @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #creating-props-deprecated } @@ -245,7 +251,7 @@ In addition, it offers: * `self` reference to the `ActorRef` of the actor * `sender` reference sender Actor of the last received message, typically used as described in [Actor.Reply](#actor-reply) - * + * `supervisorStrategy` user overridable definition the strategy to use for supervising child actors This strategy is typically declared inside the actor in order to have access to the actor’s internal state within the decider function: since failure is @@ -255,7 +261,7 @@ within the actor are available, as is the `sender` reference (which will be the immediate child reporting the failure; if the original failure occurred within a distant descendant it is still reported one level up at a time). - * + * `context` exposes contextual information for the actor and the current message, such as: * factory methods to create child actors (`actorOf`) * system that the actor belongs to @@ -375,7 +381,7 @@ handling strategy. Actors may be restarted in case an exception is thrown while processing a message (see @ref:[supervision](general/supervision.md)). This restart involves the hooks mentioned above: - 1. + 1. The old actor is informed by calling `preRestart` with the exception which caused the restart and the message which triggered that exception; the latter may be `None` if the restart was not caused by processing a diff --git a/akka-docs/src/main/paradox/scala/stream/stream-quickstart.md b/akka-docs/src/main/paradox/scala/stream/stream-quickstart.md index 2594ae0212..259de5cb00 100644 --- a/akka-docs/src/main/paradox/scala/stream/stream-quickstart.md +++ b/akka-docs/src/main/paradox/scala/stream/stream-quickstart.md @@ -130,7 +130,7 @@ certain speed: we use the `throttle` combinator to slow down the stream to 1 element per second (the second `1` in the argument list is the maximum size of a burst that we want to allow—passing `1` means that the first element gets through immediately and the second then has to wait for one second and so -on). +on). If you run this program you will see one line printed per second. One aspect that is not immediately visible deserves mention, though: if you try and set @@ -241,6 +241,12 @@ whereas `flatMap` would have to operate on streams all the way through. @@@ +@@@ note { title=DIY } + +@@fiddle [TwitterStreamQuickstartDocSpec.scala]($code$/scala/docs/stream/TwitterStreamQuickstartDocSpec.scala) { #fiddle_code height=400px extraParams=theme=light&layout=v75 cssStyle=width:100%; } + +@@@ + ## Broadcasting a stream Now let's say we want to persist all hashtags, as well as all author names from this one live stream. @@ -347,4 +353,4 @@ what happens behind the scenes when we run this one-liner, which is equivalent t those appended by the `runWith()` itself. In the above example it translates to using `Keep.right` as the combiner for materialized values. -@@@ \ No newline at end of file +@@@ diff --git a/akka-docs/src/test/scala/docs/actor/ActorDocSpec.scala b/akka-docs/src/test/scala/docs/actor/ActorDocSpec.scala index 5f0344bcb8..a382b0099e 100644 --- a/akka-docs/src/test/scala/docs/actor/ActorDocSpec.scala +++ b/akka-docs/src/test/scala/docs/actor/ActorDocSpec.scala @@ -5,21 +5,29 @@ package docs.actor import jdocs.actor.ImmutableMessage +//#fiddle_code import language.postfixOps +//#fiddle_code +//#fiddle_code //#imports1 import akka.actor.Actor import akka.actor.Props +//#fiddle_code import akka.event.Logging //#imports1 import scala.concurrent.Future +//#fiddle_code import akka.actor.{ ActorRef, ActorSystem, PoisonPill, Terminated, ActorLogging } +//#fiddle_code import org.scalatest.{ BeforeAndAfterAll, WordSpec } import akka.testkit._ import akka.util._ +//#fiddle_code import scala.concurrent.duration._ +//#fiddle_code import scala.concurrent.Await import akka.Done import akka.actor.CoordinatedShutdown @@ -275,6 +283,38 @@ final case class Give(thing: Any) //#receive-orElse +//#fiddle_code + +case object Ping +case object Pong + +class Pinger extends Actor { + var countDown = 100 + + def receive = { + case Pong => + println(s"${self.path} received pong, count down $countDown") + + if (countDown > 0) { + countDown -= 1 + sender() ! Ping + } else { + sender() ! PoisonPill + self ! PoisonPill + } + } +} + +class Ponger(pinger: ActorRef) extends Actor { + def receive = { + case Ping => + println(s"${self.path} received ping") + pinger ! Pong + } +} + +//#fiddle_code + class ActorDocSpec extends AkkaSpec(""" akka.loglevel = INFO akka.loggers = [] @@ -322,6 +362,31 @@ class ActorDocSpec extends AkkaSpec(""" system.stop(myActor) } + "run basic Ping Pong" in { + //#fiddle_code + val system = ActorSystem("pingpong") + + val pinger = system.actorOf(Props[Pinger], "pinger") + + val ponger = system.actorOf(Props(classOf[Ponger], pinger), "ponger") + + //#fiddle_code + val testProbe = new TestProbe(system) + testProbe watch pinger + testProbe watch ponger + //#fiddle_code + import system.dispatcher + system.scheduler.scheduleOnce(500 millis) { + ponger ! Ping + } + +// $FiddleDependency org.akka-js %%% akkajsactor % 1.2.5.1 + //#fiddle_code + testProbe.expectTerminated(pinger) + testProbe.expectTerminated(ponger) + system.terminate() + } + "creating a Props config" in { //#creating-props import akka.actor.Props diff --git a/akka-docs/src/test/scala/docs/stream/TwitterStreamQuickstartDocSpec.scala b/akka-docs/src/test/scala/docs/stream/TwitterStreamQuickstartDocSpec.scala index e8628b9d84..3a21cf30cb 100644 --- a/akka-docs/src/test/scala/docs/stream/TwitterStreamQuickstartDocSpec.scala +++ b/akka-docs/src/test/scala/docs/stream/TwitterStreamQuickstartDocSpec.scala @@ -5,11 +5,12 @@ package docs.stream //#imports +//#fiddle_code import akka.{ Done, NotUsed } import akka.actor.ActorSystem import akka.stream.{ ClosedShape, ActorMaterializer, OverflowStrategy } import akka.stream.scaladsl._ - +//#fiddle_code import scala.concurrent.Await import scala.concurrent.Future @@ -18,6 +19,8 @@ import scala.concurrent.Future import akka.testkit.AkkaSpec object TwitterStreamQuickstartDocSpec { + //#fiddle_code + //#model final case class Author(handle: String) @@ -31,12 +34,15 @@ object TwitterStreamQuickstartDocSpec { val akkaTag = Hashtag("#akka") //#model + //#fiddle_code + abstract class TweetSourceDecl { //#tweet-source val tweets: Source[Tweet, NotUsed] //#tweet-source } + //#fiddle_code val tweets: Source[Tweet, NotUsed] = Source( Tweet(Author("rolandkuhn"), System.currentTimeMillis, "#akka rocks!") :: Tweet(Author("patriknw"), System.currentTimeMillis, "#akka !") :: @@ -49,6 +55,8 @@ object TwitterStreamQuickstartDocSpec { Tweet(Author("appleman"), System.currentTimeMillis, "#apples rock!") :: Tweet(Author("drama"), System.currentTimeMillis, "we compared #apples to #oranges!") :: Nil) + + //#fiddle_code } class TwitterStreamQuickstartDocSpec extends AkkaSpec { @@ -60,12 +68,15 @@ class TwitterStreamQuickstartDocSpec extends AkkaSpec { def println(s: Any): Unit = () trait Example1 { + //#fiddle_code //#first-sample //#materializer-setup implicit val system = ActorSystem("reactive-tweets") implicit val materializer = ActorMaterializer() //#materializer-setup //#first-sample + + //#fiddle_code } implicit val materializer = ActorMaterializer() @@ -133,6 +144,20 @@ class TwitterStreamQuickstartDocSpec extends AkkaSpec { // format: ON } + "simple fiddle showcase" in { + + //#fiddle_code + tweets + .filterNot(_.hashtags.contains(akkaTag)) + .mapConcat(_.hashtags) + .map(_.name.toUpperCase) + .runWith(Sink.foreach(println)) + + // $FiddleDependency org.akka-js %%% akkajsactorstream % 1.2.5.1 + //#fiddle_code + .value + } + "slowProcessing" in { def slowComputation(t: Tweet): Long = { Thread.sleep(500) // act as if performing some heavy computation