0
Akka:
                               Simpler Scalability, Fault-tolerance,
                                       Concurre...
State
                                 2
Wednesday, December 30, 2009
The devil is in
                                 the state



                                      3
Wednesday, December ...
Wrong,
                               let me rephrase



                                      4
Wednesday, December 30, 2...
The devil is in
                      the      mutable state
                                      5
Wednesday, December 3...
Definitions
                                    &
                               Philosophy
                               ...
What is a Value?
                               A Value is something that
                                does not change
...
What is an Identity?
                                A stable logical entity
                                   associated...
What is State?
                                   The Value
                                an entity with a
             ...
How do we know if
                   something has State?
                            If a function is invoked with
      ...
The Problem
                                 The   unification Of
                Identity & Value
                        ...
We need to separate Identity & Value
    ...add a level of indirection
    Software Transactional Memory
            Manag...
The problems with
                   Shared State
                   Concurrency

Wednesday, December 30, 2009
Shared-State Concurrency
   > Concurrent access to shared, mutable state.
   > Protect mutable state with locks
   > The
 ...
Shared-State
                               Concurrency is
                               incredibly hard
     > Inherentl...
Example of
  Shared-State Concurrency
                                   Transfer funds
                               bet...
Account
                    public
class
Account
{


                    

private
int
balance;


                    

pu...
Let’s make it thread-safe
      public
class
Account
{


      

private
int
balance;


      

public
synchronized
void
w...
It’s still broken
         Transfers are not atomic


Wednesday, December 30, 2009
Let’s write an
                           atomic transfer method
               public
class
Account
{
               

.....
Let’s transfer funds
                 Account
alice
=
...


                 Account
bob
=
...


                 


     ...
Might lead to
                               DEADLOCK
                               Darn, this is really hard!!!




Wedn...
We need to enforce lock ordering
   > How?
   > Javawon’t help us
   > Need to use code convention (names etc.)
   > Requi...
The problem with locks
      Locks do not compose
      Taking too few locks
      Taking too many locks
      Taking the ...
It’s just
                               too hard

Wednesday, December 30, 2009
Java bet on the
                                wrong horse?
                                     Perhaps,
               ...
We need better
                                 and more
                                 high-level
                     ...
Alternative Paradigms
   >Software Transactional
                         Memory (STM)
   >Message-Passing Concurrency (Ac...
Actors
Wednesday, December 30, 2009
Actors
    • Originates in a 1973 paper by Carl
      Hewitt
    • Implemented in Erlang, Occam, Oz
    • Encapsulates sta...
Alan Kay
                  (father of SmallTalk and OOP)
                               “OOP to me means only messaging,
 ...
Actors
    • Implements Message-Passing Concurrency
    • Share NOTHING
    • Isolated lightweight processes
    • Communi...
Actor Model of
                                Concurrency
    • No shared state
       … hence, nothing to synchronize.
 ...
Actor Model of
                                Concurrency
    • Non-blocking send
    • Blocking receive
    • Messages a...
Actor Model of
                                Concurrency
    • Easier to reason about
    • Raised abstraction level
   ...
Akka Actors
    • Asynchronous
      –Fire-and-forget
      –Futures (Send Receive Reply Eventually)
    • Synchronous
   ...
Two different models
             • Thread-based
             • Event-based
               –Very lightweight
             ...
Actor libs for the JVM
         > Akka  (Java/Scala)
         > Kilim (Java)
         > Jetlang (Java)
         > Actor’s ...
Fault tolerance & Scalablility
                  Akka Transactors
                   Supervisor hierarchies
              ...
Actors
                               case
object
Tick

                               class
Counter
extends
Actor
{
     ...
Actors
                                   anonymous
                               val
worker
=
actor
{
                  ...
Actors
                                   anonymous
                               val
worker
=
actor
{
                  ...
Send: !
                               //
fire‐forget

                               counter
!
Tick





Wednesday, Decem...
Reply
                     class
SomeActor
extends
Actor
{
                     

def
receive
=
{
                     


...
Reply
                        class
SomeActor
extends
Actor
{
                        

def
receive
=
{
                  ...
Send: !!
             //
uses
Future
with
default
timeout
             val
resultOption
=
actor
!!
Message
             va...
Reply
                       class
SomeActor
extends
Actor
{
                       

def
receive
=
{
                    ...
Reply
              class
SomeActor
extends
Actor
{
              

def
receive
=
{
              



case
User(name)
=>

...
Start / Stop
      actor.start
      actor.stop

      spawn(classOf[MyActor])

      //
callback
      override
def
shutd...
Active Objects: Java
              public
class
Counter
{
              

private
int
counter
=
0;
              

public
...
Create: POJO

      Counter
counter
=
(Counter)ActiveObject
      

.newInstance(Counter.class,
1000);




Wednesday, Dece...
Create:
                    Interface & Implementation

      Counter
counter
=
(Counter)ActiveObject
      

.newInstance...
Active Objects
                      class
Counter
{
                      

private
var
counter
=
0
                     ...
Create: POSO

           val
counter
=
ActiveObject.newInstance(
           



classOf[Counter],
1000)




Wednesday, Dec...
Send

                               counter.count




Wednesday, December 30, 2009
@oneway
                      class
Counter
{
                      

private
var
counter
=
0
                      

@one...
Immutable messages
               //
define
the
case
class
               case
class
Register(user:
User)

               ...
Actors: config
                 <akka>
                 

version
=
"0.6"
                 

<actor>
                 



t...
Akka Dispatchers


Wednesday, December 30, 2009
Dispatchers
        class
Dispatchers
{
        

def
newThreadBasedDispatcher(actor:
Actor)

        

def
newExecutorBas...
Set dispatcher
     class
MyActor
extends
Actor
{
     

dispatcher
=
Dispatchers
     



.newThreadBasedDispatcher(this)...
EventBasedDispatcher
                               Fluent DSL
    val
dispatcher
=
    

Dispatchers.newExecutorBasedEven...
When to use which
                 dispatcher?


Wednesday, December 30, 2009
Thread-based actors
        • One thread per Actor
        • Good:
         • Threads (actors) don’t block each other
    ...
Event-based actors
         • Backed by thread pool
         • Lightweight:
          • Can create millions of Actors
    ...
Single threaded event-based actors

         • Best performance
         • Millions of Actors
         • Bad:
           •...
MessageQueues
                      Unbounded LinkedBlockingQueue
                        Bounded LinkedBlockingQueue
    ...
Akka Supervision


Wednesday, December 30, 2009
Stolen from

                               Erlang
Wednesday, December 30, 2009
9   nines
Wednesday, December 30, 2009
Supervisor hierarchies
            OneForOne




Wednesday, December 30, 2009
Supervisor hierarchies
             AllForOne




Wednesday, December 30, 2009
Fault handlers
                               AllForOneStrategy(
                               

maxNrOfRetries,

       ...
Linking
                 link(actor)

                 unlink(actor)


                 startLink(actor)
                 ...
trapExit
           trapExit
=
List(
           
classOf[ServiceException],

           
classOf[PersistenceException])


...
Supervision
                class
Supervisor
extends
Actor
{
                

trapExit
=
List(classOf[Throwable])
       ...
Manage failure
          class
FaultTolerant
extends
Actor
{
          

...
          

override
def
preRestart(reason:
A...
Declarative config
          RestartStrategy(
          

AllForOne,


//
restart
policy

          

10,









//
max
#...
Declarative config
                  object
factory
extends
SupervisorFactory(
                  

SupervisorConfig(
      ...
ActorRegistry
            val
actors
=

            

ActorRegistry.actorsFor(FQN)

            val
actors
=

            ...
Initialize actor
                               override
def
init
=
{
                               

...
//
init
the
act...
Akka Remote Actors


Wednesday, December 30, 2009
Remote Server
              //
use
host
&
port
in
config
              RemoteNode.start
              RemoteNode.start(cla...
Remote Server
                 //
use
host
&
port
in
config
                 val
server
=
new
RemoteServer

              ...
Remote actors
        spawnRemote(classOf[MyActor],
host,
port)


        startLinkRemote(actor,
host,
port)

        spaw...
Remote config
                          <akka>
                          

<remote>
                          



service
=...
Akka STM

Wednesday, December 30, 2009
Software Transactional
          Memory (STM)


                               88
Wednesday, December 30, 2009
What is STM?

                               89
Wednesday, December 30, 2009
STM: overview
 > See  the memory (heap and stack) as a
   transactional dataset
 > Similar to a database
    begin

    ...
STM: overview
     > Transactions can nest
     > Transactions compose (yipee!!)
    


atomic
{



    




..



    


...
STM: restrictions
   >All   operations in scope of a
      transaction:
      
       Need to be idempotent
      
     ...
Akka STM
                               is based on the ideas of
                                     Clojure STM


      ...
2 things:
     1. Managed References
     2. Persistent Datastructures

                               94
Wednesday, Decem...
Managed References
     Typical OO - Direct
• Typical OO: direct Mutable Objects objects
     references to access to muta...
Managed References
     • Separates Identity from Value
        - Values are immutable
        - Identity (Ref) holds Valu...
Managed References
           val
ref
=
TransactionalState.newRef(
           

HashTrie[String,
User]())

           val
...
Managed References
                val
usersRef
=
TransactionalState.newRef(
                

HashTrie[String,
User]())

...
Managed References
                               for
{
                               

users
<‐
usersRef
               ...
Managed References
                      convenience classes
     //
wraps
a
Ref
with
a
HashTrie

     val
users
=
Transac...
Persistent
                               datastructures
        • Immutable
        • Change is a function
        • Old ...
Bit-partitioned hash trie
          Bit-partitioned hash tries




                               Copyright Rich Hickey 20...
Structural sharing
                                           with path copying
                                          ...
Persistent datastructures
ble



          HashTrie
oordination




       import
se.scalablesolutions.akka.collection._

...
Persistent datastructures
ble



           Vector
oordination




       import
se.scalablesolutions.akka.collection._

 ...
Akka STM
     • Transactional Memory
        - Atomic, Consistent, Isolated (ACI)
        - MVCC
        - Rolls back in m...
STM: declarative API
               class
UserRegistry
extends
Transactor
{
               


               

private
laz...
STM: declarative API
              class
UserRegistry
extends
Actor
{
              

makeTransactionRequired
            ...
STM: declarative Java API
                               @transactionrequired
                               class
UserReg...
STM: high-order fun API
    import
se.scalablesolutions.akka.stm.Transaction._

    atomic
{
    

..
//
do
something
with...
STM: high-order fun API

     import
se.scalablesolutions.akka.stm.Transaction._

     atomically
{
     

..
//
try
to
do...
STM: monadic API
                   val
userStorage
=

                   

TransactionalState.newMap[String,
User]

     ...
STM: monadic API
           val
userStorage
=

           

TransactionalState.newMap[String,
User]

           val
users
...
STM: config
                               <akka>
                               

<stm>
                               


...
STM: disable
                  TransactionManagement.disableTransactions




Wednesday, December 30, 2009
Akka Serialization


Wednesday, December 30, 2009
Serializers
                                  ScalaJSON
                                   JavaJSON
                      ...
Serializers
                        Scala 2 JSON & JSON 2 Scala

      val
foo
=
new
Foo
      val
json
=
Serializer.Scala...
Serializers
                    Scala 2 Binary & Binary 2 Scala

           import
sbinary.DefaultProtocol._

           v...
Serializers
                                  Protobuf
                val
pojo
=

                

ProtobufPOJO.getDefau...
Serializable
    case
class
MyMessage(
    

id:
String,

    

value:
Tuple2[String,
Int])

    

extends
Serializable.Sc...
Akka Persistence


Wednesday, December 30, 2009
Persistence
     • Pluggable storage backend
        - Cassandra
        - MongoDB
        - Redis
     • Map, Vector and ...
Akka Persistence API
                        //
transactional
Cassandra‐backed
Map

                        val
map
=
Cass...
Persistence: config
                               <akka>
                               

<storage>

                     ...
Akka’s Cassandra API
        val
sessions
=
new
CassandraSessionPool(
        



keyspace,
        



StackPool(SocketPr...
Akka Cassandra API
  //
get
a
column
  val
column
=
sessions.withSession
{
session
=>

  

session
|
(key,
new
ColumnPath(...
Akka Cassandra API
     //
add
a
column
     sessions.withSession
{
session
=>

     

session
++|

     



(key,

     
...
Akka REST


Wednesday, December 30, 2009
RESTful actors
                 @Path("/count")
                 class
Counter
extends
Actor
{
                 

private
...
REST: config
                     <akka>
                     

<rest>
                     



service
=
on
              ...
Boot classes
                  class
Boot
{
                  

object
factory
extends
SupervisorFactory(
                ...
Boot config
                   <akka>
                   

boot
=
["sample.rest.Boot",

                   









"sampl...
Akka Comet


Wednesday, December 30, 2009
Comet actors
                      • Based on Atmosphere project
                      • Portable
                      • ...
Comet actors
            @Path("/chat")
            class
Chat
extends
Actor
{
            

case
class
Chat(who:
String,
...
Akka Security


Wednesday, December 30, 2009
Security: service
     class
SampleAuthenticationService

     

extends
DigestAuthenticationActor
{

     

//
Use
an
in‐...
Security: usage
        class
SecuredActor
extends
Actor
{
        

@RolesAllowed(Array(“admin”))
        

def
resetSyst...
Security: config
       <akka>
       

<rest>
       



service
=
on
       



hostname
=
“localhost”
       



port
=
...
Akka Lift


Wednesday, December 30, 2009
Lift integration
       class
Boot
{
//
Lift’s
bootstrap
class
       

def
boot
{
       



LiftRules.httpAuthProtectedR...
Lift integration
              <web‐app>
              

<servlet>
              



<servlet‐name>AkkaServlet</servlet‐na...
Akka HotSwap


Wednesday, December 30, 2009
HotSwap
                               actor
!
HotSwap(Some({
                               

//
new
body
               ...
Akka AMQP


Wednesday, December 30, 2009
AMQP: producer
               val
producer
=
AMQP.newProducer(
               

config,

               

hostname,
port,
...
AMQP: consumer
                  val
consumer
=
AMQP.newConsumer(
                  

config,
hostname,
port,
exchangeName...
Akka Kernel


Wednesday, December 30, 2009
Start Kernel
             java
‐jar
akka‐0.6.jar

             

‐Dakka.config=<path>/akka.conf



                       ...
Akka Deployment


Wednesday, December 30, 2009
Akka as a library



          Using the Actor module
Wednesday, December 30, 2009
Akka as a library



                               Add STM module
Wednesday, December 30, 2009
Akka as a library



  Add Persistence module as a Cache
Wednesday, December 30, 2009
Akka as a library



     Add Persistence module as primary SoR
Wednesday, December 30, 2009
Akka as a library



           Add REST and Comet modules
Wednesday, December 30, 2009
Akka as
                  stand-alone Kernel




Wednesday, December 30, 2009
Logging
           <log>
           

console
=
on
           

filename
=
"./logs/akka.log"
           

roll
=
"daily"

...
Monitoring &
                               Management
                               Provisioning
                       ...
Learn more
                               http://akkasource.org




Wednesday, December 30, 2009
Professional help
      Consulting Training Mentoring

                         http://scalablesolutions.se
              ...
EOF
Wednesday, December 30, 2009
Upcoming SlideShare
Loading in...5
×

Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

18,170

Published on

Akka is the platform for the next generation event-driven, scalable and fault-tolerant architectures on the JVM

We believe that writing correct concurrent, fault-tolerant and scalable applications is too hard. Most of the time it's because we are using the wrong tools and the wrong level of abstraction.

Akka is here to change that.

Using the Actor Model together with Software Transactional Memory we raise the abstraction level and provides a better platform to build correct concurrent and scalable applications.

For fault-tolerance we adopt the "Let it crash" / "Embrace failure" model which have been used with great success in the telecom industry to build applications that self-heals, systems that never stop.

Actors also provides the abstraction for transparent distribution and the basis for truly scalable and fault-tolerant applications.

Akka is Open Source and available under the Apache 2 License.

Published in: Technology, Business
4 Comments
74 Likes
Statistics
Notes
  • Too difficult.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • great, but a question, if mutable state is the devil i see that the Actor has mutable state: class Counter extends Actor { private var counter = 0.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • cool slide, counter balances the ego of 'Concurrency for legacy languages'
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • good
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
18,170
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
752
Comments
4
Likes
74
Embeds 0
No embeds

No notes for slide

Transcript of "Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors"

  1. 1. Akka: Simpler Scalability, Fault-tolerance, Concurrency & Remoting through Actors http://akkasource.org Jonas Bonér Scalable Solutions AB Copyright 2009 - Scalable Solutions AB Wednesday, December 30, 2009
  2. 2. State 2 Wednesday, December 30, 2009
  3. 3. The devil is in the state 3 Wednesday, December 30, 2009
  4. 4. Wrong, let me rephrase 4 Wednesday, December 30, 2009
  5. 5. The devil is in the mutable state 5 Wednesday, December 30, 2009
  6. 6. Definitions & Philosophy 6 Wednesday, December 30, 2009
  7. 7. What is a Value? A Value is something that does not change Discussion based on http://clojure.org/state by Rich Hickey Wednesday, December 30, 2009
  8. 8. What is an Identity? A stable logical entity associated with a series of different Values over time Wednesday, December 30, 2009
  9. 9. What is State? The Value an entity with a specific Identity has at a particular point in time Wednesday, December 30, 2009
  10. 10. How do we know if something has State? If a function is invoked with the same arguments at two different points in time and returns different values... ...then it has state Wednesday, December 30, 2009
  11. 11. The Problem The unification Of Identity & Value They are not the same Wednesday, December 30, 2009
  12. 12. We need to separate Identity & Value ...add a level of indirection Software Transactional Memory Managed References Message-Passing Concurrency Actors/Active Objects Dataflow Concurrency Dataflow (Single-Assignment) Variables Wednesday, December 30, 2009
  13. 13. The problems with Shared State Concurrency Wednesday, December 30, 2009
  14. 14. Shared-State Concurrency > Concurrent access to shared, mutable state. > Protect mutable state with locks > The  Java  C#  C/C++  Ruby  Python  etc. Wednesday, December 30, 2009
  15. 15. Shared-State Concurrency is incredibly hard > Inherentlyvery hard to use reliably > Even the experts get it wrong Wednesday, December 30, 2009
  16. 16. Example of Shared-State Concurrency Transfer funds between bank accounts Wednesday, December 30, 2009
  17. 17. Account public
class
Account
{

 

private
int
balance;

 

public
void
withdraw(int
amount)
{
 



balance
‐=
amount;
 

}

 

public
void
deposit(int
amount)
{
 



balance
+=
amount;
 

}

 }
 Not thread-safe Wednesday, December 30, 2009
  18. 18. Let’s make it thread-safe public
class
Account
{

 

private
int
balance;

 

public
synchronized
void
withdraw(int
amount)
{
 



balance
‐=
amount;
 

}

 

public
synchronized
void
deposit(int
amount)
{
 



balance
+=
amount;
 

}

 }

 Thread-safe right? Wednesday, December 30, 2009
  19. 19. It’s still broken Transfers are not atomic Wednesday, December 30, 2009
  20. 20. Let’s write an atomic transfer method public
class
Account
{ 

... 



public
synchronized
void
transferTo( 





Account
to,
double
amount)
{ 





this.withdraw(amount);

 





to.deposit(amount); 



}

 



... 

} This will work right? Wednesday, December 30, 2009
  21. 21. Let’s transfer funds Account
alice
=
...

 Account
bob
=
...

 

 //
in
one
thread

 alice.transferTo(bob,
10.0D);

 

 //
in
another
thread

 bob.transferTo(alice,
3.0D);
 Wednesday, December 30, 2009
  22. 22. Might lead to DEADLOCK Darn, this is really hard!!! Wednesday, December 30, 2009
  23. 23. We need to enforce lock ordering > How? > Javawon’t help us > Need to use code convention (names etc.) > Requires knowledge about the internal state and implementation of Account > …runs counter to the principles of encapsulation in OOP > Opens up a Can of Worms Wednesday, December 30, 2009
  24. 24. The problem with locks Locks do not compose Taking too few locks Taking too many locks Taking the wrong locks Taking locks in the wrong order Error recovery is hard Wednesday, December 30, 2009
  25. 25. It’s just too hard Wednesday, December 30, 2009
  26. 26. Java bet on the wrong horse? Perhaps, but we’re not completely screwed There are alternatives Wednesday, December 30, 2009
  27. 27. We need better and more high-level abstractions Wednesday, December 30, 2009
  28. 28. Alternative Paradigms >Software Transactional Memory (STM) >Message-Passing Concurrency (Actors) >Dataflow Concurrency 28 Wednesday, December 30, 2009
  29. 29. Actors Wednesday, December 30, 2009
  30. 30. Actors • Originates in a 1973 paper by Carl Hewitt • Implemented in Erlang, Occam, Oz • Encapsulates state and behavior • Closer to the definition of OO than classes Wednesday, December 30, 2009
  31. 31. Alan Kay (father of SmallTalk and OOP) “OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.” “Actually I made up the term “object-oriented”, and I can tell you I did not have C++ in mind.” Replace C++ with Java or C# Wednesday, December 30, 2009
  32. 32. Actors • Implements Message-Passing Concurrency • Share NOTHING • Isolated lightweight processes • Communicates through messages • Asynchronous and non-blocking Wednesday, December 30, 2009
  33. 33. Actor Model of Concurrency • No shared state … hence, nothing to synchronize. • Each actor has a mailbox (message queue) Wednesday, December 30, 2009
  34. 34. Actor Model of Concurrency • Non-blocking send • Blocking receive • Messages are immutable • Highly performant and scalable • SEDA-style (Staged Event-Driven Architecture) Wednesday, December 30, 2009
  35. 35. Actor Model of Concurrency • Easier to reason about • Raised abstraction level • Easier to avoid –Race conditions –Deadlocks –Starvation –Live locks Wednesday, December 30, 2009
  36. 36. Akka Actors • Asynchronous –Fire-and-forget –Futures (Send Receive Reply Eventually) • Synchronous • Message loop with pattern (message) matching • Erlang-style Wednesday, December 30, 2009
  37. 37. Two different models • Thread-based • Event-based –Very lightweight –Can easily create millions on a single workstation (6.5 million on 4 G RAM) Wednesday, December 30, 2009
  38. 38. Actor libs for the JVM > Akka (Java/Scala) > Kilim (Java) > Jetlang (Java) > Actor’s Guild (Java) > ActorFoundry (Java) > Actorom (Java) > FunctionalJava (Java) > GParallelizer (Groovy) > Fan Actors (Fan) Wednesday, December 30, 2009
  39. 39. Fault tolerance & Scalablility Akka Transactors Supervisor hierarchies STM Distributed Secure Persistent RESTful Comet Wednesday, December 30, 2009
  40. 40. Actors case
object
Tick class
Counter
extends
Actor
{ 

private
var
counter
=
0 

def
receive
=
{ 



case
Tick
=>
 





counter
+=
1 





println(counter) 

} } Wednesday, December 30, 2009
  41. 41. Actors anonymous val
worker
=
actor
{ 

case
Work(fn)
=>
fn() } Wednesday, December 30, 2009
  42. 42. Actors anonymous val
worker
=
actor
{ 

...
//
init }
receive
{ 

case
Work(fn)
=>
fn() } Wednesday, December 30, 2009
  43. 43. Send: ! //
fire‐forget
 counter
!
Tick
 Wednesday, December 30, 2009
  44. 44. Reply class
SomeActor
extends
Actor
{ 

def
receive
=
{ 



case
User(name)
=>
 





//
use
implicit
sender 





sender.get
!
(“Hi
”
+
name) 

} } Wednesday, December 30, 2009
  45. 45. Reply class
SomeActor
extends
Actor
{ 

def
receive
=
{ 



case
User(name)
=>
 





//
use
reply 





reply(“Hi
”
+
name) 

} } Wednesday, December 30, 2009
  46. 46. Send: !! //
uses
Future
with
default
timeout val
resultOption
=
actor
!!
Message val
result
=
 

resultOption
getOrElse
defaultResult //
uses
Future
with
explicit
timeout (actor
!!
(Message,
1000)).getOrElse( 

throw
new
Exception(“Timed
out”)) Wednesday, December 30, 2009
  47. 47. Reply class
SomeActor
extends
Actor
{ 

def
receive
=
{ 



case
User(name)
=>
 





//
use
reply 





reply(“Hi
”
+
name) 

} } Wednesday, December 30, 2009
  48. 48. Reply class
SomeActor
extends
Actor
{ 

def
receive
=
{ 



case
User(name)
=>
 





//
store
away
the
sender
future 





//
to
resolve
later
or
 





//
somewhere
else 





...
=
senderFuture 

} } Wednesday, December 30, 2009
  49. 49. Start / Stop actor.start actor.stop spawn(classOf[MyActor]) //
callback override
def
shutdown
=
{ 

...
//
clean
up
before
shutdown
 } Wednesday, December 30, 2009
  50. 50. Active Objects: Java public
class
Counter
{ 

private
int
counter
=
0; 

public
void
count()
{ 



counter++; 



System.out.println(counter); 

} } Wednesday, December 30, 2009
  51. 51. Create: POJO Counter
counter
=
(Counter)ActiveObject 

.newInstance(Counter.class,
1000); Wednesday, December 30, 2009
  52. 52. Create: Interface & Implementation Counter
counter
=
(Counter)ActiveObject 

.newInstance( 



Counter.class,
 



CounterImpl.class,
 



1000); Wednesday, December 30, 2009
  53. 53. Active Objects class
Counter
{ 

private
var
counter
=
0 

def
count
=
{ 



counter
+=
1 



println(counter) 

} } Wednesday, December 30, 2009
  54. 54. Create: POSO val
counter
=
ActiveObject.newInstance( 



classOf[Counter],
1000) Wednesday, December 30, 2009
  55. 55. Send counter.count Wednesday, December 30, 2009
  56. 56. @oneway class
Counter
{ 

private
var
counter
=
0 

@oneway
def
count
=
{ 



counter
+=
1 



println(counter) 

} } Wednesday, December 30, 2009
  57. 57. Immutable messages //
define
the
case
class case
class
Register(user:
User) //
create
and
send
a
new
case
class
message actor
!
Register(user) //
tuples actor
!
(username,
password) //
lists actor
!
List(“bill”,
“bob”,
“alice”) Wednesday, December 30, 2009
  58. 58. Actors: config <akka> 

version
=
"0.6" 

<actor> 



timeout
=
5000 



serialize‐messages
=
off 

</actor> </akka> Wednesday, December 30, 2009
  59. 59. Akka Dispatchers Wednesday, December 30, 2009
  60. 60. Dispatchers class
Dispatchers
{ 

def
newThreadBasedDispatcher(actor:
Actor) 

def
newExecutorBasedEventDrivenDispatcher(name:String) 
 

... } Wednesday, December 30, 2009
  61. 61. Set dispatcher class
MyActor
extends
Actor
{ 

dispatcher
=
Dispatchers 



.newThreadBasedDispatcher(this) 

 

... } actor.dispatcher
=
dispatcher
//
before
started Wednesday, December 30, 2009
  62. 62. EventBasedDispatcher Fluent DSL val
dispatcher
= 

Dispatchers.newExecutorBasedEventDrivenDispatcher

 
 



.withNewThreadPoolWithBoundedBlockingQueue(100) 



.setCorePoolSize(16) 



.setMaxPoolSize(128) 



.setKeepAliveTimeInMillis(60000) 



.setRejectionPolicy(new
CallerRunsPolicy) 



.buildThreadPool Wednesday, December 30, 2009
  63. 63. When to use which dispatcher? Wednesday, December 30, 2009
  64. 64. Thread-based actors • One thread per Actor • Good: • Threads (actors) don’t block each other • Good for long-running tasks • Bad: • Poor scalability • Bad for short running tasks • Use for a limited number of Actors • Use for low frequency of messages Wednesday, December 30, 2009
  65. 65. Event-based actors • Backed by thread pool • Lightweight: • Can create millions of Actors • 6.5 million on 4 G RAM • Best scalability and performance • 2 million messages in 8 seconds Wednesday, December 30, 2009
  66. 66. Single threaded event-based actors • Best performance • Millions of Actors • Bad: • one actor can block all other actors • Does not take advantage of multicore Wednesday, December 30, 2009
  67. 67. MessageQueues Unbounded LinkedBlockingQueue Bounded LinkedBlockingQueue Bounded ArrayBlockingQueue Bounded SynchronousQueue Plus different options per queue Wednesday, December 30, 2009
  68. 68. Akka Supervision Wednesday, December 30, 2009
  69. 69. Stolen from Erlang Wednesday, December 30, 2009
  70. 70. 9 nines Wednesday, December 30, 2009
  71. 71. Supervisor hierarchies OneForOne Wednesday, December 30, 2009
  72. 72. Supervisor hierarchies AllForOne Wednesday, December 30, 2009
  73. 73. Fault handlers AllForOneStrategy( 

maxNrOfRetries,
 

withinTimeRange) OneForOneStrategy( 

maxNrOfRetries,
 

withinTimeRange) Wednesday, December 30, 2009
  74. 74. Linking link(actor)
 unlink(actor)
 startLink(actor) spawnLink(classOf[MyActor]) Wednesday, December 30, 2009
  75. 75. trapExit trapExit
=
List( 
classOf[ServiceException],
 
classOf[PersistenceException]) Wednesday, December 30, 2009
  76. 76. Supervision class
Supervisor
extends
Actor
{ 

trapExit
=
List(classOf[Throwable]) 

faultHandler
=
 



Some(OneForOneStrategy(5,
5000)) 

def
receive
=
{ 



case
Register(actor)
=>
 





link(actor) 

} } Wednesday, December 30, 2009
  77. 77. Manage failure class
FaultTolerant
extends
Actor
{ 

... 

override
def
preRestart(reason:
AnyRef)
=
{ 



...
//
clean
up
before
restart 

} 

override
def
postRestart(reason:
AnyRef)
=
{ 



...
//
init
after
restart 

} } Wednesday, December 30, 2009
  78. 78. Declarative config RestartStrategy( 

AllForOne,


//
restart
policy
 

10,









//
max
#
of
restart
retries 

5000)







//
within
time
in
millis LifeCycle( 

//
Permanent:
always
be
restarted 

//
Temporary:
restarted
if
exited
through
ERR 

Permanent)






 Wednesday, December 30, 2009
  79. 79. Declarative config object
factory
extends
SupervisorFactory( 

SupervisorConfig( 



RestartStrategy(AllForOne,
3,
10000), 




Supervise( 





actor1, 





LifeCycle(Permanent))
:: 




Supervise( 





actor2, 





LifeCycle(Temporary))
:: 



Nil)) factory.newSupervisor.start Wednesday, December 30, 2009
  80. 80. ActorRegistry val
actors
=
 

ActorRegistry.actorsFor(FQN) val
actors
=
 

ActorRegistry.actorsFor(classOf[..]) Wednesday, December 30, 2009
  81. 81. Initialize actor override
def
init
=
{ 

...
//
init
the
actor } init is called on startup Wednesday, December 30, 2009
  82. 82. Akka Remote Actors Wednesday, December 30, 2009
  83. 83. Remote Server //
use
host
&
port
in
config RemoteNode.start RemoteNode.start(classLoader) RemoteNode.start( 

"localhost",
9999) RemoteNode.start( 

"localhost",
9999,
classLoader) Wednesday, December 30, 2009
  84. 84. Remote Server //
use
host
&
port
in
config val
server
=
new
RemoteServer server.start("localhost",
9999) Wednesday, December 30, 2009
  85. 85. Remote actors spawnRemote(classOf[MyActor],
host,
port)
 startLinkRemote(actor,
host,
port) spawnLinkRemote(classOf[MyActor],
host,
port) Wednesday, December 30, 2009
  86. 86. Remote config <akka> 

<remote> 



service
=
on 



hostname
=
"localhost" 



port
=
9999 



connection‐timeout
=
1000 

</remote> </akka> Wednesday, December 30, 2009
  87. 87. Akka STM Wednesday, December 30, 2009
  88. 88. Software Transactional Memory (STM) 88 Wednesday, December 30, 2009
  89. 89. What is STM? 89 Wednesday, December 30, 2009
  90. 90. STM: overview > See the memory (heap and stack) as a transactional dataset > Similar to a database  begin  commit  abort/rollback > Transactions are retried automatically upon collision > Rolls back the memory on abort Wednesday, December 30, 2009
  91. 91. STM: overview > Transactions can nest > Transactions compose (yipee!!) 


atomic
{


 




..


 




atomic
{



 






..



 




}

 


}

 Wednesday, December 30, 2009
  92. 92. STM: restrictions >All operations in scope of a transaction:  Need to be idempotent  Can’t have side-effects 92 Wednesday, December 30, 2009
  93. 93. Akka STM is based on the ideas of Clojure STM 93 Wednesday, December 30, 2009
  94. 94. 2 things: 1. Managed References 2. Persistent Datastructures 94 Wednesday, December 30, 2009
  95. 95. Managed References Typical OO - Direct • Typical OO: direct Mutable Objects objects references to access to mutable foo :a ? :b ? :c 42 :d ? :e 6 Clojure - and value • Unifies identity Indirect references • Managed Reference: separates Identity & Value • Anything can change at any time • Consistency is a user problem Objects to Immutable • Encapsulation doesn’t solve concurrency:a foo "fred" problems :b "ethel" @foo :c 42 :d 17 :e 6 Copyright Rich Hickey 2009 Wednesday, December 30, 2009 • Separates identity and value
  96. 96. Managed References • Separates Identity from Value - Values are immutable - Identity (Ref) holds Values • Change is a function • Compare-and-swap (CAS) • Abstraction of time • Can only be altered within a transaction Wednesday, December 30, 2009
  97. 97. Managed References val
ref
=
TransactionalState.newRef( 

HashTrie[String,
User]()) val
users
=
ref.get val
newUsers
=
users
+
//
creates
new
HashTrie 

(“bill”
‐>
new
User(“bill”,
“secret”) ref.swap(newUsers) Wednesday, December 30, 2009
  98. 98. Managed References val
usersRef
=
TransactionalState.newRef( 

HashTrie[String,
User]()) for
(users
<‐
usersRef)
{ 

users
+
(name
‐>
user) } val
user
=
for
(users
<‐
usersRef)
yield
{ 

users(name) } Wednesday, December 30, 2009
  99. 99. Managed References for
{ 

users
<‐
usersRef 

user

<‐
users 

roles
<‐
rolesRef 

role

<‐
roles 

if
user.hasRole(role) }
{ 

...
//
do
stuff } Wednesday, December 30, 2009
  100. 100. Managed References convenience classes //
wraps
a
Ref
with
a
HashTrie
 val
users
=
TransactionalState.newMap[String,
User] //
wraps
a
Ref
with
a
Vector
 val
users
=
TransactionalState.newVector[User] Wednesday, December 30, 2009
  101. 101. Persistent datastructures • Immutable • Change is a function • Old version still available after change • Very fast with performance guarantees (near constant time) • Thread safe • Iteration safe Wednesday, December 30, 2009
  102. 102. Bit-partitioned hash trie Bit-partitioned hash tries Copyright Rich Hickey 2009 Wednesday, December 30, 2009
  103. 103. Structural sharing with path copying Approach Path Copying • Programming with values is critical HashMap HashMap int count 16 int count 15 INode root INode root • By eschewing morphing in place, we just need to manage the succession of values (states) of an identity • A timeline coordination problem • Several semantics possible • Managed references • Variable-like cells with coordination semantics Hickey 2009 Copyright Rich Wednesday, December 30, 2009
  104. 104. Persistent datastructures ble HashTrie oordination import
se.scalablesolutions.akka.collection._ val
hashTrie
=
new
HashTrie[K,
V] //
API
(+
extends
Map) def
get(key:
K):
V def
+[A
>:
V](pair:
(K,
A)):
HashTrie[K,
A] def
‐(key:
K):
HashTrie[K,
A] def
empty[A]:
HashTrie[K,
A] Wednesday, December 30, 2009
  105. 105. Persistent datastructures ble Vector oordination import
se.scalablesolutions.akka.collection._ val
vector
=
new
Vector[T] //
API
(+
extends
RandomAccessSeq) def
apply(i:
Int):
T def
+[A
>:
T](obj:
A):
Vector[A] def
pop:
HashTrie[K,
A]
//
remove
tail def
update[A
>:
T](i:
Int,
obj:
A):
Vector[A] Wednesday, December 30, 2009
  106. 106. Akka STM • Transactional Memory - Atomic, Consistent, Isolated (ACI) - MVCC - Rolls back in memory and retries automatically on clash • Works together with Managed References • Map, Vector and Ref abstraction Wednesday, December 30, 2009
  107. 107. STM: declarative API class
UserRegistry
extends
Transactor
{ 

 

private
lazy
val
storage
=
 



TransactionalState.newMap[String,
User] 

def
receive
=
{ 



case
NewUser(user)
=> 





storage
+
(user.name
‐>
user) 



...
 

} } Wednesday, December 30, 2009
  108. 108. STM: declarative API class
UserRegistry
extends
Actor
{ 

makeTransactionRequired 

 

private
lazy
val
storage
=
 



TransactionalState.newMap[String,
User] 

def
receive
=
{ 



case
NewUser(user)
=> 





storage
+
(user.name
‐>
user) 



...
 

} } Wednesday, December 30, 2009
  109. 109. STM: declarative Java API @transactionrequired class
UserRegistry
{ 


 } Wednesday, December 30, 2009
  110. 110. STM: high-order fun API import
se.scalablesolutions.akka.stm.Transaction._ atomic
{ 

..
//
do
something
within
a
transaction } atomic(maxNrOfRetries)
{ 

..
//
do
something
within
a
transaction } atomicReadOnly
{ 

..
//
do
something
within
a
transaction } Wednesday, December 30, 2009
  111. 111. STM: high-order fun API import
se.scalablesolutions.akka.stm.Transaction._ atomically
{ 

..
//
try
to
do
something }
orElse
{ 

..
//
if
tx
clash;
try
do
do
something
else } Wednesday, December 30, 2009
  112. 112. STM: monadic API val
userStorage
=
 

TransactionalState.newMap[String,
User] for
(tx
<‐
Transaction())
{ 

userStorage.put(user.name,
user) }
 Wednesday, December 30, 2009
  113. 113. STM: monadic API val
userStorage
=
 

TransactionalState.newMap[String,
User] val
users
=
for
{ 

tx
<‐
Transaction() 

name
<‐
userNames 

if
userStorage.contains(name) }
yield
userStorage.get(name)
//
transactional Wednesday, December 30, 2009
  114. 114. STM: config <akka> 

<stm> 



service
=
on 



distributed
=
off 

</stm> </akka> Wednesday, December 30, 2009
  115. 115. STM: disable TransactionManagement.disableTransactions Wednesday, December 30, 2009
  116. 116. Akka Serialization Wednesday, December 30, 2009
  117. 117. Serializers ScalaJSON JavaJSON Protobuf SBinary Java Wednesday, December 30, 2009
  118. 118. Serializers Scala 2 JSON & JSON 2 Scala val
foo
=
new
Foo val
json
=
Serializer.ScalaJSON.out(foo) val
fooCopy
=
 

Serializer.ScalaJSON.in(json).asInstanceOf[Foo] Wednesday, December 30, 2009
  119. 119. Serializers Scala 2 Binary & Binary 2 Scala import
sbinary.DefaultProtocol._
 val
users
=
 


("user1",
"passwd1")
:: 


("user2",
"passwd2")
::
 


("user3",
"passwd3")
::
Nil val
bytes
=
Serializer.SBinary.out(users) val
usersCopy:
List[Tuple2[String,
String]]]
=

 

Serializer.SBinary.in(bytes) Wednesday, December 30, 2009
  120. 120. Serializers Protobuf val
pojo
=
 

ProtobufPOJO.getDefaultInstance.toBuilder 

.setId(1) 

.setName("protobuf") 

.setStatus(true).build val
bytes
=
pojo.toByteArray val
pojoCopy
=
Serializer.Protobuf.in( 

bytes,
classOf[ProtobufPOJO]) Wednesday, December 30, 2009
  121. 121. Serializable case
class
MyMessage( 

id:
String,
 

value:
Tuple2[String,
Int])
 

extends
Serializable.ScalaJSON val
message
=
MyMessage("id",
("hello",
34)) val
json
=
message.toJSON Wednesday, December 30, 2009
  122. 122. Akka Persistence Wednesday, December 30, 2009
  123. 123. Persistence • Pluggable storage backend - Cassandra - MongoDB - Redis • Map, Vector and Ref abstraction • MVCC • Works together with STM Wednesday, December 30, 2009
  124. 124. Akka Persistence API //
transactional
Cassandra‐backed
Map
 val
map
=
CassandraStorage.newMap //
transactional
Redis‐backed
Vector
 val
vector
=
RedisStorage.newVector //
transactional
Mongo‐backed
Ref val
ref
=
MongoStorage.newRef Wednesday, December 30, 2009
  125. 125. Persistence: config <akka> 

<storage>
 



<cassandra> 





hostname
=
"127.0.0.1"







 





port
=
9160 





storage‐format
=
"protobuf"






 





consistency‐level
=
quorum 



</cassandra> 



<mongodb> 





hostname
=
"127.0.0.1"







 





port
=
27017 





dbname
=
"mydb" 



</mongodb> 

</storage> </akka> Wednesday, December 30, 2009
  126. 126. Akka’s Cassandra API val
sessions
=
new
CassandraSessionPool( 



keyspace, 



StackPool(SocketProvider(host,
port)), 



Protocol.Binary, 



consistencyLevel) Create a session pool Wednesday, December 30, 2009
  127. 127. Akka Cassandra API //
get
a
column val
column
=
sessions.withSession
{
session
=>
 

session
|
(key,
new
ColumnPath( 



columnFamily,
superColumn,
serializer.out(name)) } val
value
=
if
(column.isDefined)
 

Some(serializer.in(column.get.value,
None))
else

 

None Automatic connection management Wednesday, December 30, 2009
  128. 128. Akka Cassandra API //
add
a
column sessions.withSession
{
session
=>
 

session
++|
 



(key,
 



new
ColumnPath(cf,
null,
serializer.out(name)), 



serializer.out(value), 



System.currentTimeMillis, 



consistencyLevel) } Wednesday, December 30, 2009
  129. 129. Akka REST Wednesday, December 30, 2009
  130. 130. RESTful actors @Path("/count") class
Counter
extends
Actor
{ 

private
var
counter
=
0 

@GET
@Produces(Array("text/html")) 

def
count
=
(this
!!
Tick) 



.getOrElse(<h1>Error
in
counter</h1>) 

def
receive
=
{ 



case
Tick
=>
 





counter
+=
1 





reply(<h1>Tick:
{counter}</h1>) 



} 

}} Wednesday, December 30, 2009
  131. 131. REST: config <akka> 

<rest> 



service
=
on 



hostname
=
“localhost” 



port
=
9998 

</rest> </akka> Wednesday, December 30, 2009
  132. 132. Boot classes class
Boot
{ 

object
factory
extends
SupervisorFactory( 



SupervisorConfig( 





RestartStrategy(OneForOne,
3,
100), 





Supervise( 







new
Counter,
LifeCycle(Permanent))
:: 





Supervise( 







new
Chat,
LifeCycle(Permanent))
:: 





Nil))) 

val
supervisor
=
factory.newInstance 

supervisor.start } Wednesday, December 30, 2009
  133. 133. Boot config <akka> 

boot
=
["sample.rest.Boot",
 









"sample.comet.Boot"]
 

... </akka> Wednesday, December 30, 2009
  134. 134. Akka Comet Wednesday, December 30, 2009
  135. 135. Comet actors • Based on Atmosphere project • Portable • Supports natively: • Tomcat 4, 5, 6 • Jetty 5, 6, 7 • GlassFish 1, 2, 3 • Weblogic 9.x, 10.x • Grizzly 1.9.x • JBossWeb 2.x • Annotation based Wednesday, December 30, 2009
  136. 136. Comet actors @Path("/chat") class
Chat
extends
Actor
{ 

case
class
Chat(who:
String,
what:
String,
message:
String) 

@Suspend
//
receiving
endpoint 

@GET
@Produces(Array("text/html")) 

def
suspend
=
<!‐‐
suspend
‐‐> 

//
sending
endpoint 

@Broadcast(Array(classOf[XSSHtmlFilter],
classOf[JsonFilter])) 

@Consumes(Array("application/x‐www‐form‐urlencoded")) 

@Produces(Array("text/html")) 

@POST
 

def
publishMessage(form:
MultivaluedMap[String,
String])
= 



(this
!!
Chat(form.getFirst("name"),
form.getFirst("action"),

 












form.getFirst("message"))).getOrElse("System
error") 

def
receive
=
{
case
Chat(..)
=>
..} } Wednesday, December 30, 2009
  137. 137. Akka Security Wednesday, December 30, 2009
  138. 138. Security: service class
SampleAuthenticationService
 

extends
DigestAuthenticationActor
{ 

//
Use
an
in‐memory
nonce‐map
as
default 

override
def
mkNonceMap
=
new
HashMap[String,
Long] 

//
Change
this
to
whatever
you
want 

override
def
realm
=
“sample” 

//
Username,
password
and
roles
for
a
username 

override
def
userInfo(uname:
String):
Option[UserInfo]
=
{ 



...
//
get
user
with
password
and
roles 



Some(UserInfo(uname,
password,
roles)) 

} } Wednesday, December 30, 2009
  139. 139. Security: usage class
SecuredActor
extends
Actor
{ 

@RolesAllowed(Array(“admin”)) 

def
resetSystem
=
 



(this
!!
Reset).getOrElse( 





<error>Could
not
reset
system</error>) 

def
receive
=
{ 



case
Reset
=>
... 

} } Wednesday, December 30, 2009
  140. 140. Security: config <akka> 

<rest> 



service
=
on 



hostname
=
“localhost” 



port
=
9998 



filters
=
[“AkkaSecurityFilterFactory”] 



authenticator
=
“SimpleAuthenticationService” 

</rest> </akka> Wednesday, December 30, 2009
  141. 141. Akka Lift Wednesday, December 30, 2009
  142. 142. Lift integration class
Boot
{
//
Lift’s
bootstrap
class 

def
boot
{ 



LiftRules.httpAuthProtectedResource.prepend
{ 





case
(ParsePath("akka‐lift"
::
Nil,
_,
_,
_))
=>
 







Full(AuthRole("admin")) 



} 



LiftRules.authentication
=
HttpBasicAuthentication("lift")
{ 





case
("guest",
"guest",
req)
=>
userRoles(AuthRole("admin")) 



} 



object
factory
extends
SupervisorFactory( 





SupervisorConfig( 







RestartStrategy(OneForOne,
3,
100), 







List(Supervise(new
AkkaService,
LifeCycle(Permanent)))) 



factory.newInstance.start 

} } Wednesday, December 30, 2009
  143. 143. Lift integration <web‐app> 

<servlet> 



<servlet‐name>AkkaServlet</servlet‐name> 



<servlet‐class> 





se.ss.akka.rest.AkkaServlet 



</servlet‐class> 

</servlet> 

<servlet‐mapping> 



<servlet‐name>AkkaServlet</servlet‐name> 



<url‐pattern>/*</url‐pattern> 

</servlet‐mapping> </web‐app> Wednesday, December 30, 2009
  144. 144. Akka HotSwap Wednesday, December 30, 2009
  145. 145. HotSwap actor
!
HotSwap(Some({ 

//
new
body 

case
Ping
=>
 



...
 

case
Pong
=>
 



...

 })) Wednesday, December 30, 2009
  146. 146. Akka AMQP Wednesday, December 30, 2009
  147. 147. AMQP: producer val
producer
=
AMQP.newProducer( 

config,
 

hostname,
port,
 

exchangeName,
 

serializer,
 


None,
None,
//
listeners
 

100) producer
!
Message(“Hi
there”,
routingId) 

 Wednesday, December 30, 2009
  148. 148. AMQP: consumer val
consumer
=
AMQP.newConsumer( 

config,
hostname,
port,
exchangeName,


 

ExchangeType.Direct,
serializer,
 

None,
100,
passive,
durable,
 

Map[String,
AnyRef()) consumer
!
MessageConsumerListener(
 

queueName,
routingId,
actor
{ 



case
Message(payload,
_,
_,
_,
_)
=>
 






...
//
process
message 



}) Wednesday, December 30, 2009
  149. 149. Akka Kernel Wednesday, December 30, 2009
  150. 150. Start Kernel java
‐jar
akka‐0.6.jar
 

‐Dakka.config=<path>/akka.conf Or export
AKKA_HOME=<path
to
akka
dist> java
‐jar
$AKKA_HOME/dist/akka‐0.6.jar Wednesday, December 30, 2009
  151. 151. Akka Deployment Wednesday, December 30, 2009
  152. 152. Akka as a library Using the Actor module Wednesday, December 30, 2009
  153. 153. Akka as a library Add STM module Wednesday, December 30, 2009
  154. 154. Akka as a library Add Persistence module as a Cache Wednesday, December 30, 2009
  155. 155. Akka as a library Add Persistence module as primary SoR Wednesday, December 30, 2009
  156. 156. Akka as a library Add REST and Comet modules Wednesday, December 30, 2009
  157. 157. Akka as stand-alone Kernel Wednesday, December 30, 2009
  158. 158. Logging <log> 

console
=
on 

filename
=
"./logs/akka.log" 

roll
=
"daily"
 

level
=
"debug" 

syslog_host
=
".." 

syslog_server_name
=
".." </log> Wednesday, December 30, 2009
  159. 159. Monitoring & Management Provisioning and more... Part of commercial license Wednesday, December 30, 2009
  160. 160. Learn more http://akkasource.org Wednesday, December 30, 2009
  161. 161. Professional help Consulting Training Mentoring http://scalablesolutions.se jonas@jonasboner.com Wednesday, December 30, 2009
  162. 162. EOF Wednesday, December 30, 2009
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×