Actor Concurrency

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    4 Favorites

    Actor Concurrency - Presentation Transcript

    1. Actor Concurrency Alex Miller Blog: http://tech.puredanger.com Twitter: @puredanger
    2. 8086
    3. Moore’s Law? http://en.wikipedia.org/wiki/CPU_speed http://en.wikipedia.org/wiki/Transistor_count
    4. Moore’s Law? http://en.wikipedia.org/wiki/CPU_speed http://en.wikipedia.org/wiki/Transistor_count
    5. Moore’s Law? http://en.wikipedia.org/wiki/CPU_speed http://en.wikipedia.org/wiki/Transistor_count
    6. State of the Practice public class Counter { private int count = 0; public int increment() { synchronized(this) { return ++count; } } }
    7. JCIP says: • It’s the mutable state, stupid. • Make fields final unless they need to be mutable. • Immutable objects are automatically thread-safe. • Encapsulation makes it practical to manage the complexity. • Guard each mutable variable with a lock. • Guard all variables in an invariant with the same lock. • Hold locks for the duration of compound actions. • A program that accesses a mutable variable from multiple threads without synchronization is a broken program. • Don’t rely on clever reasoning about why you don’t need to synchronize. • Include thread safety in the design process - or explicitly document that your class is not thread-safe. • Document your synchronization policy.
    8. JCIP says: • It’s the mutable state, stupid. • Make fields final unless they need to be mutable. • Immutable objects are automatically thread-safe. • Encapsulation makes it practical to manage the complexity. • Guard each mutable variable with a lock. • Guard all variables in an invariant with the same lock. • Hold locks for the duration of compound actions. • A program that accesses a mutable variable from multiple threads without synchronization is a broken program. • Don’t rely on clever reasoning about why you don’t need to synchronize. • Include thread safety in the design process - or explicitly document that your class is not thread-safe. • Document your synchronization policy.
    9. The problem with shared state concurrency
    10. The problem with shared state concurrency ...is the shared state.
    11. Actors • No shared state • Lightweight processes • Asynchronous message-passing • Buffer messages in a mailbox • Receive messages with pattern matching
    12. The Basics
    13. The Basics spawn
    14. The Basics send spawn
    15. The Basics receive
    16. Erlang • Invented at Ericsson • Functional language • Dynamic typing • Designed for concurrency, fault-tolerance
    17. Single assignment Eshell V5.6.3 (abort with ^G) 1> A = 4. 4 2> A. 4 3> A = 6. ** exception error: no match of right hand side value 6 4> A = 2*2. 4
    18. Atoms and Tuples 1> F=foo. foo 2> Stooges = {larry,curly,moe}. {larry,curly,moe} 3> Me = {person,\"Alex\",\"nachos\"}. {person,\"Alex\",\"nachos\"} 4> {person,Name,Food} = Me. {person,\"Alex\",\"nachos\"} 5> Name. \"Alex\" 6> Food. \"nachos\"
    19. Lists 1> List=[1,2,3]. [1,2,3] 2> [First|Rest]=List. [1,2,3] 3> First. 1 4> Rest. [2,3] 5> List2=[4|List]. [4,1,2,3] 6> [Char|String] = “abc”. “abc” 7> Char. 97
    20. Functions 1> Square = fun(X) -> X*X end. #Fun<erl_eval.6.13229925> 2> Square(5). 25. 3> TimesN = fun(N) -> (fun(X) -> N*X end) 3> end. #Fun<erl_eval.6.13229925> 4> lists:map(TimesN(10), [1,2,3]). [10,20,30]
    21. Modules -module(mymath). -export([square/1,fib/1]). square(Value) -> Value*Value. fib(0) -> 0; fib(1) -> 1; fib(N) when N>0 -> fib(N-1) + fib(N-2). 1> c(mymath.erl). 2> mymath:square(5). 25 3> mymath:fib(7). 13
    22. Modules and Functions -module(mymath2). -export([fibtr/1]). fibtr(N) -> fibtr_iter(N, 0, 1). fibtr_iter(0, Result, _Next) -> Result; fibtr_iter(Iter, Result, Next) when Iter > 0 -> fibtr_iter(Iter-1, Next, Result+Next). 1> c(mymath2.erl). 2> mymath2:fibtr(200). 280571172992510140037611932413038677189525
    23. Concurrency Primitives • Pid = spawn(fun) • Pid ! message • receive...end
    24. Concurrency Primitives • Pid = spawn(fun) • Pid ! message • receive...end Pid
    25. Concurrency Primitives • Pid = spawn(fun) • Pid ! message • receive...end Pid
    26. Concurrency Primitives • Pid = spawn(fun) • Pid ! message • receive...end Pid
    27. Concurrency Primitives • Pid = spawn(fun) • Pid ! message • receive...end receive Pid ... end
    28. A Simple Process loop() -> receive {toF, C} -> io:format(\"~p C is ~p F~n\", [C, 32+C*9/5]), loop(); {toC, F} -> io:format(\"~p F is ~p C~n\", [F, (F-32)*5/9]), loop(); {stop} -> io:format(\"Stopping~n\"); Other -> io:format(\"Unknown: ~p~n\", [Other]), loop() end.
    29. Spawn! 1> c(temperature). {ok,temperature} 2> Pid = spawn(fun temperature:loop/0). <0.128.0> 3> Pid ! {toC, 32}. 32F is 0.0 C {convertToC,32} 4> Pid ! {toF, 100}. 100C is 212.0 F {convertToF,100} 5> Pid ! {stop}. Stopping {stop}
    30. Responding -module(temp2). -export([start/0,convert/2]). start() -> spawn(fun() -> loop() end). convert(Pid, Request) -> Pid ! {self(), Request}, receive {Pid, Response} -> Response end.
    31. Responding loop() -> receive {From, {toF, C}} -> From ! {self(), 32+C*9/5}, loop(); {From, {toC, F}} -> From ! {self(), (F-32)*5/9}, loop(); {From, stop} -> From ! {self(), stop}, io:format(\"Stopping~n\"); {From, Other} -> From ! {self(), {error, Other}}, loop() end.
    32. Responding 1> c(temp2). {ok,temp2} 2> Pid = temp2:start(). <0.57.0> 3> temp2:convert(Pid2, {toF, 100}). 212.0
    33. Process Ring
    34. Running Rings 1> c(ring). 2> T=ring:startTimer(). 3> R=ring:startRing(100,T). spawned 100 in 241 microseconds 4> R ! start. {1230,863064,116530} Starting message {1230,863064,879862} Around ring 10000 times {1230,863065,642097} Around ring 20000 times ...etc {1230,863140,707023} Around ring 990000 times {1230,863141,471193} Around ring 1000000 times Start={1230,863064,116875} Stop={1230,863141,471380} Elapsed=77354505 5> R20k = ring:startRing(20000,T). spawned: 20000 in 118580 microseconds
    35. Processes and Messages • Processes cheap to create (10ks < second) • Create many processes (10ks to 100ks) • Messages very fast to send (1M / second)
    36. Error Handling
    37. Error Handling link
    38. Error Handling link
    39. Error Handling exit signal
    40. Linked Processes reportExit(WatchedPid) -> spawn(fun() -> process_flag(trap_exit, true), link(WatchedPid), receive {'EXIT', _Pid, Msg} -> io:format(\"got linked exit: ~p~n\", [Msg]) end end). startWatched() -> spawn(fun() -> receive die -> exit(\"die\"); crash -> erlang:error(\"crash\") end end).
    41. Linked Processes 1> c(link). 2> P1 = link:startWatched(). 3> P2 = link:startWatched(). 4> link:reportExit(P1). 5> link:reportExit(P2). 6> P1 ! die. got linked exit: \"die\" 7> P2 ! crash. got linked exit: {\"crash\",[{link,'- startWatched/0-fun-0-',0}]}
    42. Does it work?
    43. Ericsson AXD301 • Telecom ATM switch • Millions of calls / week • 99.9999999% uptime = 32 ms down / year • -> Nortel Alteon SSL Accelerator
    44. YAWS http://www.sics.se/~joe/apachevsyaws.html
    45. Messaging
    46. Facebook Chat “For Facebook Chat, we rolled our own subsystem for logging chat messages (in C++) as well as an epoll- driven web server (in Erlang) that holds online users' conversations in-memory and serves the long-polled HTTP requests. Both subsystems are clustered and partitioned for reliability and efficient failover. ” Reference: http://www.facebook.com/note.php?note_id=14218138919
    47. And others...
    48. • JVM-based language • Object-functional hybrid • Actor library
    49. Scala Rings def act() { loop { react { case StartMessage => { log(\"Starting messages\") timer ! StartMessage nextNode ! TokenMessage(nodeId, 0) } case StopMessage => { log(\"Stopping\") nextNode ! StopMessage exit }
    50. Scala Rings case TokenMessage(id,value) if id == nodeId => { val nextValue = value+1 if(nextValue % 10000 == 0) log(\"Around ring \" + nextValue + \" times\") if(nextValue == 1000000) { timer ! StopMessage timer ! CancelMessage nextNode ! StopMessage exit } else { nextNode ! TokenMessage(id, nextValue) } } case TokenMessage(id,value) => { nextNode ! TokenMessage(id,value) } }
    51. Comparison to Erlang • receive-based actors cheap to create (Erlang about 3x faster) • Can also create many processes • Messages also fast to send (Erlang about 2x faster)
    52. • Java-based framework with compile-time weaving • Tasks - lightweight threads/processes/etc • @pausable - let task be paused during execution • sleep / yield • Mailbox (typed via generics) - single consumer • Messaging - mutable (in limited ways)
    53. Kilim Ring import kilim.Mailbox; import kilim.Task; import kilim.pausable; public class NodeActor extends Task { private final int nodeId; private final Mailbox<Message> inbox; private final Mailbox<Message> timerInbox; private Mailbox<Message> nextInbox; public NodeActor(int nodeId, Mailbox<Message> inbox, Mailbox<Message> timerInbox) { this.nodeId = nodeId; this.inbox = inbox; this.timerInbox = timerInbox; }
    54. Kilim Ring @pausable public void execute() throws Exception { while(true) { Message message = inbox.get(); if(message.equals(Message.START)) { timerInbox.putnb(Message.START); nextInbox.putnb(new TokenMessage(nodeId, 0)); } else if(message.equals(Message.STOP)) { nextInbox.putnb(Message.STOP); break; ...
    55. Kilim Ring } else if(message instanceof TokenMessage) { TokenMessage token = (TokenMessage)message; if(token.source == nodeId) { int nextVal = token.value+1; if(nextVal == 1000000) { timerInbox.putnb(Message.STOP); timerInbox.putnb(Message.CANCEL); nextInbox.putnb(Message.STOP); break; } else { token.value = nextVal; nextInbox.putnb(token); } } else { nextInbox.putnb(token); } } }
    56. Performance 10.0 400 7.5 300 milliseconds milliseconds 5.0 200 2.5 100 0 0 100 nodes 20k nodes 130,000 Erlang 97,500 milliseconds Scala Kilim 65,000 32,500 0 100M messages
    57. http://tech.puredanger.com/presentations/actor-concurrency

    + Alex MillerAlex Miller, 5 months ago

    custom

    1075 views, 4 favs, 1 embeds more stats

    An introduction to Erlang and the actor model of co more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 1075
      • 1057 on SlideShare
      • 18 from embeds
    • Comments 0
    • Favorites 4
    • Downloads 46
    Most viewed embeds
    • 18 views on http://tech.puredanger.com

    more

    All embeds
    • 18 views on http://tech.puredanger.com

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories