SlideShare a Scribd company logo
1 of 162
Download to read offline
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

Building Stream Infrastructure across Multiple Data Centers with Apache Kafka
Building Stream Infrastructure across Multiple Data Centers with Apache KafkaBuilding Stream Infrastructure across Multiple Data Centers with Apache Kafka
Building Stream Infrastructure across Multiple Data Centers with Apache KafkaGuozhang Wang
 
Same plan different performance
Same plan different performanceSame plan different performance
Same plan different performanceMauro Pagano
 
Threads in Operating System | Multithreading | Interprocess Communication
Threads in Operating System | Multithreading | Interprocess CommunicationThreads in Operating System | Multithreading | Interprocess Communication
Threads in Operating System | Multithreading | Interprocess CommunicationShivam Mitra
 
OpenNebulaConf2015 2.02 Backing up your VM’s with Bacula - Alberto García
OpenNebulaConf2015 2.02 Backing up your VM’s with Bacula - Alberto GarcíaOpenNebulaConf2015 2.02 Backing up your VM’s with Bacula - Alberto García
OpenNebulaConf2015 2.02 Backing up your VM’s with Bacula - Alberto GarcíaOpenNebula Project
 
Practical examples of using extended events
Practical examples of using extended eventsPractical examples of using extended events
Practical examples of using extended eventsDean Richards
 
Curso de Sistemas Operativos - Unidad Procesos e Hilos
Curso de Sistemas Operativos - Unidad Procesos e HilosCurso de Sistemas Operativos - Unidad Procesos e Hilos
Curso de Sistemas Operativos - Unidad Procesos e HilosJuan Rafael Alvarez Correa
 
Ash architecture and advanced usage rmoug2014
Ash architecture and advanced usage rmoug2014Ash architecture and advanced usage rmoug2014
Ash architecture and advanced usage rmoug2014John Beresniewicz
 
Server system architecture
Server system architectureServer system architecture
Server system architectureFaiza Hafeez
 
Bp101-Can Domino Be Hacked
Bp101-Can Domino Be HackedBp101-Can Domino Be Hacked
Bp101-Can Domino Be HackedHoward Greenberg
 
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Aaron Shilo
 
vSAN architecture components
vSAN architecture componentsvSAN architecture components
vSAN architecture componentsDavid Pasek
 
Achieve Extreme Simplicity and Superior Price/Performance with Greenplum Buil...
Achieve Extreme Simplicity and Superior Price/Performance with Greenplum Buil...Achieve Extreme Simplicity and Superior Price/Performance with Greenplum Buil...
Achieve Extreme Simplicity and Superior Price/Performance with Greenplum Buil...VMware Tanzu
 
Advanced Operating System Lecture Notes
Advanced Operating System Lecture NotesAdvanced Operating System Lecture Notes
Advanced Operating System Lecture NotesAnirudhan Guru
 
How Development Teams Cut Costs with ScyllaDB.pdf
How Development Teams Cut Costs with ScyllaDB.pdfHow Development Teams Cut Costs with ScyllaDB.pdf
How Development Teams Cut Costs with ScyllaDB.pdfScyllaDB
 

What's hot (20)

Building Stream Infrastructure across Multiple Data Centers with Apache Kafka
Building Stream Infrastructure across Multiple Data Centers with Apache KafkaBuilding Stream Infrastructure across Multiple Data Centers with Apache Kafka
Building Stream Infrastructure across Multiple Data Centers with Apache Kafka
 
Same plan different performance
Same plan different performanceSame plan different performance
Same plan different performance
 
Threads in Operating System | Multithreading | Interprocess Communication
Threads in Operating System | Multithreading | Interprocess CommunicationThreads in Operating System | Multithreading | Interprocess Communication
Threads in Operating System | Multithreading | Interprocess Communication
 
OpenNebulaConf2015 2.02 Backing up your VM’s with Bacula - Alberto García
OpenNebulaConf2015 2.02 Backing up your VM’s with Bacula - Alberto GarcíaOpenNebulaConf2015 2.02 Backing up your VM’s with Bacula - Alberto García
OpenNebulaConf2015 2.02 Backing up your VM’s with Bacula - Alberto García
 
Operating system - Deadlock
Operating system - DeadlockOperating system - Deadlock
Operating system - Deadlock
 
Practical examples of using extended events
Practical examples of using extended eventsPractical examples of using extended events
Practical examples of using extended events
 
Deadlocks in operating system
Deadlocks in operating systemDeadlocks in operating system
Deadlocks in operating system
 
Curso de Sistemas Operativos - Unidad Procesos e Hilos
Curso de Sistemas Operativos - Unidad Procesos e HilosCurso de Sistemas Operativos - Unidad Procesos e Hilos
Curso de Sistemas Operativos - Unidad Procesos e Hilos
 
Ash architecture and advanced usage rmoug2014
Ash architecture and advanced usage rmoug2014Ash architecture and advanced usage rmoug2014
Ash architecture and advanced usage rmoug2014
 
Server system architecture
Server system architectureServer system architecture
Server system architecture
 
Deep Dive on Amazon Redshift
Deep Dive on Amazon RedshiftDeep Dive on Amazon Redshift
Deep Dive on Amazon Redshift
 
Sophos XG Firewall
Sophos XG FirewallSophos XG Firewall
Sophos XG Firewall
 
Deadlock Presentation
Deadlock PresentationDeadlock Presentation
Deadlock Presentation
 
Bp101-Can Domino Be Hacked
Bp101-Can Domino Be HackedBp101-Can Domino Be Hacked
Bp101-Can Domino Be Hacked
 
Concurrency control
Concurrency controlConcurrency control
Concurrency control
 
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
 
vSAN architecture components
vSAN architecture componentsvSAN architecture components
vSAN architecture components
 
Achieve Extreme Simplicity and Superior Price/Performance with Greenplum Buil...
Achieve Extreme Simplicity and Superior Price/Performance with Greenplum Buil...Achieve Extreme Simplicity and Superior Price/Performance with Greenplum Buil...
Achieve Extreme Simplicity and Superior Price/Performance with Greenplum Buil...
 
Advanced Operating System Lecture Notes
Advanced Operating System Lecture NotesAdvanced Operating System Lecture Notes
Advanced Operating System Lecture Notes
 
How Development Teams Cut Costs with ScyllaDB.pdf
How Development Teams Cut Costs with ScyllaDB.pdfHow Development Teams Cut Costs with ScyllaDB.pdf
How Development Teams Cut Costs with ScyllaDB.pdf
 

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 featuresGrzegorz Duda
 
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 StreamsKonrad Malawski
 
Akka in Production - ScalaDays 2015
Akka in Production - ScalaDays 2015Akka in Production - ScalaDays 2015
Akka in Production - ScalaDays 2015Evan 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

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 ApplicationsJonas Bonér
 
Cloudstate—Towards Stateful Serverless
Cloudstate—Towards Stateful ServerlessCloudstate—Towards Stateful Serverless
Cloudstate—Towards Stateful ServerlessJonas Bonér
 
Designing Events-first Microservices
Designing Events-first MicroservicesDesigning Events-first Microservices
Designing Events-first MicroservicesJonas Bonér
 
How Events Are Reshaping Modern Systems
How Events Are Reshaping Modern SystemsHow Events Are Reshaping Modern Systems
How Events Are Reshaping Modern SystemsJonas 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 ScaleJonas Bonér
 
From Microliths To Microsystems
From Microliths To MicrosystemsFrom Microliths To Microsystems
From Microliths To MicrosystemsJonas Bonér
 
Without Resilience, Nothing Else Matters
Without Resilience, Nothing Else MattersWithout Resilience, Nothing Else Matters
Without Resilience, Nothing Else MattersJonas Bonér
 
Life Beyond the Illusion of Present
Life Beyond the Illusion of PresentLife Beyond the Illusion of Present
Life Beyond the Illusion of PresentJonas 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 SystemsJonas Bonér
 
Reactive Supply To Changing Demand
Reactive Supply To Changing DemandReactive Supply To Changing Demand
Reactive Supply To Changing DemandJonas 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 SystemsJonas 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 LearnedJonas 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 perspectiveJonas Bonér
 
Scalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsScalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsJonas 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 JVMJonas 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 (17)

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
 
Scalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsScalability, Availability & Stability Patterns
Scalability, Availability & Stability Patterns
 
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

activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfJamie (Taka) Wang
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
All in AI: LLM Landscape & RAG in 2024 with Mark Ryan (Google) & Jerry Liu (L...
All in AI: LLM Landscape & RAG in 2024 with Mark Ryan (Google) & Jerry Liu (L...All in AI: LLM Landscape & RAG in 2024 with Mark Ryan (Google) & Jerry Liu (L...
All in AI: LLM Landscape & RAG in 2024 with Mark Ryan (Google) & Jerry Liu (L...Daniel Zivkovic
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxGDSC PJATK
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
99.99% of Your Traces Are (Probably) Trash (SRECon NA 2024).pdf
99.99% of Your Traces  Are (Probably) Trash (SRECon NA 2024).pdf99.99% of Your Traces  Are (Probably) Trash (SRECon NA 2024).pdf
99.99% of Your Traces Are (Probably) Trash (SRECon NA 2024).pdfPaige Cruz
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
Governance in SharePoint Premium:What's in the box?
Governance in SharePoint Premium:What's in the box?Governance in SharePoint Premium:What's in the box?
Governance in SharePoint Premium:What's in the box?Juan Carlos Gonzalez
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
The Kubernetes Gateway API and its role in Cloud Native API Management
The Kubernetes Gateway API and its role in Cloud Native API ManagementThe Kubernetes Gateway API and its role in Cloud Native API Management
The Kubernetes Gateway API and its role in Cloud Native API ManagementNuwan Dias
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxMatsuo Lab
 
UiPath Clipboard AI: "A TIME Magazine Best Invention of 2023 Unveiled"
UiPath Clipboard AI: "A TIME Magazine Best Invention of 2023 Unveiled"UiPath Clipboard AI: "A TIME Magazine Best Invention of 2023 Unveiled"
UiPath Clipboard AI: "A TIME Magazine Best Invention of 2023 Unveiled"DianaGray10
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-pyJamie (Taka) Wang
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
UiPath Studio Web workshop series - Day 5
UiPath Studio Web workshop series - Day 5UiPath Studio Web workshop series - Day 5
UiPath Studio Web workshop series - Day 5DianaGray10
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 

Recently uploaded (20)

activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
All in AI: LLM Landscape & RAG in 2024 with Mark Ryan (Google) & Jerry Liu (L...
All in AI: LLM Landscape & RAG in 2024 with Mark Ryan (Google) & Jerry Liu (L...All in AI: LLM Landscape & RAG in 2024 with Mark Ryan (Google) & Jerry Liu (L...
All in AI: LLM Landscape & RAG in 2024 with Mark Ryan (Google) & Jerry Liu (L...
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptx
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
99.99% of Your Traces Are (Probably) Trash (SRECon NA 2024).pdf
99.99% of Your Traces  Are (Probably) Trash (SRECon NA 2024).pdf99.99% of Your Traces  Are (Probably) Trash (SRECon NA 2024).pdf
99.99% of Your Traces Are (Probably) Trash (SRECon NA 2024).pdf
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
Governance in SharePoint Premium:What's in the box?
Governance in SharePoint Premium:What's in the box?Governance in SharePoint Premium:What's in the box?
Governance in SharePoint Premium:What's in the box?
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
The Kubernetes Gateway API and its role in Cloud Native API Management
The Kubernetes Gateway API and its role in Cloud Native API ManagementThe Kubernetes Gateway API and its role in Cloud Native API Management
The Kubernetes Gateway API and its role in Cloud Native API Management
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptx
 
UiPath Clipboard AI: "A TIME Magazine Best Invention of 2023 Unveiled"
UiPath Clipboard AI: "A TIME Magazine Best Invention of 2023 Unveiled"UiPath Clipboard AI: "A TIME Magazine Best Invention of 2023 Unveiled"
UiPath Clipboard AI: "A TIME Magazine Best Invention of 2023 Unveiled"
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-py
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
UiPath Studio Web workshop series - Day 5
UiPath Studio Web workshop series - Day 5UiPath Studio Web workshop series - Day 5
UiPath Studio Web workshop series - Day 5
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 

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