SlideShare a Scribd company logo
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
State
                                 2
Wednesday, December 30, 2009
The devil is in
                                 the state



                                      3
Wednesday, December 30, 2009
Wrong,
                               let me rephrase



                                      4
Wednesday, December 30, 2009
The devil is in
                      the      mutable state
                                      5
Wednesday, December 30, 2009
Definitions
                                    &
                               Philosophy
                                   6
Wednesday, December 30, 2009
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
What is an Identity?
                                A stable logical entity
                                   associated with a
                               series of different Values
                                       over time


Wednesday, December 30, 2009
What is State?
                                   The Value
                                an entity with a
                                specific Identity
                               has at a particular
                                 point in time


Wednesday, December 30, 2009
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
The Problem
                                 The   unification Of
                Identity & Value
                               They are   not   the same


Wednesday, December 30, 2009
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
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
      Java

      C#

      C/C++

      Ruby

      Python

      etc.


Wednesday, December 30, 2009
Shared-State
                               Concurrency is
                               incredibly hard
     > Inherentlyvery hard to use reliably
     > Even the experts get it wrong




Wednesday, December 30, 2009
Example of
  Shared-State Concurrency
                                   Transfer funds
                               between bank accounts



Wednesday, December 30, 2009
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
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
It’s still broken
         Transfers are not atomic


Wednesday, December 30, 2009
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
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
Might lead to
                               DEADLOCK
                               Darn, this is really hard!!!




Wednesday, December 30, 2009
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
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
It’s just
                               too hard

Wednesday, December 30, 2009
Java bet on the
                                wrong horse?
                                     Perhaps,
                                  but we’re not
                                completely screwed
                               There are alternatives
Wednesday, December 30, 2009
We need better
                                 and more
                                 high-level
                                abstractions

Wednesday, December 30, 2009
Alternative Paradigms
   >Software Transactional
                         Memory (STM)
   >Message-Passing Concurrency (Actors)
   >Dataflow Concurrency




                               28
Wednesday, December 30, 2009
Actors
Wednesday, December 30, 2009
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
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
Actors
    • Implements Message-Passing Concurrency
    • Share NOTHING
    • Isolated lightweight processes
    • Communicates through messages
    • Asynchronous and non-blocking




Wednesday, December 30, 2009
Actor Model of
                                Concurrency
    • No shared state
       … hence, nothing to synchronize.
    • Each actor has a mailbox (message queue)




Wednesday, December 30, 2009
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
Actor Model of
                                Concurrency
    • Easier to reason about
    • Raised abstraction level
    • Easier to avoid
      –Race conditions
      –Deadlocks
      –Starvation
      –Live locks
Wednesday, December 30, 2009
Akka Actors
    • Asynchronous
      –Fire-and-forget
      –Futures (Send Receive Reply Eventually)
    • Synchronous
    • Message loop with pattern (message)
      matching
    • Erlang-style

Wednesday, December 30, 2009
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
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
Fault tolerance & Scalablility
                  Akka Transactors
                   Supervisor hierarchies
                 STM           Distributed
                     Secure        Persistent
               RESTful           Comet
Wednesday, December 30, 2009
Actors
                               case
object
Tick

                               class
Counter
extends
Actor
{
                               

private
var
counter
=
0

                               

def
receive
=
{
                               



case
Tick
=>

                               





counter
+=
1
                               





println(counter)
                               

}
                               }

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

case
Work(fn)
=>
fn()
                               }




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

...
//
init
                               }
receive
{
                               

case
Work(fn)
=>
fn()
                               }

Wednesday, December 30, 2009
Send: !
                               //
fire‐forget

                               counter
!
Tick





Wednesday, December 30, 2009
Reply
                     class
SomeActor
extends
Actor
{
                     

def
receive
=
{
                     



case
User(name)
=>

                     





//
use
implicit
sender
                     





sender.get
!
(“Hi
”
+
name)
                     

}
                     }




Wednesday, December 30, 2009
Reply
                        class
SomeActor
extends
Actor
{
                        

def
receive
=
{
                        



case
User(name)
=>

                        





//
use
reply
                        





reply(“Hi
”
+
name)
                        

}
                        }




Wednesday, December 30, 2009
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
Reply
                       class
SomeActor
extends
Actor
{
                       

def
receive
=
{
                       



case
User(name)
=>

                       





//
use
reply
                       





reply(“Hi
”
+
name)
                       

}
                       }




Wednesday, December 30, 2009
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
Start / Stop
      actor.start
      actor.stop

      spawn(classOf[MyActor])

      //
callback
      override
def
shutdown
=
{
      

...
//
clean
up
before
shutdown

      }
Wednesday, December 30, 2009
Active Objects: Java
              public
class
Counter
{
              

private
int
counter
=
0;
              

public
void
count()
{
              



counter++;
              



System.out.println(counter);
              

}
              }



Wednesday, December 30, 2009
Create: POJO

      Counter
counter
=
(Counter)ActiveObject
      

.newInstance(Counter.class,
1000);




Wednesday, December 30, 2009
Create:
                    Interface & Implementation

      Counter
counter
=
(Counter)ActiveObject
      

.newInstance(
      



Counter.class,

      



CounterImpl.class,

      



1000);



Wednesday, December 30, 2009
Active Objects
                      class
Counter
{
                      

private
var
counter
=
0
                      

def
count
=
{
                      



counter
+=
1
                      



println(counter)
                      

}
                      }


Wednesday, December 30, 2009
Create: POSO

           val
counter
=
ActiveObject.newInstance(
           



classOf[Counter],
1000)




Wednesday, December 30, 2009
Send

                               counter.count




Wednesday, December 30, 2009
@oneway
                      class
Counter
{
                      

private
var
counter
=
0
                      

@oneway
def
count
=
{
                      



counter
+=
1
                      



println(counter)
                      

}
                      }


Wednesday, December 30, 2009
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
Actors: config
                 <akka>
                 

version
=
"0.6"
                 

<actor>
                 



timeout
=
5000
                 



serialize‐messages
=
off
                 

</actor>
                 </akka>

Wednesday, December 30, 2009
Akka Dispatchers


Wednesday, December 30, 2009
Dispatchers
        class
Dispatchers
{
        

def
newThreadBasedDispatcher(actor:
Actor)

        

def
newExecutorBasedEventDrivenDispatcher(name:String)
        

        

...
        }




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

dispatcher
=
Dispatchers
     



.newThreadBasedDispatcher(this)
     


     

...
     }

     actor.dispatcher
=
dispatcher
//
before
started




Wednesday, December 30, 2009
EventBasedDispatcher
                               Fluent DSL
    val
dispatcher
=
    

Dispatchers.newExecutorBasedEventDrivenDispatcher


                                                        

    



.withNewThreadPoolWithBoundedBlockingQueue(100)
    



.setCorePoolSize(16)
    



.setMaxPoolSize(128)
    



.setKeepAliveTimeInMillis(60000)
    



.setRejectionPolicy(new
CallerRunsPolicy)
    



.buildThreadPool



Wednesday, December 30, 2009
When to use which
                 dispatcher?


Wednesday, December 30, 2009
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
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
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
MessageQueues
                      Unbounded LinkedBlockingQueue
                        Bounded LinkedBlockingQueue
                         Bounded ArrayBlockingQueue
                          Bounded SynchronousQueue

                               Plus different options per queue


Wednesday, December 30, 2009
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,

                               

withinTimeRange)

                               OneForOneStrategy(
                               

maxNrOfRetries,

                               

withinTimeRange)


Wednesday, December 30, 2009
Linking
                 link(actor)

                 unlink(actor)


                 startLink(actor)
                 spawnLink(classOf[MyActor])



Wednesday, December 30, 2009
trapExit
           trapExit
=
List(
           
classOf[ServiceException],

           
classOf[PersistenceException])




Wednesday, December 30, 2009
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
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
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
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
ActorRegistry
            val
actors
=

            

ActorRegistry.actorsFor(FQN)

            val
actors
=

            

ActorRegistry.actorsFor(classOf[..])




Wednesday, December 30, 2009
Initialize actor
                               override
def
init
=
{
                               

...
//
init
the
actor
                               }




                         init is called on startup
Wednesday, December 30, 2009
Akka Remote Actors


Wednesday, December 30, 2009
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
Remote Server
                 //
use
host
&
port
in
config
                 val
server
=
new
RemoteServer

                 server.start("localhost",
9999)




Wednesday, December 30, 2009
Remote actors
        spawnRemote(classOf[MyActor],
host,
port)


        startLinkRemote(actor,
host,
port)

        spawnLinkRemote(classOf[MyActor],
host,
port)




Wednesday, December 30, 2009
Remote config
                          <akka>
                          

<remote>
                          



service
=
on
                          



hostname
=
"localhost"
                          



port
=
9999
                          



connection‐timeout
=
1000
                          

</remote>
                          </akka>


Wednesday, December 30, 2009
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

    commit

    abort/rollback

 > Transactions are retried automatically upon
   collision
 > Rolls back the memory on abort

Wednesday, December 30, 2009
STM: overview
     > Transactions can nest
     > Transactions compose (yipee!!)
    


atomic
{



    




..



    




atomic
{




    






..




    




}


    


}


Wednesday, December 30, 2009
STM: restrictions
   >All   operations in scope of a
      transaction:
      
       Need to be idempotent
      
       Can’t have side-effects




                               92
Wednesday, December 30, 2009
Akka STM
                               is based on the ideas of
                                     Clojure STM


                                          93
Wednesday, December 30, 2009
2 things:
     1. Managed References
     2. Persistent Datastructures

                               94
Wednesday, December 30, 2009
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
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
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
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
Managed References
                               for
{
                               

users
<‐
usersRef
                               

user

<‐
users
                               

roles
<‐
rolesRef
                               

role

<‐
roles
                               

if
user.hasRole(role)
                               }
{
                               

...
//
do
stuff
                               }

Wednesday, December 30, 2009
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
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
Bit-partitioned hash trie
          Bit-partitioned hash tries




                               Copyright Rich Hickey 2009
Wednesday, December 30, 2009
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
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
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
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
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
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
STM: declarative Java API
                               @transactionrequired
                               class
UserRegistry
{
                               



                               }




Wednesday, December 30, 2009
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
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
STM: monadic API
                   val
userStorage
=

                   

TransactionalState.newMap[String,
User]

                   for
(tx
<‐
Transaction())
{
                   

userStorage.put(user.name,
user)
                   }





Wednesday, December 30, 2009
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
STM: config
                               <akka>
                               

<stm>
                               



service
=
on
                               



distributed
=
off
                               

</stm>
                               </akka>




Wednesday, December 30, 2009
STM: disable
                  TransactionManagement.disableTransactions




Wednesday, December 30, 2009
Akka Serialization


Wednesday, December 30, 2009
Serializers
                                  ScalaJSON
                                   JavaJSON
                                    Protobuf
                                     SBinary
                                         Java
Wednesday, December 30, 2009
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
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
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
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
Akka Persistence


Wednesday, December 30, 2009
Persistence
     • Pluggable storage backend
        - Cassandra
        - MongoDB
        - Redis
     • Map, Vector and Ref abstraction
     • MVCC
     • Works together with STM

Wednesday, December 30, 2009
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
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
Akka’s Cassandra API
        val
sessions
=
new
CassandraSessionPool(
        



keyspace,
        



StackPool(SocketProvider(host,
port)),
        



Protocol.Binary,
        



consistencyLevel)




                               Create a session pool
Wednesday, December 30, 2009
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
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
Akka REST


Wednesday, December 30, 2009
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
REST: config
                     <akka>
                     

<rest>
                     



service
=
on
                     



hostname
=
“localhost”
                     



port
=
9998
                     

</rest>
                     </akka>


Wednesday, December 30, 2009
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
Boot config
                   <akka>
                   

boot
=
["sample.rest.Boot",

                   









"sample.comet.Boot"]

                   

...
                   </akka>




Wednesday, December 30, 2009
Akka Comet


Wednesday, December 30, 2009
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
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
Akka Security


Wednesday, December 30, 2009
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
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
Security: config
       <akka>
       

<rest>
       



service
=
on
       



hostname
=
“localhost”
       



port
=
9998
       



filters
=
[“AkkaSecurityFilterFactory”]
       



authenticator
=
“SimpleAuthenticationService”
       

</rest>
       </akka>




Wednesday, December 30, 2009
Akka Lift


Wednesday, December 30, 2009
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
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
Akka HotSwap


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

//
new
body
                               

case
Ping
=>

                               



...

                               

case
Pong
=>

                               



...


                               }))


Wednesday, December 30, 2009
Akka AMQP


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

config,

               

hostname,
port,

               

exchangeName,

               

serializer,

               


None,
None,
//
listeners

               

100)

               producer
!
Message(“Hi
there”,
routingId)
               




Wednesday, December 30, 2009
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
Akka Kernel


Wednesday, December 30, 2009
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
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"

           

level
=
"debug"
           

syslog_host
=
".."
           

syslog_server_name
=
".."
           </log>

Wednesday, December 30, 2009
Monitoring &
                               Management
                               Provisioning
                                and more...
                     Part of commercial license
Wednesday, December 30, 2009
Learn more
                               http://akkasource.org




Wednesday, December 30, 2009
Professional help
      Consulting Training Mentoring

                         http://scalablesolutions.se
                          jonas@jonasboner.com
Wednesday, December 30, 2009
EOF
Wednesday, December 30, 2009

More Related Content

What's hot

Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
SANG WON PARK
 
Locking and Concurrency Control
Locking and Concurrency ControlLocking and Concurrency Control
Locking and Concurrency Control
Morgan Tocker
 
Making Apache Spark Better with Delta Lake
Making Apache Spark Better with Delta LakeMaking Apache Spark Better with Delta Lake
Making Apache Spark Better with Delta Lake
Databricks
 
IBM Spectrum Scale and Its Use for Content Management
 IBM Spectrum Scale and Its Use for Content Management IBM Spectrum Scale and Its Use for Content Management
IBM Spectrum Scale and Its Use for Content Management
Sandeep Patil
 
Multi-Datacenter Kafka - Strata San Jose 2017
Multi-Datacenter Kafka - Strata San Jose 2017Multi-Datacenter Kafka - Strata San Jose 2017
Multi-Datacenter Kafka - Strata San Jose 2017
Gwen (Chen) Shapira
 
A Deep Dive into Kafka Controller
A Deep Dive into Kafka ControllerA Deep Dive into Kafka Controller
A Deep Dive into Kafka Controller
confluent
 
Using AWS WAF and Lambda for Automatic Protection
Using AWS WAF and Lambda for Automatic ProtectionUsing AWS WAF and Lambda for Automatic Protection
Using AWS WAF and Lambda for Automatic Protection
Amazon Web Services
 
Scalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsScalability, Availability & Stability Patterns
Scalability, Availability & Stability Patterns
Jonas Bonér
 
Apache Kafka
Apache KafkaApache Kafka
Apache Kafka
Saroj Panyasrivanit
 
RocksDB Performance and Reliability Practices
RocksDB Performance and Reliability PracticesRocksDB Performance and Reliability Practices
RocksDB Performance and Reliability Practices
Yoshinori Matsunobu
 
Parquet - Data I/O - Philadelphia 2013
Parquet - Data I/O - Philadelphia 2013Parquet - Data I/O - Philadelphia 2013
Parquet - Data I/O - Philadelphia 2013
larsgeorge
 
Redis vs Infinispan | DevNation Tech Talk
Redis vs Infinispan | DevNation Tech TalkRedis vs Infinispan | DevNation Tech Talk
Redis vs Infinispan | DevNation Tech Talk
Red Hat Developers
 
Everything You Always Wanted to Know About Kafka’s Rebalance Protocol but Wer...
Everything You Always Wanted to Know About Kafka’s Rebalance Protocol but Wer...Everything You Always Wanted to Know About Kafka’s Rebalance Protocol but Wer...
Everything You Always Wanted to Know About Kafka’s Rebalance Protocol but Wer...
confluent
 
How netflix manages petabyte scale apache cassandra in the cloud
How netflix manages petabyte scale apache cassandra in the cloudHow netflix manages petabyte scale apache cassandra in the cloud
How netflix manages petabyte scale apache cassandra in the cloud
Vinay Kumar Chella
 
What is Apache Kafka and What is an Event Streaming Platform?
What is Apache Kafka and What is an Event Streaming Platform?What is Apache Kafka and What is an Event Streaming Platform?
What is Apache Kafka and What is an Event Streaming Platform?
confluent
 
A Tale of Two Data Centers: Kafka Streams Resiliency (Anna McDonald, Confluen...
A Tale of Two Data Centers: Kafka Streams Resiliency (Anna McDonald, Confluen...A Tale of Two Data Centers: Kafka Streams Resiliency (Anna McDonald, Confluen...
A Tale of Two Data Centers: Kafka Streams Resiliency (Anna McDonald, Confluen...
confluent
 
Advanced Caching Concepts @ Velocity NY 2015
Advanced Caching Concepts @ Velocity NY 2015Advanced Caching Concepts @ Velocity NY 2015
Advanced Caching Concepts @ Velocity NY 2015
Rakesh Chaudhary
 
(APP307) Leverage the Cloud with a Blue/Green Deployment Architecture | AWS r...
(APP307) Leverage the Cloud with a Blue/Green Deployment Architecture | AWS r...(APP307) Leverage the Cloud with a Blue/Green Deployment Architecture | AWS r...
(APP307) Leverage the Cloud with a Blue/Green Deployment Architecture | AWS r...
Amazon Web Services
 
MySQL Sharding: Tools and Best Practices for Horizontal Scaling
MySQL Sharding: Tools and Best Practices for Horizontal ScalingMySQL Sharding: Tools and Best Practices for Horizontal Scaling
MySQL Sharding: Tools and Best Practices for Horizontal Scaling
Mats Kindahl
 
Deploying Kafka Streams Applications with Docker and Kubernetes
Deploying Kafka Streams Applications with Docker and KubernetesDeploying Kafka Streams Applications with Docker and Kubernetes
Deploying Kafka Streams Applications with Docker and Kubernetes
confluent
 

What's hot (20)

Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
 
Locking and Concurrency Control
Locking and Concurrency ControlLocking and Concurrency Control
Locking and Concurrency Control
 
Making Apache Spark Better with Delta Lake
Making Apache Spark Better with Delta LakeMaking Apache Spark Better with Delta Lake
Making Apache Spark Better with Delta Lake
 
IBM Spectrum Scale and Its Use for Content Management
 IBM Spectrum Scale and Its Use for Content Management IBM Spectrum Scale and Its Use for Content Management
IBM Spectrum Scale and Its Use for Content Management
 
Multi-Datacenter Kafka - Strata San Jose 2017
Multi-Datacenter Kafka - Strata San Jose 2017Multi-Datacenter Kafka - Strata San Jose 2017
Multi-Datacenter Kafka - Strata San Jose 2017
 
A Deep Dive into Kafka Controller
A Deep Dive into Kafka ControllerA Deep Dive into Kafka Controller
A Deep Dive into Kafka Controller
 
Using AWS WAF and Lambda for Automatic Protection
Using AWS WAF and Lambda for Automatic ProtectionUsing AWS WAF and Lambda for Automatic Protection
Using AWS WAF and Lambda for Automatic Protection
 
Scalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsScalability, Availability & Stability Patterns
Scalability, Availability & Stability Patterns
 
Apache Kafka
Apache KafkaApache Kafka
Apache Kafka
 
RocksDB Performance and Reliability Practices
RocksDB Performance and Reliability PracticesRocksDB Performance and Reliability Practices
RocksDB Performance and Reliability Practices
 
Parquet - Data I/O - Philadelphia 2013
Parquet - Data I/O - Philadelphia 2013Parquet - Data I/O - Philadelphia 2013
Parquet - Data I/O - Philadelphia 2013
 
Redis vs Infinispan | DevNation Tech Talk
Redis vs Infinispan | DevNation Tech TalkRedis vs Infinispan | DevNation Tech Talk
Redis vs Infinispan | DevNation Tech Talk
 
Everything You Always Wanted to Know About Kafka’s Rebalance Protocol but Wer...
Everything You Always Wanted to Know About Kafka’s Rebalance Protocol but Wer...Everything You Always Wanted to Know About Kafka’s Rebalance Protocol but Wer...
Everything You Always Wanted to Know About Kafka’s Rebalance Protocol but Wer...
 
How netflix manages petabyte scale apache cassandra in the cloud
How netflix manages petabyte scale apache cassandra in the cloudHow netflix manages petabyte scale apache cassandra in the cloud
How netflix manages petabyte scale apache cassandra in the cloud
 
What is Apache Kafka and What is an Event Streaming Platform?
What is Apache Kafka and What is an Event Streaming Platform?What is Apache Kafka and What is an Event Streaming Platform?
What is Apache Kafka and What is an Event Streaming Platform?
 
A Tale of Two Data Centers: Kafka Streams Resiliency (Anna McDonald, Confluen...
A Tale of Two Data Centers: Kafka Streams Resiliency (Anna McDonald, Confluen...A Tale of Two Data Centers: Kafka Streams Resiliency (Anna McDonald, Confluen...
A Tale of Two Data Centers: Kafka Streams Resiliency (Anna McDonald, Confluen...
 
Advanced Caching Concepts @ Velocity NY 2015
Advanced Caching Concepts @ Velocity NY 2015Advanced Caching Concepts @ Velocity NY 2015
Advanced Caching Concepts @ Velocity NY 2015
 
(APP307) Leverage the Cloud with a Blue/Green Deployment Architecture | AWS r...
(APP307) Leverage the Cloud with a Blue/Green Deployment Architecture | AWS r...(APP307) Leverage the Cloud with a Blue/Green Deployment Architecture | AWS r...
(APP307) Leverage the Cloud with a Blue/Green Deployment Architecture | AWS r...
 
MySQL Sharding: Tools and Best Practices for Horizontal Scaling
MySQL Sharding: Tools and Best Practices for Horizontal ScalingMySQL Sharding: Tools and Best Practices for Horizontal Scaling
MySQL Sharding: Tools and Best Practices for Horizontal Scaling
 
Deploying Kafka Streams Applications with Docker and Kubernetes
Deploying Kafka Streams Applications with Docker and KubernetesDeploying Kafka Streams Applications with Docker and Kubernetes
Deploying Kafka Streams Applications with Docker and Kubernetes
 

Viewers also liked

Modernizing Infrastructures for Fast Data with Spark, Kafka, Cassandra, React...
Modernizing Infrastructures for Fast Data with Spark, Kafka, Cassandra, React...Modernizing Infrastructures for Fast Data with Spark, Kafka, Cassandra, React...
Modernizing Infrastructures for Fast Data with Spark, Kafka, Cassandra, React...
Lightbend
 
Advanced akka features
Advanced akka featuresAdvanced akka features
Advanced akka features
Grzegorz Duda
 
Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
Konrad Malawski
 
Introducing Akka
Introducing AkkaIntroducing Akka
Introducing Akka
Jonas Bonér
 
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Lightbend
 
Reactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka StreamsReactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka Streams
Konrad Malawski
 
Akka in Production - ScalaDays 2015
Akka in Production - ScalaDays 2015Akka in Production - ScalaDays 2015
Akka in Production - ScalaDays 2015
Evan Chan
 
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
Chris Fregly
 

Viewers also liked (8)

Modernizing Infrastructures for Fast Data with Spark, Kafka, Cassandra, React...
Modernizing Infrastructures for Fast Data with Spark, Kafka, Cassandra, React...Modernizing Infrastructures for Fast Data with Spark, Kafka, Cassandra, React...
Modernizing Infrastructures for Fast Data with Spark, Kafka, Cassandra, React...
 
Advanced akka features
Advanced akka featuresAdvanced akka features
Advanced akka features
 
Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
 
Introducing Akka
Introducing AkkaIntroducing Akka
Introducing Akka
 
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
 
Reactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka StreamsReactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka Streams
 
Akka in Production - ScalaDays 2015
Akka in Production - ScalaDays 2015Akka in Production - ScalaDays 2015
Akka in Production - ScalaDays 2015
 
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
 

More from Jonas Bonér

We are drowning in complexity—can we do better?
We are drowning in complexity—can we do better?We are drowning in complexity—can we do better?
We are drowning in complexity—can we do better?
Jonas Bonér
 
Kalix: Tackling the The Cloud to Edge Continuum
Kalix: Tackling the The Cloud to Edge ContinuumKalix: Tackling the The Cloud to Edge Continuum
Kalix: Tackling the The Cloud to Edge Continuum
Jonas Bonér
 
The Reactive Principles: Design Principles For Cloud Native Applications
The Reactive Principles: Design Principles For Cloud Native ApplicationsThe Reactive Principles: Design Principles For Cloud Native Applications
The Reactive Principles: Design Principles For Cloud Native Applications
Jonas Bonér
 
Cloudstate—Towards Stateful Serverless
Cloudstate—Towards Stateful ServerlessCloudstate—Towards Stateful Serverless
Cloudstate—Towards Stateful Serverless
Jonas Bonér
 
Designing Events-first Microservices
Designing Events-first MicroservicesDesigning Events-first Microservices
Designing Events-first Microservices
Jonas Bonér
 
How Events Are Reshaping Modern Systems
How Events Are Reshaping Modern SystemsHow Events Are Reshaping Modern Systems
How Events Are Reshaping Modern Systems
Jonas Bonér
 
Reactive Microsystems: The Evolution of Microservices at Scale
Reactive Microsystems: The Evolution of Microservices at ScaleReactive Microsystems: The Evolution of Microservices at Scale
Reactive Microsystems: The Evolution of Microservices at Scale
Jonas Bonér
 
From Microliths To Microsystems
From Microliths To MicrosystemsFrom Microliths To Microsystems
From Microliths To Microsystems
Jonas Bonér
 
Without Resilience, Nothing Else Matters
Without Resilience, Nothing Else MattersWithout Resilience, Nothing Else Matters
Without Resilience, Nothing Else Matters
Jonas Bonér
 
Life Beyond the Illusion of Present
Life Beyond the Illusion of PresentLife Beyond the Illusion of Present
Life Beyond the Illusion of Present
Jonas Bonér
 
Go Reactive: Building Responsive, Resilient, Elastic & Message-Driven Systems
Go Reactive: Building Responsive, Resilient, Elastic & Message-Driven SystemsGo Reactive: Building Responsive, Resilient, Elastic & Message-Driven Systems
Go Reactive: Building Responsive, Resilient, Elastic & Message-Driven Systems
Jonas Bonér
 
Reactive Supply To Changing Demand
Reactive Supply To Changing DemandReactive Supply To Changing Demand
Reactive Supply To Changing Demand
Jonas Bonér
 
Building Reactive Systems with Akka (in Java 8 or Scala)
Building Reactive Systems with Akka (in Java 8 or Scala)Building Reactive Systems with Akka (in Java 8 or Scala)
Building Reactive Systems with Akka (in Java 8 or Scala)
Jonas Bonér
 
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems
Go Reactive: Event-Driven, Scalable, Resilient & Responsive SystemsGo Reactive: Event-Driven, Scalable, Resilient & Responsive Systems
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems
Jonas Bonér
 
Building Scalable, Highly Concurrent & Fault Tolerant Systems - Lessons Learned
Building Scalable, Highly Concurrent & Fault Tolerant Systems -  Lessons LearnedBuilding Scalable, Highly Concurrent & Fault Tolerant Systems -  Lessons Learned
Building Scalable, Highly Concurrent & Fault Tolerant Systems - Lessons Learned
Jonas Bonér
 
Event Driven-Architecture from a Scalability perspective
Event Driven-Architecture from a Scalability perspectiveEvent Driven-Architecture from a Scalability perspective
Event Driven-Architecture from a Scalability perspective
Jonas Bonér
 
State: You're Doing It Wrong - Alternative Concurrency Paradigms For The JVM
State: You're Doing It Wrong - Alternative Concurrency Paradigms For The JVMState: You're Doing It Wrong - Alternative Concurrency Paradigms For The JVM
State: You're Doing It Wrong - Alternative Concurrency Paradigms For The JVM
Jonas Bonér
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
Jonas Bonér
 

More from Jonas Bonér (18)

We are drowning in complexity—can we do better?
We are drowning in complexity—can we do better?We are drowning in complexity—can we do better?
We are drowning in complexity—can we do better?
 
Kalix: Tackling the The Cloud to Edge Continuum
Kalix: Tackling the The Cloud to Edge ContinuumKalix: Tackling the The Cloud to Edge Continuum
Kalix: Tackling the The Cloud to Edge Continuum
 
The Reactive Principles: Design Principles For Cloud Native Applications
The Reactive Principles: Design Principles For Cloud Native ApplicationsThe Reactive Principles: Design Principles For Cloud Native Applications
The Reactive Principles: Design Principles For Cloud Native Applications
 
Cloudstate—Towards Stateful Serverless
Cloudstate—Towards Stateful ServerlessCloudstate—Towards Stateful Serverless
Cloudstate—Towards Stateful Serverless
 
Designing Events-first Microservices
Designing Events-first MicroservicesDesigning Events-first Microservices
Designing Events-first Microservices
 
How Events Are Reshaping Modern Systems
How Events Are Reshaping Modern SystemsHow Events Are Reshaping Modern Systems
How Events Are Reshaping Modern Systems
 
Reactive Microsystems: The Evolution of Microservices at Scale
Reactive Microsystems: The Evolution of Microservices at ScaleReactive Microsystems: The Evolution of Microservices at Scale
Reactive Microsystems: The Evolution of Microservices at Scale
 
From Microliths To Microsystems
From Microliths To MicrosystemsFrom Microliths To Microsystems
From Microliths To Microsystems
 
Without Resilience, Nothing Else Matters
Without Resilience, Nothing Else MattersWithout Resilience, Nothing Else Matters
Without Resilience, Nothing Else Matters
 
Life Beyond the Illusion of Present
Life Beyond the Illusion of PresentLife Beyond the Illusion of Present
Life Beyond the Illusion of Present
 
Go Reactive: Building Responsive, Resilient, Elastic & Message-Driven Systems
Go Reactive: Building Responsive, Resilient, Elastic & Message-Driven SystemsGo Reactive: Building Responsive, Resilient, Elastic & Message-Driven Systems
Go Reactive: Building Responsive, Resilient, Elastic & Message-Driven Systems
 
Reactive Supply To Changing Demand
Reactive Supply To Changing DemandReactive Supply To Changing Demand
Reactive Supply To Changing Demand
 
Building Reactive Systems with Akka (in Java 8 or Scala)
Building Reactive Systems with Akka (in Java 8 or Scala)Building Reactive Systems with Akka (in Java 8 or Scala)
Building Reactive Systems with Akka (in Java 8 or Scala)
 
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems
Go Reactive: Event-Driven, Scalable, Resilient & Responsive SystemsGo Reactive: Event-Driven, Scalable, Resilient & Responsive Systems
Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems
 
Building Scalable, Highly Concurrent & Fault Tolerant Systems - Lessons Learned
Building Scalable, Highly Concurrent & Fault Tolerant Systems -  Lessons LearnedBuilding Scalable, Highly Concurrent & Fault Tolerant Systems -  Lessons Learned
Building Scalable, Highly Concurrent & Fault Tolerant Systems - Lessons Learned
 
Event Driven-Architecture from a Scalability perspective
Event Driven-Architecture from a Scalability perspectiveEvent Driven-Architecture from a Scalability perspective
Event Driven-Architecture from a Scalability perspective
 
State: You're Doing It Wrong - Alternative Concurrency Paradigms For The JVM
State: You're Doing It Wrong - Alternative Concurrency Paradigms For The JVMState: You're Doing It Wrong - Alternative Concurrency Paradigms For The JVM
State: You're Doing It Wrong - Alternative Concurrency Paradigms For The JVM
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 

Recently uploaded

Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
Daiki Mogmet Ito
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
Tomaz Bratanic
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 

Recently uploaded (20)

Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 

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

  • 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. State 2 Wednesday, December 30, 2009
  • 3. The devil is in the state 3 Wednesday, December 30, 2009
  • 4. Wrong, let me rephrase 4 Wednesday, December 30, 2009
  • 5. The devil is in the mutable state 5 Wednesday, December 30, 2009
  • 6. Definitions & Philosophy 6 Wednesday, December 30, 2009
  • 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. What is an Identity? A stable logical entity associated with a series of different Values over time Wednesday, December 30, 2009
  • 9. What is State? The Value an entity with a specific Identity has at a particular point in time Wednesday, December 30, 2009
  • 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. The Problem The unification Of Identity & Value They are not the same Wednesday, December 30, 2009
  • 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. The problems with Shared State Concurrency Wednesday, December 30, 2009
  • 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. Shared-State Concurrency is incredibly hard > Inherentlyvery hard to use reliably > Even the experts get it wrong Wednesday, December 30, 2009
  • 16. Example of Shared-State Concurrency Transfer funds between bank accounts Wednesday, December 30, 2009
  • 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. 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. It’s still broken Transfers are not atomic Wednesday, December 30, 2009
  • 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. 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. Might lead to DEADLOCK Darn, this is really hard!!! Wednesday, December 30, 2009
  • 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. 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. It’s just too hard Wednesday, December 30, 2009
  • 26. Java bet on the wrong horse? Perhaps, but we’re not completely screwed There are alternatives Wednesday, December 30, 2009
  • 27. We need better and more high-level abstractions Wednesday, December 30, 2009
  • 28. Alternative Paradigms >Software Transactional Memory (STM) >Message-Passing Concurrency (Actors) >Dataflow Concurrency 28 Wednesday, December 30, 2009
  • 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. 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. Actors • Implements Message-Passing Concurrency • Share NOTHING • Isolated lightweight processes • Communicates through messages • Asynchronous and non-blocking Wednesday, December 30, 2009
  • 33. Actor Model of Concurrency • No shared state … hence, nothing to synchronize. • Each actor has a mailbox (message queue) Wednesday, December 30, 2009
  • 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. 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. 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. 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. 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. Fault tolerance & Scalablility Akka Transactors Supervisor hierarchies STM Distributed Secure Persistent RESTful Comet Wednesday, December 30, 2009
  • 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. Actors anonymous val
worker
=
actor
{ 

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

...
//
init }
receive
{ 

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

def
receive
=
{ 



case
User(name)
=>
 





//
use
implicit
sender 





sender.get
!
(“Hi
”
+
name) 

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

def
receive
=
{ 



case
User(name)
=>
 





//
use
reply 





reply(“Hi
”
+
name) 

} } Wednesday, December 30, 2009
  • 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. Reply class
SomeActor
extends
Actor
{ 

def
receive
=
{ 



case
User(name)
=>
 





//
use
reply 





reply(“Hi
”
+
name) 

} } Wednesday, December 30, 2009
  • 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. Start / Stop actor.start actor.stop spawn(classOf[MyActor]) //
callback override
def
shutdown
=
{ 

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

private
int
counter
=
0; 

public
void
count()
{ 



counter++; 



System.out.println(counter); 

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

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

.newInstance( 



Counter.class,
 



CounterImpl.class,
 



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

private
var
counter
=
0 

def
count
=
{ 



counter
+=
1 



println(counter) 

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



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

private
var
counter
=
0 

@oneway
def
count
=
{ 



counter
+=
1 



println(counter) 

} } Wednesday, December 30, 2009
  • 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. Actors: config <akka> 

version
=
"0.6" 

<actor> 



timeout
=
5000 



serialize‐messages
=
off 

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

def
newThreadBasedDispatcher(actor:
Actor) 

def
newExecutorBasedEventDrivenDispatcher(name:String) 
 

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

dispatcher
=
Dispatchers 



.newThreadBasedDispatcher(this) 

 

... } actor.dispatcher
=
dispatcher
//
before
started Wednesday, December 30, 2009
  • 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. When to use which dispatcher? Wednesday, December 30, 2009
  • 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. 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. 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. MessageQueues Unbounded LinkedBlockingQueue Bounded LinkedBlockingQueue Bounded ArrayBlockingQueue Bounded SynchronousQueue Plus different options per queue Wednesday, December 30, 2009
  • 69. Stolen from Erlang Wednesday, December 30, 2009
  • 70. 9 nines Wednesday, December 30, 2009
  • 71. Supervisor hierarchies OneForOne Wednesday, December 30, 2009
  • 72. Supervisor hierarchies AllForOne Wednesday, December 30, 2009
  • 73. Fault handlers AllForOneStrategy( 

maxNrOfRetries,
 

withinTimeRange) OneForOneStrategy( 

maxNrOfRetries,
 

withinTimeRange) Wednesday, December 30, 2009
  • 74. Linking link(actor)
 unlink(actor)
 startLink(actor) spawnLink(classOf[MyActor]) Wednesday, December 30, 2009
  • 75. trapExit trapExit
=
List( 
classOf[ServiceException],
 
classOf[PersistenceException]) Wednesday, December 30, 2009
  • 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. 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. 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. 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. ActorRegistry val
actors
=
 

ActorRegistry.actorsFor(FQN) val
actors
=
 

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

...
//
init
the
actor } init is called on startup Wednesday, December 30, 2009
  • 82. Akka Remote Actors Wednesday, December 30, 2009
  • 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. Remote Server //
use
host
&
port
in
config val
server
=
new
RemoteServer server.start("localhost",
9999) Wednesday, December 30, 2009
  • 85. Remote actors spawnRemote(classOf[MyActor],
host,
port)
 startLinkRemote(actor,
host,
port) spawnLinkRemote(classOf[MyActor],
host,
port) Wednesday, December 30, 2009
  • 86. Remote config <akka> 

<remote> 



service
=
on 



hostname
=
"localhost" 



port
=
9999 



connection‐timeout
=
1000 

</remote> </akka> Wednesday, December 30, 2009
  • 88. Software Transactional Memory (STM) 88 Wednesday, December 30, 2009
  • 89. What is STM? 89 Wednesday, December 30, 2009
  • 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. STM: overview > Transactions can nest > Transactions compose (yipee!!) 


atomic
{


 




..


 




atomic
{



 






..



 




}

 


}

 Wednesday, December 30, 2009
  • 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. Akka STM is based on the ideas of Clojure STM 93 Wednesday, December 30, 2009
  • 94. 2 things: 1. Managed References 2. Persistent Datastructures 94 Wednesday, December 30, 2009
  • 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. 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. 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. 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. Managed References for
{ 

users
<‐
usersRef 

user

<‐
users 

roles
<‐
rolesRef 

role

<‐
roles 

if
user.hasRole(role) }
{ 

...
//
do
stuff } Wednesday, December 30, 2009
  • 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. 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. Bit-partitioned hash trie Bit-partitioned hash tries Copyright Rich Hickey 2009 Wednesday, December 30, 2009
  • 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. 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. 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. 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. 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. 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. STM: declarative Java API @transactionrequired class
UserRegistry
{ 


 } Wednesday, December 30, 2009
  • 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. 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. STM: monadic API val
userStorage
=
 

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

userStorage.put(user.name,
user) }
 Wednesday, December 30, 2009
  • 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. STM: config <akka> 

<stm> 



service
=
on 



distributed
=
off 

</stm> </akka> Wednesday, December 30, 2009
  • 115. STM: disable TransactionManagement.disableTransactions Wednesday, December 30, 2009
  • 117. Serializers ScalaJSON JavaJSON Protobuf SBinary Java Wednesday, December 30, 2009
  • 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. 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. 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. 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
  • 123. Persistence • Pluggable storage backend - Cassandra - MongoDB - Redis • Map, Vector and Ref abstraction • MVCC • Works together with STM Wednesday, December 30, 2009
  • 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. 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. 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. 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. 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
  • 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. REST: config <akka> 

<rest> 



service
=
on 



hostname
=
“localhost” 



port
=
9998 

</rest> </akka> Wednesday, December 30, 2009
  • 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. Boot config <akka> 

boot
=
["sample.rest.Boot",
 









"sample.comet.Boot"]
 

... </akka> Wednesday, December 30, 2009
  • 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. 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
  • 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. 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. Security: config <akka> 

<rest> 



service
=
on 



hostname
=
“localhost” 



port
=
9998 



filters
=
[“AkkaSecurityFilterFactory”] 



authenticator
=
“SimpleAuthenticationService” 

</rest> </akka> Wednesday, December 30, 2009
  • 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. 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
  • 145. HotSwap actor
!
HotSwap(Some({ 

//
new
body 

case
Ping
=>
 



...
 

case
Pong
=>
 



...

 })) Wednesday, December 30, 2009
  • 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. 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
  • 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
  • 152. Akka as a library Using the Actor module Wednesday, December 30, 2009
  • 153. Akka as a library Add STM module Wednesday, December 30, 2009
  • 154. Akka as a library Add Persistence module as a Cache Wednesday, December 30, 2009
  • 155. Akka as a library Add Persistence module as primary SoR Wednesday, December 30, 2009
  • 156. Akka as a library Add REST and Comet modules Wednesday, December 30, 2009
  • 157. Akka as stand-alone Kernel Wednesday, December 30, 2009
  • 158. Logging <log> 

console
=
on 

filename
=
"./logs/akka.log" 

roll
=
"daily"
 

level
=
"debug" 

syslog_host
=
".." 

syslog_server_name
=
".." </log> Wednesday, December 30, 2009
  • 159. Monitoring & Management Provisioning and more... Part of commercial license Wednesday, December 30, 2009
  • 160. Learn more http://akkasource.org Wednesday, December 30, 2009
  • 161. Professional help Consulting Training Mentoring http://scalablesolutions.se jonas@jonasboner.com Wednesday, December 30, 2009