On Wednesday, February 5, 2014 5:32:54 PM UTC-8, Rajiv Kurian wrote:
>
> First things first can you make enough space for the actors. You might be 
> surprised by what you can do on a modern machine :) Of course this is a 
> non-answer. But this does force you to answer capacity planning questions 
> like:
>    i) How much state will each of these actors have i.e. how much memory 
> will each actor consume?
>   ii) How many actors can you potentially have in the system?
>  iii) How often do these actors receive msgs?
> This exercise will lead to an answer of the form : "I have enough memory 
> to represent X amount of actors but I need Y memory that I can dedicate to 
> these specific actors". If  Y > X then your problem is solved. If it's not 
> then the exercise really boils down to how do I keep around more state than 
> can fit in memory. I see a few options:
>
I meant: "I have need X memory to represent all of my actors and I have Y 
total memory".

>
> 1) You can turn your individual actors to "fat actors". You can make each 
> of them responsible for a certain % of leaf actors. You might get 
> significant savings from the aggregation of state (think one giant map vs 
> many small maps). Sometimes you might not. If you do get enough savings 
> where Y is not more than X, then you are in luck. Cons include not writing 
> things in an "object oriented" manner. You just figure out which ShardActor 
> to msg to when you need to reach a particular IndividualActor and it does 
> everything. Sharding logic is up to you and routers might assist. You can 
> keep a dedicated executionContext for these shard actors so you can isolate 
> and analyze their performance and parallelize appropriately.
>
Meant to say: If you do get enough savings such that Y > X, then you are in 
luck.

>
> 2) If there is no way to fit all actors in memory using (1)  then you have 
> to have a mechanism of deflating them and then inflating them again. No 
> magic here. This is like virtual memory - when you don't have enough memory 
> page out to disk. This ties to how you populate the state in each actor to 
> begin with. You could use files, databases, Akka persistence etc. What you 
> can do then is have one or more shard actors that control when actors are 
> serialized/deserialized. Pseudo-code:
>
> class ShardActor extends actor {
>   state...
>   def receive = {
>     case Msg(Id, payload) => {
>       if (activeDirectory contains Id) {
>         actor = activeDirectory get Id
>         Cancel any timer msg that requires us to shutdown this actor since 
> it is active.
>         actor.tell(payload, sender) // In case you want to preseve the 
> original sender
>         Start timer to send yourself a msg to ask this actor to shutdown.
>       } else {
>         create RealActor with id Id. The RealActor should be able to 
> inflate it's state from a database, filesystem or whatever.
>         actor.tell(payload, sender)
>         Start timer to send yourself a msg to ask this actor to shutdown.
>       }
>     }
>     case InactiveActorTimerMsg(Id) => {
>       // Timer for this actor has hit. It's been inactive for too long. 
> Send a msg to the actor to serialize itself and shut itself down.
>       actorRef = Directory get Id // Assume it's there. Use pattern 
> matching (Some, None) in real life etc etc.
>       Remove actorRef from activeDirectory.
>       actorRef ! SerializeAndShutYourSelfDown
>       // We assume that if the child actor cannot serialize itself, there 
> will be an exception
>       // and the ShardActor will handle it through its supervision 
> strategy.
>     }
> }
>
> On Tuesday, February 4, 2014 11:46:55 PM UTC-8, Roger Alsing wrote:
>>
>> Lets say we have the following senario
>>
>> * we have an unbounded number of entities
>> * each entity may only process one command at a time
>> * each entity only process a few messages occasionally and then idle for 
>> an undefined amount of time
>>
>> Spawning an actor for each entity would force us to keep atleast one 
>> actor per entity in memory all the time. which is expensive since the will 
>> mostly be idle.
>>
>> What would be the most idiomatic Akka way to deal with this?
>>
>> Should we instead add an entity Id to each message, and have a custom 
>> router that directs each message to a pool of actors and create an affinity 
>> between the entity id and the pooled actor?
>> e.g.
>>
>> someting like:
>> var poolIndex = ((IHaveId)message).Id.GetHashCode() % poolSize;
>>
>> This way, I could direct every message for a specific entity to the same 
>> underlying worker actor and thus prevent concurrency issues for this entity.
>> The worker actor could also fetch the entity on demand and then release 
>> it once the command completes.
>>
>> Are there other alternatives?
>>
>> //Roger
>>
>

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: http://akka.io/faq/
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to