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.user.actor
38 import gr.grnet.aquarium.user.UserState
39 import gr.grnet.aquarium.util.Loggable
40 import gr.grnet.aquarium.processor.actor.{UserResponseGetBalance, UserRequestGetBalance}
41 import scala.PartialFunction
42 import gr.grnet.aquarium.actor._
43 import com.ckkloverdos.maybe.Maybe
48 * @author Christos KK Loverdos <loverdos@gmail.com>
51 class UserActor extends AquariumActor with Loggable {
53 private[this] var _userId: String = _
55 private[this] var _isInitialized: Boolean = false
57 private[this] var _userState: UserState = _
59 private[this] var _actorProvider: ActorProvider = _
61 def role = UserActorRole
63 protected def receive: Receive = {
67 case m @ UserActorInitWithUserId(userId) ⇒
69 this._isInitialized = true
70 // TODO: query DB etc to get internal state
71 logger.info("Setup my userId = %s".format(userId))
73 case m @ ActorProviderConfigured(actorProvider) ⇒
74 this._actorProvider = actorProvider
75 logger.info("Configured %s with %s".format(this, m))
77 case m @ UserRequestGetBalance(userId, timestamp) ⇒
78 if(this._userId != userId) {
79 logger.error("Received %s but my userId = %s".format(m, this._userId))
80 // TODO: throw an exception here
82 // This is the big party.
83 // Get the user state, if it exists and make sure it is not stale.
85 // Do we have a user state?
86 if(_userState ne null) {
87 // Yep, we do. See what there is inside it.
88 val credits = _userState.credits
89 val creditsTimestamp = credits.snapshotTime
91 // Check if data is stale
92 if(creditsTimestamp + 10000 > timestamp) {
94 self reply UserResponseGetBalance(userId, credits.data)
96 // Yep, data is stale and must recompute balance
98 logger.error("FIXME: Should have computed a new value for %s".format(credits))
99 self reply UserResponseGetBalance(userId, credits.data)
102 // Nope. No user state exists. Must reproduce one
104 logger.error("FIXME: Should have computed the user state for userId = %s".format(userId))
105 self reply UserResponseGetBalance(userId, Maybe(userId.toDouble).getOr(10.5))