diff --git a/akka-core/pom.xml b/akka-core/pom.xml index a414d69740..2bfc0e3b68 100644 --- a/akka-core/pom.xml +++ b/akka-core/pom.xml @@ -4,7 +4,7 @@ 4.0.0 akka-core - Akka Actors, Remote Actors, Transactors and STM Module + Akka Core - Actors, Remote Actors, Transactors and STM Module jar diff --git a/akka-core/src/main/scala/remote/RemoteServer.scala b/akka-core/src/main/scala/remote/RemoteServer.scala index 315d6b8e49..5b8e1f3e1b 100755 --- a/akka-core/src/main/scala/remote/RemoteServer.scala +++ b/akka-core/src/main/scala/remote/RemoteServer.scala @@ -43,7 +43,7 @@ import org.jboss.netty.handler.codec.compression.{ZlibEncoder, ZlibDecoder} * * @author Jonas Bonér */ -object RemoteNode extends RemoteServer(true) +object RemoteNode extends RemoteServer /** * This object holds configuration variables. @@ -88,7 +88,8 @@ object RemoteServer { } private val remoteActorSets = new ConcurrentHashMap[Address, RemoteActorSet] - + private val remoteServers = new ConcurrentHashMap[Address, RemoteServer] + def actorsFor(remoteServerAddress: RemoteServer.Address): RemoteActorSet = { val set = remoteActorSets.get(remoteServerAddress) if (set ne null) set @@ -98,6 +99,20 @@ object RemoteServer { remoteActorSet } } + + def serverFor(hostname: String, port: Int): Option[RemoteServer] = { + val server = remoteServers.get(Address(hostname, port)) + if (server eq null) None + else Some(server) + } + + private[remote] def register(hostname: String, port: Int, server: RemoteServer) = + remoteServers.put(Address(hostname, port), server) + + private[remote] def unregister(hostname: String, port: Int) = + remoteServers.remove(Address(hostname, port)) + + private[remote] def canShutDownCluster: Boolean = remoteServers.isEmpty } /** @@ -116,9 +131,8 @@ object RemoteServer { * * @author Jonas Bonér */ -class RemoteServer(val registerNodeInCluster: Boolean) extends Logging { +class RemoteServer extends Logging { val name = "RemoteServer@" + hostname + ":" + port - def this() = this(false) private var hostname = RemoteServer.HOSTNAME private var port = RemoteServer.PORT @@ -147,6 +161,7 @@ class RemoteServer(val registerNodeInCluster: Boolean) extends Logging { hostname = _hostname port = _port log.info("Starting remote server at [%s:%s]", hostname, port) + RemoteServer.register(hostname, port, this) val remoteActorSet = RemoteServer.actorsFor(RemoteServer.Address(hostname, port)) val pipelineFactory = new RemoteServerPipelineFactory(name, openChannels, loader, remoteActorSet.actors, remoteActorSet.activeObjects) bootstrap.setPipelineFactory(pipelineFactory) @@ -156,7 +171,7 @@ class RemoteServer(val registerNodeInCluster: Boolean) extends Logging { bootstrap.setOption("child.connectTimeoutMillis", RemoteServer.CONNECTION_TIMEOUT_MILLIS) openChannels.add(bootstrap.bind(new InetSocketAddress(hostname, port))) isRunning = true - if (registerNodeInCluster) Cluster.registerLocalNode(hostname, port) + Cluster.registerLocalNode(hostname, port) } } catch { case e => log.error(e, "Could not start up remote server") @@ -164,14 +179,13 @@ class RemoteServer(val registerNodeInCluster: Boolean) extends Logging { } def shutdown = { + RemoteServer.unregister(hostname, port) openChannels.disconnect openChannels.unbind openChannels.close.awaitUninterruptibly(1000) bootstrap.releaseExternalResources - if (registerNodeInCluster) { - Cluster.deregisterLocalNode(hostname, port) - Cluster.shutdown - } + Cluster.deregisterLocalNode(hostname, port) + if (RemoteServer.canShutDownCluster) Cluster.shutdown } } diff --git a/akka-samples/akka-sample-chat/README b/akka-samples/akka-sample-chat/README index 57084eeef6..47ee2601f2 100644 --- a/akka-samples/akka-sample-chat/README +++ b/akka-samples/akka-sample-chat/README @@ -1,11 +1,28 @@ Akka Chat Client/Server Sample Application -To run the sample: -1. Run 'mvn install' (builds and deploys jar to AKKA_HOME/deploy) -2. In another shell run 'java -jar ./dist/akka-0.6.jar' to start up Akka microkernel -3. In the first shell run 'mvn scala:console -o' -4. In the REPL you get execute: - - scala> import se.scalablesolutions.akka.sample.chat._ - - scala> Runner.run -5. See the chat simulation run -6. Run it again to see full speed after first initialization +First we need to download, build and start up Redis: + +1. Download Redis from http://code.google.com/p/redis/downloads/list. +2. Step into the distribution. +3. Build: ‘make install’. +4. Run: ‘./redis-server’. +For details on how to set up Redis server have a look at http://code.google.com/p/redis/wiki/QuickStart. + +Then to run the sample: + +1. Set ‘AKKA_HOME’ environment variable to the root of the Akka distribution. +2. Open up a shell and step into the Akka distribution root folder. +3. Build Akka by invoking ‘mvn install -Dmaven.test.skip=true’. This will also bulid the sample application and deploy it to the ‘$AKKA_HOME/deploy’ directory. +4. Run the microkernel + export AKKA_HOME=... + cd $AKKA_HOME + java -jar ./dist/akka-0.6.jar +5. Now start up a new shell and go down into the ‘./akka-samples/akka-sample-chat’ directory. +6. Invoke ‘mvn scala:console -o’. This will give you a Scala REPL (interpreter) with the chat application and all its dependency JARs on the classpath. +7. Simply paste in the whole code block with the ‘Runner’ object above and invoke ‘Runner.run’. This run a simulated client session that will connect to the running server in the microkernel. +8. Invoke ‘Runner.run’ again and again… + +Now you could test client reconnect by killing the running microkernel and start it up again. See the client reconnect take place in the REPL shell. + +That’s it. Have fun. + diff --git a/akka-samples/akka-sample-chat/src/main/scala/ChatServer.scala b/akka-samples/akka-sample-chat/src/main/scala/ChatServer.scala index 952c291cfe..9528ad4da7 100644 --- a/akka-samples/akka-sample-chat/src/main/scala/ChatServer.scala +++ b/akka-samples/akka-sample-chat/src/main/scala/ChatServer.scala @@ -187,7 +187,6 @@ object ChatService extends * Test runner emulating a chat session. */ object Runner { - // create a handle to the remote ChatService ChatService.makeRemote("localhost", 9999) ChatService.start diff --git a/akka-util/src/main/scala/Config.scala b/akka-util/src/main/scala/Config.scala index 75228f3631..f7a204f650 100644 --- a/akka-util/src/main/scala/Config.scala +++ b/akka-util/src/main/scala/Config.scala @@ -53,12 +53,12 @@ object Config extends Logging { log.info("Config loaded from the application classpath.") } catch { case e: ParseException => throw new IllegalStateException( - "Can't find 'akka.conf' configuration file." + - "One of the three ways of locating the 'akka.conf' file needs to be defined:" + - "\n\t1. Define '$AKKA_HOME' to the root of the Akka distribution." + - "\n\t2. Define the '-Dakka.config=...' environment option." + + "\nCan't find 'akka.conf' configuration file." + + "\nOne of the three ways of locating the 'akka.conf' file needs to be defined:" + + "\n\t1. Define 'AKKA_HOME' environment variable to the root of the Akka distribution." + + "\n\t2. Define the '-Dakka.config=...' system property option." + "\n\t3. Put the 'akka.conf' file on the classpath." + - "\n\tI have no way of finding the 'akka.conf' configuration file." + + "\nI have no way of finding the 'akka.conf' configuration file." + "\nAborting.") } } diff --git a/pom.xml b/pom.xml index f405169c8e..adc0fa961b 100755 --- a/pom.xml +++ b/pom.xml @@ -508,8 +508,6 @@ - - release