Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

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

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

Akka is here to change that.

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

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

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

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

E0b5787d1a1935a2800e0bbffc81c196?s=128

Jonas Bonér

December 29, 2009
Tweet

Transcript

  1. Jonas Bonér Akka: Simpler Scalability, Fault-tolerance, Concurrency & Remoting through

    Actors http://akkasource.org Scalable Solutions AB Copyright 2009 - Scalable Solutions AB Wednesday, December 30, 2009
  2. 2 State Wednesday, December 30, 2009

  3. 3 The devil is in the state Wednesday, December 30,

    2009
  4. 4 Wrong, let me rephrase Wednesday, December 30, 2009

  5. 5 The devil is in the mutable state Wednesday, December

    30, 2009
  6. 6 Definitions & Philosophy 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 >Inherently very 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? >Java won’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. 28 Alternative Paradigms >Software Transactional Memory (STM) >Message-Passing Concurrency (Actors)

    >Dataflow Concurrency Wednesday, December 30, 2009
  29. Actors Wednesday, December 30, 2009

  30. •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 Actors Wednesday, December 30, 2009
  31. “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# Alan Kay (father of SmallTalk and OOP) 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. • Non-blocking send • Blocking receive • Messages are immutable

    • Highly performant and scalable • SEDA-style (Staged Event-Driven Architecture) Actor Model of Concurrency 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. > Akka (Java/Scala) > Kilim (Java) > Jetlang (Java) >

    Actor’s Guild (Java) > ActorFoundry (Java) > Actorom (Java) > FunctionalJava (Java) > GParallelizer (Groovy) > Fan Actors (Fan) Actor libs for the JVM Wednesday, December 30, 2009
  39. Akka Transactors Supervisor hierarchies STM Persistent Fault tolerance & Scalablility

    Distributed RESTful Comet Secure Wednesday, December 30, 2009
  40. case
object
Tick class
Counter
extends
Actor
{ 

private
var
counter
=
0 

def
receive
=
{ 



case
Tick
=>
 





counter
+=
1 





println(counter) 

} } Actors

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

case
Work(fn)
=>
fn() } Actors anonymous Wednesday, December 30, 2009

  42. val
worker
=
actor
{ 

...
//
init }
receive
{ 

case
Work(fn)
=>
fn() } Actors anonymous Wednesday, December 30,

    2009
  43. //
fire‐forget
 counter
!
Tick
 Send: ! Wednesday, December 30, 2009

  44. class
SomeActor
extends
Actor
{ 

def
receive
=
{ 



case
User(name)
=>
 





//
use
implicit
sender 





sender.get
!
(“Hi
”
+
name) 

} } Reply Wednesday, December

    30, 2009
  45. class
SomeActor
extends
Actor
{ 

def
receive
=
{ 



case
User(name)
=>
 





//
use
reply 





reply(“Hi
”
+
name) 

} } Reply Wednesday, December

    30, 2009
  46. //
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”)) Send: !! Wednesday,

    December 30, 2009
  47. class
SomeActor
extends
Actor
{ 

def
receive
=
{ 



case
User(name)
=>
 





//
use
reply 





reply(“Hi
”
+
name) 

} } Reply Wednesday, December

    30, 2009
  48. class
SomeActor
extends
Actor
{ 

def
receive
=
{ 



case
User(name)
=>
 





//
store
away
the
sender
future 





//
to
resolve
later
or
 





//
somewhere
else 





...
=
senderFuture 

} } Reply

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

...
//
clean
up
before
shutdown
 } Start / Stop

    Wednesday, December 30, 2009
  50. public
class
Counter
{ 

private
int
counter
=
0; 

public
void
count()
{ 



counter++; 



System.out.println(counter); 

} } Active Objects: Java

    Wednesday, December 30, 2009
  51. Counter
counter
=
(Counter)ActiveObject 

.newInstance(Counter.class,
1000); Create: POJO Wednesday, December 30, 2009

  52. Counter
counter
=
(Counter)ActiveObject 

.newInstance( 



Counter.class,
 



CounterImpl.class,
 



1000); Create: Interface & Implementation Wednesday,

    December 30, 2009
  53. class
Counter
{ 

private
var
counter
=
0 

def
count
=
{ 



counter
+=
1 



println(counter) 

} } Active Objects Wednesday,

    December 30, 2009
  54. val
counter
=
ActiveObject.newInstance( 



classOf[Counter],
1000) Create: POSO Wednesday, December 30, 2009

  55. counter.count Send Wednesday, December 30, 2009

  56. @oneway class
Counter
{ 

private
var
counter
=
0 

@oneway
def
count
=
{ 



counter
+=
1 



println(counter) 

} } Wednesday, December

    30, 2009
  57. //
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”) Immutable messages

    Wednesday, December 30, 2009
  58. <akka> 

version
=
"0.6" 

<actor> 



timeout
=
5000 



serialize‐messages
=
off 

</actor> </akka> Actors: config Wednesday,

    December 30, 2009
  59. Akka Dispatchers Wednesday, December 30, 2009

  60. class
Dispatchers
{ 

def
newThreadBasedDispatcher(actor:
Actor) 

def
newExecutorBasedEventDrivenDispatcher(name:String) 
 

... } Dispatchers Wednesday, December 30,

    2009
  61. class
MyActor
extends
Actor
{ 

dispatcher
=
Dispatchers 



.newThreadBasedDispatcher(this) 

 

... } actor.dispatcher
=
dispatcher
//
before
started Set dispatcher Wednesday,

    December 30, 2009
  62. val
dispatcher
= 

Dispatchers.newExecutorBasedEventDrivenDispatcher

 
 
 



.withNewThreadPoolWithBoundedBlockingQueue(100) 



.setCorePoolSize(16) 



.setMaxPoolSize(128) 



.setKeepAliveTimeInMillis(60000) 



.setRejectionPolicy(new
CallerRunsPolicy) 



.buildThreadPool

    EventBasedDispatcher Fluent DSL 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
  68. Akka Supervision 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. AllForOneStrategy( 

maxNrOfRetries,
 

withinTimeRange) OneForOneStrategy( 

maxNrOfRetries,
 

withinTimeRange) Fault handlers Wednesday, December

    30, 2009
  74. link(actor)
 unlink(actor)
 startLink(actor) spawnLink(classOf[MyActor]) Linking Wednesday, December 30, 2009

  75. trapExit
=
List( 
classOf[ServiceException],
 
classOf[PersistenceException]) trapExit Wednesday, December 30, 2009

  76. class
Supervisor
extends
Actor
{ 

trapExit
=
List(classOf[Throwable]) 

faultHandler
=
 



Some(OneForOneStrategy(5,
5000)) 

def
receive
=
{ 



case
Register(actor)
=>
 





link(actor) 

} } Supervision

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

... 

override
def
preRestart(reason:
AnyRef)
=
{ 



...
//
clean
up
before
restart 

} 

override
def
postRestart(reason:
AnyRef)
=
{ 



...
//
init
after
restart 

} } Manage

    failure Wednesday, December 30, 2009
  78. 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)






 Declarative config

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

SupervisorConfig( 



RestartStrategy(AllForOne,
3,
10000), 




Supervise( 





actor1, 





LifeCycle(Permanent))
:: 




Supervise( 





actor2, 





LifeCycle(Temporary))
:: 



Nil))

    factory.newSupervisor.start Declarative config Wednesday, December 30, 2009
  80. val
actors
=
 

ActorRegistry.actorsFor(FQN) val
actors
=
 

ActorRegistry.actorsFor(classOf[..]) ActorRegistry Wednesday, December 30, 2009

  81. override
def
init
=
{ 

...
//
init
the
actor } Initialize actor init is called on startup

    Wednesday, December 30, 2009
  82. Akka Remote Actors Wednesday, December 30, 2009

  83. //
use
host
&
port
in
config RemoteNode.start RemoteNode.start(classLoader) RemoteNode.start( 

"localhost",
9999) RemoteNode.start( 

"localhost",
9999,
classLoader) Remote Server Wednesday,

    December 30, 2009
  84. //
use
host
&
port
in
config val
server
=
new
RemoteServer server.start("localhost",
9999) Remote Server Wednesday, December 30, 2009

  85. spawnRemote(classOf[MyActor],
host,
port)
 startLinkRemote(actor,
host,
port) spawnLinkRemote(classOf[MyActor],
host,
port) Remote actors Wednesday, December 30, 2009

  86. <akka> 

<remote> 



service
=
on 



hostname
=
"localhost" 



port
=
9999 



connection‐timeout
=
1000 

</remote> </akka> Remote config

    Wednesday, December 30, 2009
  87. Akka STM Wednesday, December 30, 2009

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

  89. 89 What is STM? 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. > Transactions can nest > Transactions compose (yipee!!) 


atomic
{


 




..




    




atomic
{



 






..



 




}

 


}

 STM: overview Wednesday, December 30, 2009
  92. 92 >All operations in scope of a transaction:  Need

    to be idempotent  Can’t have side-effects STM: restrictions Wednesday, December 30, 2009
  93. 93 Akka STM is based on the ideas of Clojure

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

    December 30, 2009
  95. • Typical OO: direct access to mutable objects Managed References

    Typical OO - Direct references to Mutable Objects • Unifies identity and value • Anything can change at any time • Consistency is a user problem • Encapsulation doesn’t solve concurrency problems ? ? 42 ? 6 :e :d :c :b :a foo • Managed Reference: separates Identity & Value Clojure - Indirect references to Immutable Objects 6 17 "ethel" "fred" 42 :e :d :c :b :a foo @foo • Separates identity and value Copyright Rich Hickey 2009 Wednesday, December 30, 2009
  96. • 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 Managed References Wednesday, December 30, 2009
  97. 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) Managed References Wednesday, December

    30, 2009
  98. val
usersRef
=
TransactionalState.newRef( 

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

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

users(name) } Managed References

    Wednesday, December 30, 2009
  99. for
{ 

users
<‐
usersRef 

user

<‐
users 

roles
<‐
rolesRef 

role

<‐
roles 

if
user.hasRole(role) }
{ 

...
//
do
stuff } Managed

    References Wednesday, December 30, 2009
  100. //
wraps
a
Ref
with
a
HashTrie
 val
users
=
TransactionalState.newMap[String,
User] //
wraps
a
Ref
with
a
Vector
 val
users
=
TransactionalState.newVector[User] Managed References convenience classes 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 Path Copying int count 15

    INode root HashMap int count 16 INode root HashMap Copyright Rich Hickey 2009 Approach • Programming with values is critical • 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 Wednesday, December 30, 2009
  104. 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] Persistent datastructures HashTrie

    ble oordination Wednesday, December 30, 2009
  105. 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] Persistent datastructures Vector

    ble oordination Wednesday, December 30, 2009
  106. • 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 Akka STM Wednesday, December 30, 2009
  107. class
UserRegistry
extends
Transactor
{ 

 

private
lazy
val
storage
=
 



TransactionalState.newMap[String,
User] 

def
receive
=
{ 



case
NewUser(user)
=> 





storage
+
(user.name
‐>
user) 



...
 

} }

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

makeTransactionRequired 

 

private
lazy
val
storage
=
 



TransactionalState.newMap[String,
User] 

def
receive
=
{ 



case
NewUser(user)
=> 





storage
+
(user.name
‐>
user) 



...
 

}

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


 } STM: declarative Java API Wednesday, December

    30, 2009
  110. 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 }

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

..
//
try
to
do
something }
orElse
{ 

..
//
if
tx
clash;
try
do
do
something
else } STM: high-order fun API

    Wednesday, December 30, 2009
  112. val
userStorage
=
 

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

userStorage.put(user.name,
user) }
 STM: monadic API Wednesday, December

    30, 2009
  113. val
userStorage
=
 

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

tx
<‐
Transaction() 

name
<‐
userNames 

if
userStorage.contains(name) }
yield
userStorage.get(name)
//
transactional STM: monadic API

    Wednesday, December 30, 2009
  114. <akka> 

<stm> 



service
=
on 



distributed
=
off 

</stm> </akka> STM: config Wednesday, December

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

  116. Akka Serialization Wednesday, December 30, 2009

  117. Serializers ScalaJSON JavaJSON Protobuf SBinary Java Wednesday, December 30, 2009

  118. val
foo
=
new
Foo val
json
=
Serializer.ScalaJSON.out(foo) val
fooCopy
=
 

Serializer.ScalaJSON.in(json).asInstanceOf[Foo] Serializers Scala 2 JSON & JSON

    2 Scala Wednesday, December 30, 2009
  119. 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) Serializers Scala

    2 Binary & Binary 2 Scala Wednesday, December 30, 2009
  120. val
pojo
=
 

ProtobufPOJO.getDefaultInstance.toBuilder 

.setId(1) 

.setName("protobuf") 

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

bytes,
classOf[ProtobufPOJO]) Serializers Protobuf

    Wednesday, December 30, 2009
  121. case
class
MyMessage( 

id:
String,
 

value:
Tuple2[String,
Int])
 

extends
Serializable.ScalaJSON val
message
=
MyMessage("id",
("hello",
34)) val
json
=
message.toJSON Serializable Wednesday, December 30,

    2009
  122. Akka Persistence Wednesday, December 30, 2009

  123. • Pluggable storage backend - Cassandra - MongoDB - Redis

    • Map, Vector and Ref abstraction • MVCC • Works together with STM Persistence 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. <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> Persistence: config 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
  129. Akka REST Wednesday, December 30, 2009

  130. @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>)

    



} 

}} RESTful actors Wednesday, December 30, 2009
  131. <akka> 

<rest> 



service
=
on 



hostname
=
“localhost” 



port
=
9998 

</rest> </akka> REST: config Wednesday,

    December 30, 2009
  132. 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 } Boot classes Wednesday, December 30, 2009
  133. <akka> 

boot
=
["sample.rest.Boot",
 









"sample.comet.Boot"]
 

... </akka> Boot config Wednesday, December 30,

    2009
  134. Akka Comet 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. @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(..)
=>
..} } Comet actors Wednesday, December 30, 2009
  137. Akka Security Wednesday, December 30, 2009

  138. 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))

    

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

@RolesAllowed(Array(“admin”)) 

def
resetSystem
=
 



(this
!!
Reset).getOrElse( 





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

def
receive
=
{ 



case
Reset
=>
... 

} } Security:

    usage Wednesday, December 30, 2009
  140. <akka> 

<rest> 



service
=
on 



hostname
=
“localhost” 



port
=
9998 



filters
=
[“AkkaSecurityFilterFactory”] 



authenticator
=
“SimpleAuthenticationService” 

</rest> </akka> Security:

    config Wednesday, December 30, 2009
  141. Akka Lift Wednesday, December 30, 2009

  142. 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 

} } Lift integration Wednesday, December 30, 2009
  143. <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> Lift integration Wednesday, December 30, 2009
  144. Akka HotSwap Wednesday, December 30, 2009

  145. HotSwap actor
!
HotSwap(Some({ 

//
new
body 

case
Ping
=>
 



...
 

case
Pong
=>
 



...

 })) Wednesday, December

    30, 2009
  146. Akka AMQP Wednesday, December 30, 2009

  147. val
producer
=
AMQP.newProducer( 

config,
 

hostname,
port,
 

exchangeName,
 

serializer,
 


 None,
None,
//
listeners
 

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



    AMQP: producer Wednesday, December 30, 2009
  148. 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 



})

    AMQP: consumer Wednesday, December 30, 2009
  149. Akka Kernel Wednesday, December 30, 2009

  150. java
‐jar
akka‐0.6.jar
\ 

‐Dakka.config=<path>/akka.conf Start Kernel export
AKKA_HOME=<path
to
akka
dist> java
‐jar
$AKKA_HOME/dist/akka‐0.6.jar Or Wednesday, December 30,

    2009
  151. Akka Deployment 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. <log> 

console
=
on 

filename
=
"./logs/akka.log" 

roll
=
"daily"
 

level
=
"debug" 

syslog_host
=
".." 

syslog_server_name
=
".." </log> Logging 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 http://scalablesolutions.se jonas@jonasboner.com Consulting Training Mentoring Wednesday, December 30,

    2009
  162. EOF Wednesday, December 30, 2009