Flat project hierarchy
[aquarium] / src / main / scala / gr / grnet / aquarium / user / actor / UserActorManager.scala
1 /*
2  * Copyright 2011 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *
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.
16  *
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.
29  *
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.
34  */
35
36 package gr.grnet.aquarium.user.actor
37
38 import gr.grnet.aquarium.util.Loggable
39 import akka.actor.ActorRef
40 import gr.grnet.aquarium.actor._
41 import gr.grnet.aquarium.processor.actor.UserRequestGetBalance
42
43
44 /**
45  * Responsible for the management of user actors.
46  *
47  * The rest of the application should send UserActor-related requests
48  * to this actor and not to a UserActor directly, since UserActors are
49  * managed entities. For example, how many UserActor are currently live
50  * in Aquarium is managed by UserActorManager
51  *
52  * Any UserActor-related request sent here is properly forwarded to
53  * the intended UserActor.
54  *
55  * @author Christos KK Loverdos <loverdos@gmail.com>
56  */
57
58 class UserActorManager extends AquariumActor with Loggable {
59   // TODO: Get the constructor values from configuration
60   private[this] val userActorLRU = new UserActorsLRU(1000, 800)
61   @volatile
62   private[this] var _actorProvider: ActorProvider = _
63   
64   def role = UserActorManagerRole
65
66   private[this] def _launchUserActor(userId: String): ActorRef = {
67     // create a fresh instance
68     val userActor = _actorProvider.actorForRole(UserActorRole)
69     userActor ! UserActorInitWithUserId(userId)
70     userActor ! ActorProviderConfigured(this._actorProvider)
71     userActor
72   }
73
74   protected def receive = {
75     case m @ ActorProviderConfigured(actorProvicer) ⇒
76       this._actorProvider = actorProvicer
77       logger.info("Configured %s with %s".format(this, m))
78
79     case m @ UserRequestGetBalance(userId, timestamp) ⇒
80       logger.debug("Received %s".format(m))
81       userActorLRU.get(userId) match {
82         case Some(userActor) ⇒
83           logger.debug("Found user actor and forwarding request %s".format(m))
84           userActor forward m
85         case None ⇒
86           logger.debug("Not found user actor for userId = %s. Launching new actor".format(userId))
87           val userActor = _launchUserActor(userId)
88           logger.debug("Launched new user actor and forwarding request %s".format(m))
89           userActor forward m
90       }
91   }
92 }