2 * Copyright 2011 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
30 * The views and conclusions contained in the software and
31 * documentation are those of the authors and should not be
32 * interpreted as representing official policies, either expressed
33 * or implied, of GRNET S.A.
36 package gr.grnet.aquarium.actor
38 import com.ckkloverdos.props.Props
39 import akka.actor.ActorRef
40 import gr.grnet.aquarium.Configurable
41 import java.util.concurrent.ConcurrentHashMap
42 import gr.grnet.aquarium.util.Loggable
46 * All actors are provided locally.
48 * @author Christos KK Loverdos <loverdos@gmail.com>.
50 class SimpleLocalActorProvider extends ActorProvider with Configurable with Loggable {
51 private[this] val actorCache = new ConcurrentHashMap[ActorRole, ActorRef]
52 private[this] var _props: Props = _
54 def configure(props: Props): Unit = {
56 logger.info("Configured with props: %s".format(props))
60 // Start all actors that need to [be started]
61 val RolesToBeStarted = SimpleLocalActorProvider.RolesToBeStarted
62 logger.info("About to start actors for %s roles: %s".format(RolesToBeStarted.size, RolesToBeStarted))
63 for((role, index) <- RolesToBeStarted.zipWithIndex) {
65 logger.info("%s. Started actor for role %s".format(index + 1, role))
68 // Now that all actors have been started, send them some initialization code
69 val message = ActorProviderConfigured(this)
70 for(role <- RolesToBeStarted) {
73 logger.info("Configuring %s with %s".format(DispatcherRole, message))
74 actorForRole(DispatcherRole) ! message
76 logger.info("Configuring %s with %s".format(anyOtherRole, message))
77 actorForRole(anyOtherRole) ! message
81 logger.info("Started")
85 logger.info("Stopped")
88 private[this] def _fromCacheOrNew(role: ActorRole): ActorRef = {
89 actorCache.get(role) match {
91 val actorRef = akka.actor.Actor.actorOf(role.actorType).start()
92 actorCache.put(role, actorRef)
99 @throws(classOf[Exception])
100 def actorForRole(role: ActorRole, hints: Props = Props.empty) = {
101 // Currently, all actors are initialized to one instance
102 // and user actor are treated specially
105 _fromCacheOrNew(RESTRole)
106 case DispatcherRole ⇒
107 _fromCacheOrNew(DispatcherRole)
108 case UserActorManagerRole ⇒
109 _fromCacheOrNew(UserActorManagerRole)
111 // NOTE: This always creates a new actor and is intended to be called only
112 // from internal API that can manage the created actors.
113 // E.g. UserActorProvider knows how to manage multiple user actors and properly initialize them.
115 // Note that the returned actor is not initialized!
116 akka.actor.Actor.actorOf(UserActorRole.actorType).start()
118 throw new Exception("Cannot create actor for role %s".format(role))
123 object SimpleLocalActorProvider {
124 // Always set Dispatcher at the end.
125 final val RolesToBeStarted = List(
126 // ResourceProcessorRole,
128 UserActorManagerRole,
131 lazy val ActorClassByRole: Map[ActorRole, Class[_ <: AquariumActor]] =
132 RolesToBeStarted map { role ⇒
133 (role, role.actorType)
136 lazy val ActorRefByRole: Map[ActorRole, ActorRef] =
137 ActorClassByRole map { case (role, clazz) ⇒
138 (role, akka.actor.Actor.actorOf(clazz).start())