SlideShare une entreprise Scribd logo
1  sur  63
Télécharger pour lire hors ligne
Actor Concurrency
                         Alex Miller

Blog:   http://tech.puredanger.com     Twitter: @puredanger
8086
Moore’s Law?




http://en.wikipedia.org/wiki/CPU_speed   http://en.wikipedia.org/wiki/Transistor_count
Moore’s Law?




http://en.wikipedia.org/wiki/CPU_speed   http://en.wikipedia.org/wiki/Transistor_count
Moore’s Law?




http://en.wikipedia.org/wiki/CPU_speed   http://en.wikipedia.org/wiki/Transistor_count
State of the Practice
public class Counter {
  private int count = 0;

    public int increment() {
      synchronized(this) {
        return ++count;
      }
    }
}
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.
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.
The problem with shared state concurrency
The problem with shared state concurrency




          ...is the shared state.
Actors

•   No shared state
•   Lightweight processes
•   Asynchronous message-passing
•   Buffer messages in a mailbox
•   Receive messages with pattern matching
The Basics
The Basics




             spawn
The Basics

send




                    spawn
The Basics

         receive
Erlang


• Invented at Ericsson
• Functional language
• Dynamic typing
• Designed for concurrency, fault-tolerance
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
Atoms and Tuples
1> F=foo.
foo
2> Stooges = {larry,curly,moe}.
{larry,curly,moe}
3> Me = {person,quot;Alexquot;,quot;nachosquot;}.
{person,quot;Alexquot;,quot;nachosquot;}
4> {person,Name,Food} = Me.
{person,quot;Alexquot;,quot;nachosquot;}
5> Name.
quot;Alexquot;
6> Food.
quot;nachosquot;
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
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]
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
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
Concurrency Primitives

• Pid = spawn(fun)
• Pid ! message
• receive...end
Concurrency Primitives

• Pid = spawn(fun)
• Pid ! message
• receive...end      Pid
Concurrency Primitives

• Pid = spawn(fun)
• Pid ! message
• receive...end      Pid
Concurrency Primitives

• Pid = spawn(fun)
• Pid ! message
• receive...end      Pid
Concurrency Primitives

• Pid = spawn(fun)
• Pid ! message
• receive...end
                           receive
                     Pid     ...
                           end
A Simple Process
loop() ->
  receive
    {toF, C} ->
       io:format(quot;~p C is ~p F~nquot;,
                 [C, 32+C*9/5]),
       loop();
    {toC, F} ->
       io:format(quot;~p F is ~p C~nquot;,
                 [F, (F-32)*5/9]),
       loop();
    {stop} ->
       io:format(quot;Stopping~nquot;);
    Other ->
       io:format(quot;Unknown: ~p~nquot;, [Other]),
       loop()
  end.
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}
Responding
-module(temp2).
-export([start/0,convert/2]).

start() ->
  spawn(fun() -> loop() end).

convert(Pid, Request) ->
  Pid ! {self(), Request},
  receive
    {Pid, Response} -> Response
  end.
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(quot;Stopping~nquot;);
    {From, Other} ->
       From ! {self(), {error, Other}},
       loop()
  end.
Responding
1> c(temp2).
{ok,temp2}
2> Pid = temp2:start().
<0.57.0>
3> temp2:convert(Pid2, {toF, 100}).
212.0
Process Ring
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
Processes and
         Messages

• Processes cheap to create (10ks < second)
• Create many processes (10ks to 100ks)
• Messages very fast to send (1M / second)
Error Handling
Error Handling

     link
Error Handling

     link
Error Handling


    exit signal
Linked Processes
reportExit(WatchedPid) ->
  spawn(fun() ->
    process_flag(trap_exit, true),
    link(WatchedPid),
    receive
      {'EXIT', _Pid, Msg} ->
        io:format(quot;got linked exit: ~p~nquot;, [Msg])
    end
  end).

startWatched() ->
  spawn(fun() ->
    receive
      die -> exit(quot;diequot;);
      crash -> erlang:error(quot;crashquot;)
    end
  end).
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: quot;diequot;
7> P2 ! crash.
got linked exit: {quot;crashquot;,[{link,'-
startWatched/0-fun-0-',0}]}
Does it work?
Ericsson AXD301
• Telecom ATM switch
• Millions of calls / week
• 99.9999999% uptime =
  32 ms down / year
• -> Nortel Alteon SSL
  Accelerator
YAWS




http://www.sics.se/~joe/apachevsyaws.html
Messaging
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
And others...
• JVM-based language
• Object-functional hybrid
• Actor library
Scala Rings
def act() {
  loop {
    react {
      case StartMessage => {
         log(quot;Starting messagesquot;)
         timer ! StartMessage
         nextNode ! TokenMessage(nodeId, 0)
      }
      case StopMessage => {
         log(quot;Stoppingquot;)
         nextNode ! StopMessage
         exit
      }
Scala Rings
    case TokenMessage(id,value) if id == nodeId => {
      val nextValue = value+1
      if(nextValue % 10000 == 0)
        log(quot;Around ring quot; + nextValue + quot; timesquot;)

      if(nextValue == 1000000) {
        timer ! StopMessage
        timer ! CancelMessage
        nextNode ! StopMessage
        exit
      } else {
        nextNode ! TokenMessage(id, nextValue)
      }
    }
    case TokenMessage(id,value) => {
      nextNode ! TokenMessage(id,value)
    }
}
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)
•   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)
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;
}
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;



...
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);
        }
    }
}
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
http://tech.puredanger.com/presentations/actor-concurrency

Contenu connexe

Tendances

Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrency
priyank09
 
Qt Memory Management & Signal and Slots
Qt Memory Management & Signal and SlotsQt Memory Management & Signal and Slots
Qt Memory Management & Signal and Slots
Jussi Pohjolainen
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/O
Jussi Pohjolainen
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
Leonardo Borges
 

Tendances (20)

Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrency
 
Thread
ThreadThread
Thread
 
Qt Memory Management & Signal and Slots
Qt Memory Management & Signal and SlotsQt Memory Management & Signal and Slots
Qt Memory Management & Signal and Slots
 
Facts about multithreading that'll keep you up at night - Guy Bar on, Vonage
Facts about multithreading that'll keep you up at night - Guy Bar on, VonageFacts about multithreading that'll keep you up at night - Guy Bar on, Vonage
Facts about multithreading that'll keep you up at night - Guy Bar on, Vonage
 
C10k and beyond - Uri Shamay, Akamai
C10k and beyond - Uri Shamay, AkamaiC10k and beyond - Uri Shamay, Akamai
C10k and beyond - Uri Shamay, Akamai
 
Let'swift "Concurrency in swift"
Let'swift "Concurrency in swift"Let'swift "Concurrency in swift"
Let'swift "Concurrency in swift"
 
The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196
 
ConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with GroovyConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with Groovy
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streams
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/O
 
Java Performance Puzzlers
Java Performance PuzzlersJava Performance Puzzlers
Java Performance Puzzlers
 
Intro to Rust from Applicative / NY Meetup
Intro to Rust from Applicative / NY MeetupIntro to Rust from Applicative / NY Meetup
Intro to Rust from Applicative / NY Meetup
 
Multithreading done right
Multithreading done rightMultithreading done right
Multithreading done right
 
​"Delegates, Delegates everywhere" Владимир Миронов
​"Delegates, Delegates everywhere" Владимир Миронов​"Delegates, Delegates everywhere" Владимир Миронов
​"Delegates, Delegates everywhere" Владимир Миронов
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
04 threads
04 threads04 threads
04 threads
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 

Similaire à Actor Concurrency

Data Acquisition
Data AcquisitionData Acquisition
Data Acquisition
azhar557
 
Threaded Programming
Threaded ProgrammingThreaded Programming
Threaded Programming
Sri Prasanna
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
Miller Lee
 

Similaire à Actor Concurrency (20)

Optimization in Programming languages
Optimization in Programming languagesOptimization in Programming languages
Optimization in Programming languages
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
Deuce STM - CMP'09
Deuce STM - CMP'09Deuce STM - CMP'09
Deuce STM - CMP'09
 
Introduction to Erlang
Introduction to ErlangIntroduction to Erlang
Introduction to Erlang
 
HAB Software Woes
HAB Software WoesHAB Software Woes
HAB Software Woes
 
Appsec obfuscator reloaded
Appsec obfuscator reloadedAppsec obfuscator reloaded
Appsec obfuscator reloaded
 
Data Acquisition
Data AcquisitionData Acquisition
Data Acquisition
 
Valerii Vasylkov Erlang. measurements and benefits.
Valerii Vasylkov Erlang. measurements and benefits.Valerii Vasylkov Erlang. measurements and benefits.
Valerii Vasylkov Erlang. measurements and benefits.
 
SE2016 Exotic Valerii Vasylkov "Erlang. Measurements and benefits"
SE2016 Exotic Valerii Vasylkov "Erlang. Measurements and benefits"SE2016 Exotic Valerii Vasylkov "Erlang. Measurements and benefits"
SE2016 Exotic Valerii Vasylkov "Erlang. Measurements and benefits"
 
Qt Application Programming with C++ - Part 2
Qt Application Programming with C++ - Part 2Qt Application Programming with C++ - Part 2
Qt Application Programming with C++ - Part 2
 
Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
 
The Ring programming language version 1.10 book - Part 95 of 212
The Ring programming language version 1.10 book - Part 95 of 212The Ring programming language version 1.10 book - Part 95 of 212
The Ring programming language version 1.10 book - Part 95 of 212
 
Threaded Programming
Threaded ProgrammingThreaded Programming
Threaded Programming
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
MUST CS101 Lab11
MUST CS101 Lab11 MUST CS101 Lab11
MUST CS101 Lab11
 
Giorgio zoppi cpp11concurrency
Giorgio zoppi cpp11concurrencyGiorgio zoppi cpp11concurrency
Giorgio zoppi cpp11concurrency
 
Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitter
 
Kamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, code
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approach
 

Plus de Alex Miller

Marshmallow Test
Marshmallow TestMarshmallow Test
Marshmallow Test
Alex Miller
 

Plus de Alex Miller (20)

Clojure/West Overview (12/1/11)
Clojure/West Overview (12/1/11)Clojure/West Overview (12/1/11)
Clojure/West Overview (12/1/11)
 
Concurrent Stream Processing
Concurrent Stream ProcessingConcurrent Stream Processing
Concurrent Stream Processing
 
Stream Execution with Clojure and Fork/join
Stream Execution with Clojure and Fork/joinStream Execution with Clojure and Fork/join
Stream Execution with Clojure and Fork/join
 
Cracking clojure
Cracking clojureCracking clojure
Cracking clojure
 
Releasing Relational Data to the Semantic Web
Releasing Relational Data to the Semantic WebReleasing Relational Data to the Semantic Web
Releasing Relational Data to the Semantic Web
 
Clojure: The Art of Abstraction
Clojure: The Art of AbstractionClojure: The Art of Abstraction
Clojure: The Art of Abstraction
 
Tree Editing with Zippers
Tree Editing with ZippersTree Editing with Zippers
Tree Editing with Zippers
 
Groovy concurrency
Groovy concurrencyGroovy concurrency
Groovy concurrency
 
Blogging ZOMG
Blogging ZOMGBlogging ZOMG
Blogging ZOMG
 
Innovative Software
Innovative SoftwareInnovative Software
Innovative Software
 
Scaling Your Cache
Scaling Your CacheScaling Your Cache
Scaling Your Cache
 
Caching In The Cloud
Caching In The CloudCaching In The Cloud
Caching In The Cloud
 
Scaling Your Cache And Caching At Scale
Scaling Your Cache And Caching At ScaleScaling Your Cache And Caching At Scale
Scaling Your Cache And Caching At Scale
 
Marshmallow Test
Marshmallow TestMarshmallow Test
Marshmallow Test
 
Strange Loop Conference 2009
Strange Loop Conference 2009Strange Loop Conference 2009
Strange Loop Conference 2009
 
Cold Hard Cache
Cold Hard CacheCold Hard Cache
Cold Hard Cache
 
Scaling Hibernate with Terracotta
Scaling Hibernate with TerracottaScaling Hibernate with Terracotta
Scaling Hibernate with Terracotta
 
Project Fortress
Project FortressProject Fortress
Project Fortress
 
Java Collections API
Java Collections APIJava Collections API
Java Collections API
 
Design Patterns Reconsidered
Design Patterns ReconsideredDesign Patterns Reconsidered
Design Patterns Reconsidered
 

Dernier

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Dernier (20)

Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 

Actor Concurrency

  • 1. Actor Concurrency Alex Miller Blog: http://tech.puredanger.com Twitter: @puredanger
  • 2.
  • 3.
  • 5.
  • 6.
  • 7. Moore’s Law? http://en.wikipedia.org/wiki/CPU_speed http://en.wikipedia.org/wiki/Transistor_count
  • 8. Moore’s Law? http://en.wikipedia.org/wiki/CPU_speed http://en.wikipedia.org/wiki/Transistor_count
  • 9. Moore’s Law? http://en.wikipedia.org/wiki/CPU_speed http://en.wikipedia.org/wiki/Transistor_count
  • 10. State of the Practice public class Counter { private int count = 0; public int increment() { synchronized(this) { return ++count; } } }
  • 11.
  • 12. 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.
  • 13. 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.
  • 14. The problem with shared state concurrency
  • 15. The problem with shared state concurrency ...is the shared state.
  • 16. Actors • No shared state • Lightweight processes • Asynchronous message-passing • Buffer messages in a mailbox • Receive messages with pattern matching
  • 18. The Basics spawn
  • 20. The Basics receive
  • 21. Erlang • Invented at Ericsson • Functional language • Dynamic typing • Designed for concurrency, fault-tolerance
  • 22. 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
  • 23. Atoms and Tuples 1> F=foo. foo 2> Stooges = {larry,curly,moe}. {larry,curly,moe} 3> Me = {person,quot;Alexquot;,quot;nachosquot;}. {person,quot;Alexquot;,quot;nachosquot;} 4> {person,Name,Food} = Me. {person,quot;Alexquot;,quot;nachosquot;} 5> Name. quot;Alexquot; 6> Food. quot;nachosquot;
  • 24. 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
  • 25. 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]
  • 26. 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
  • 27. 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
  • 28. Concurrency Primitives • Pid = spawn(fun) • Pid ! message • receive...end
  • 29. Concurrency Primitives • Pid = spawn(fun) • Pid ! message • receive...end Pid
  • 30. Concurrency Primitives • Pid = spawn(fun) • Pid ! message • receive...end Pid
  • 31. Concurrency Primitives • Pid = spawn(fun) • Pid ! message • receive...end Pid
  • 32. Concurrency Primitives • Pid = spawn(fun) • Pid ! message • receive...end receive Pid ... end
  • 33. A Simple Process loop() -> receive {toF, C} -> io:format(quot;~p C is ~p F~nquot;, [C, 32+C*9/5]), loop(); {toC, F} -> io:format(quot;~p F is ~p C~nquot;, [F, (F-32)*5/9]), loop(); {stop} -> io:format(quot;Stopping~nquot;); Other -> io:format(quot;Unknown: ~p~nquot;, [Other]), loop() end.
  • 34. 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}
  • 35. Responding -module(temp2). -export([start/0,convert/2]). start() -> spawn(fun() -> loop() end). convert(Pid, Request) -> Pid ! {self(), Request}, receive {Pid, Response} -> Response end.
  • 36. 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(quot;Stopping~nquot;); {From, Other} -> From ! {self(), {error, Other}}, loop() end.
  • 37. Responding 1> c(temp2). {ok,temp2} 2> Pid = temp2:start(). <0.57.0> 3> temp2:convert(Pid2, {toF, 100}). 212.0
  • 39. 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
  • 40. Processes and Messages • Processes cheap to create (10ks < second) • Create many processes (10ks to 100ks) • Messages very fast to send (1M / second)
  • 44. Error Handling exit signal
  • 45. Linked Processes reportExit(WatchedPid) -> spawn(fun() -> process_flag(trap_exit, true), link(WatchedPid), receive {'EXIT', _Pid, Msg} -> io:format(quot;got linked exit: ~p~nquot;, [Msg]) end end). startWatched() -> spawn(fun() -> receive die -> exit(quot;diequot;); crash -> erlang:error(quot;crashquot;) end end).
  • 46. 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: quot;diequot; 7> P2 ! crash. got linked exit: {quot;crashquot;,[{link,'- startWatched/0-fun-0-',0}]}
  • 48. Ericsson AXD301 • Telecom ATM switch • Millions of calls / week • 99.9999999% uptime = 32 ms down / year • -> Nortel Alteon SSL Accelerator
  • 51. 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
  • 53. • JVM-based language • Object-functional hybrid • Actor library
  • 54. Scala Rings def act() { loop { react { case StartMessage => { log(quot;Starting messagesquot;) timer ! StartMessage nextNode ! TokenMessage(nodeId, 0) } case StopMessage => { log(quot;Stoppingquot;) nextNode ! StopMessage exit }
  • 55. Scala Rings case TokenMessage(id,value) if id == nodeId => { val nextValue = value+1 if(nextValue % 10000 == 0) log(quot;Around ring quot; + nextValue + quot; timesquot;) if(nextValue == 1000000) { timer ! StopMessage timer ! CancelMessage nextNode ! StopMessage exit } else { nextNode ! TokenMessage(id, nextValue) } } case TokenMessage(id,value) => { nextNode ! TokenMessage(id,value) } }
  • 56. 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)
  • 57. 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)
  • 58. 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; }
  • 59. 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; ...
  • 60. 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); } } }
  • 61. 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
  • 62.