Merge pull request #1370 from akka/wip-starter-∂π

add akka.Main and use that to add Hello World docs
This commit is contained in:
Roland Kuhn 2013-05-02 04:28:27 -07:00
commit 117d91e0ed
11 changed files with 254 additions and 2 deletions

View file

@ -0,0 +1,42 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package akka
import akka.actor.ActorSystem
import akka.actor.ExtendedActorSystem
import akka.actor.Actor
import akka.actor.Terminated
import akka.actor.ActorLogging
import akka.actor.Props
import akka.actor.ActorRef
import scala.util.control.NonFatal
object Main {
def main(args: Array[String]): Unit = {
if (args.length != 1) {
println("you need to provide exactly one argument: the class of the application supervisor actor")
} else {
val system = ActorSystem("Main")
try {
val appClass = system.asInstanceOf[ExtendedActorSystem].dynamicAccess.getClassFor[Actor](args(0)).get
val app = system.actorOf(Props(appClass), "app")
val terminator = system.actorOf(Props(classOf[Terminator], app), "app-terminator")
} catch {
case NonFatal(e) system.shutdown(); throw e
}
}
}
class Terminator(app: ActorRef) extends Actor with ActorLogging {
context watch app
def receive = {
case Terminated(_)
log.info("application supervisor has terminated, shutting down")
context.system.shutdown()
}
}
}

View file

@ -115,6 +115,8 @@ directory.
More information is available in the documentation of the More information is available in the documentation of the
:ref:`microkernel-scala` / :ref:`microkernel-java`. :ref:`microkernel-scala` / :ref:`microkernel-java`.
.. _build-tool:
Using a build tool Using a build tool
------------------ ------------------

View file

@ -7,6 +7,7 @@ Introduction
what-is-akka what-is-akka
why-akka why-akka
getting-started getting-started
../java/hello-world
deployment-scenarios deployment-scenarios
use-cases use-cases

View file

@ -0,0 +1,13 @@
Introduction
============
.. toctree::
:maxdepth: 2
what-is-akka
why-akka
getting-started
../scala/hello-world
deployment-scenarios
use-cases

View file

@ -6,7 +6,7 @@ Java Documentation
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
intro/index intro/index-java
general/index general/index
java/index-actors java/index-actors
java/index-futures java/index-futures

View file

@ -0,0 +1,26 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package docs.actor.japi;
import akka.actor.UntypedActor;
import java.io.Serializable;
//#greeter
public class Greeter extends UntypedActor {
public static enum Msg {
GREET, DONE;
}
@Override
public void onReceive(Object msg) {
if (msg == Msg.GREET) {
System.out.println("Hello World!");
getSender().tell(Msg.DONE, getSelf());
} else unhandled(msg);
}
}
//#greeter

View file

@ -0,0 +1,31 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package docs.actor.japi;
//#hello-world
import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.actor.ActorRef;
public class HelloWorld extends UntypedActor {
@Override
public void preStart() {
// create the greeter actor
final ActorRef greeter =
getContext().actorOf(Props.create(Greeter.class), "greeter");
// tell it to perform the greeting
greeter.tell(Greeter.Msg.GREET, getSelf());
}
@Override
public void onReceive(Object msg) {
if (msg == Greeter.Msg.DONE) {
// when the greeter is done, stop this actor and with it the application
getContext().stop(getSelf());
} else unhandled(msg);
}
}
//#hello-world

View file

@ -0,0 +1,43 @@
##########################
The Obligatory Hello World
##########################
Since every programming paradigm needs to solve the tough problem of printing a
well-known greeting to the console well introduce you to the actor-based
version.
.. includecode:: ../java/code/docs/actor/japi/HelloWorld.java#hello-world
The ``HelloWorld`` actor is the applications “main” class; when it terminates
the application will shut down—more on that later. The main business logic
happens in the :meth:`preStart` method, where a ``Greeter`` actor is created
and instructed to issue that greeting we crave for. When the greeter is done it
will tell us so by sending back a message, and when that message has been
received it will be passed into the :meth:`onReceive` method where we can
conclude the demonstration by stopping the ``HelloWorld`` actor. You will be
very curious to see how the ``Greeter`` actor performs the actual task:
.. includecode:: ../java/code/docs/actor/japi/Greeter.java#greeter
This is extremely simple now: after its creation this actor will not do
anything until someone sends it a message, and if that happens to be an
invitation to greet the world then the ``Greeter`` complies and informs the
requester that the deed has been done.
As a Java developer you will probably want to tell us that there is no
``static public void main(...)`` anywhere in these classes, so how do we run
this program? The answer is that the appropriate :meth:`main` method is
implemented in the generic launcher class :class:`akka.Main` which expects only
one command line argument: the class name of the applications main actor. This
main method will then create the infrastructure needed for running the actors,
start the given main actor and arrange for the whole application to shut down
once the main actor terminates. Thus you will be able to run the above code
with a command similar to the following::
java -classpath <all those JARs> akka.Main com.example.HelloWorld
This conveniently assumes placement of the above class definitions in package
``com.example`` and it further assumes that you have the required JAR files for
``scala-library`` and ``akka-actor`` available. The easiest would be to manage
these dependencies with a build tool, see :ref:`build-tool`.

View file

@ -6,7 +6,7 @@ Scala Documentation
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
intro/index intro/index-scala
general/index general/index
scala/index-actors scala/index-actors
scala/index-futures scala/index-futures

View file

@ -0,0 +1,50 @@
/**
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
*/
package docs.actor
import akka.testkit.AkkaSpec
//#hello-world
import akka.actor.Actor
import akka.actor.Props
class HelloWorld extends Actor {
override def preStart(): Unit = {
// create the greeter actor
val greeter = context.actorOf(Props[Greeter], "greeter")
// tell it to perform the greeting
greeter ! Greeter.Greet
}
def receive = {
// when the greeter is done, stop this actor and with it the application
case Greeter.Done context.stop(self)
}
}
//#hello-world
//#greeter
object Greeter {
case object Greet
case object Done
}
class Greeter extends Actor {
def receive = {
case Greeter.Greet
println("Hello World!")
sender ! Greeter.Done
}
}
//#greeter
class IntroDocSpec extends AkkaSpec {
"demonstrate HelloWorld" in {
expectTerminated(watch(system.actorOf(Props[HelloWorld])))
}
}

View file

@ -0,0 +1,44 @@
##########################
The Obligatory Hello World
##########################
Since every programming paradigm needs to solve the tough problem of printing a
well-known greeting to the console well introduce you to the actor-based
version.
.. includecode:: ../scala/code/docs/actor/IntroDocSpec.scala#hello-world
The ``HelloWorld`` actor is the applications “main” class; when it terminates
the application will shut down—more on that later. The main business logic
happens in the :meth:`preStart` method, where a ``Greeter`` actor is created
and instructed to issue that greeting we crave for. When the greeter is done it
will tell us so by sending back a message, and when that message has been
received it will be passed into the behavior described by the :meth:`receive`
method where we can conclude the demonstration by stopping the ``HelloWorld``
actor. You will be very curious to see how the ``Greeter`` actor performs the
actual task:
.. includecode:: ../scala/code/docs/actor/IntroDocSpec.scala#greeter
This is extremely simple now: after its creation this actor will not do
anything until someone sends it a message, and if that happens to be an
invitation to greet the world then the ``Greeter`` complies and informs the
requester that the deed has been done.
As a Scala developer you will probably want to tell us that there is no
``main(Array[String])`` method anywhere in these classes, so how do we run this
program? The answer is that the appropriate :meth:`main` method is implemented
in the generic launcher class :class:`akka.Main` which expects only one command
line argument: the class name of the applications main actor. This main method
will then create the infrastructure needed for running the actors, start the
given main actor and arrange for the whole application to shut down once the
main actor terminates. Thus you will be able to run the above code with a
command similar to the following::
java -classpath <all those JARs> akka.Main com.example.HelloWorld
This conveniently assumes placement of the above class definitions in package
``com.example`` and it further assumes that you have the required JAR files for
``scala-library`` and ``akka-actor`` available. The easiest would be to manage
these dependencies with a build tool, see :ref:`build-tool`.