Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

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

on

  • 20,092 views

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

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.

Statistics

Views

Total Views
20,092
Views on SlideShare
19,849
Embed Views
243

Actions

Likes
63
Downloads
696
Comments
3

6 Embeds 243

http://eao197.blogspot.ru 92
http://www.slideshare.net 77
http://eao197.blogspot.com 51
http://jonasboner.com 19
https://twitter.com 3
http://twitter.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • great, but a question, if mutable state is the devil i see that the Actor has mutable state: class Counter extends Actor { private var counter = 0.
    Are you sure you want to
    Your message goes here
    Processing…
  • cool slide, counter balances the ego of 'Concurrency for legacy languages'
    Are you sure you want to
    Your message goes here
    Processing…
  • good
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

  • 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
  • 29. Actors 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
  • 59. Akka Dispatchers 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
  • 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. 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
  • 87. Akka STM 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
  • 116. Akka Serialization 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
  • 122. Akka Persistence 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
  • 129. Akka REST 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
  • 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. Comet actors @Path("/chat") class
Chat
extends
Actor
{ 

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

@Suspend
//
receiving
endpoint 

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

def
suspend
=
<!‐‐
suspend
‐‐> 

//
sending
endpoint 

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

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

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

@POST
 

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



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

 












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

def
receive
=
{
case
Chat(..)
=>
..} } Wednesday, December 30, 2009
  • 137. Akka Security 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
  • 141. Akka Lift 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
  • 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. 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
  • 149. Akka Kernel 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
  • 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. 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
  • 162. EOF Wednesday, December 30, 2009