$30 off During Our Annual Pro Sale. View Details »

Distributed, Eventually Consistent Computations

Distributed, Eventually Consistent Computations

Erlang Factory SF Bay, 2015

Christopher Meiklejohn

March 26, 2015
Tweet

More Decks by Christopher Meiklejohn

Other Decks in Programming

Transcript

  1. View Slide

  2. LASP
    2

    View Slide

  3. EVENTUALLY CONSISTENT COMPUTATIONS
    DISTRIBUTED
    3

    View Slide

  4. CHRISTOPHER MEIKLEJOHN
    EN TAL AV
    4

    View Slide

  5. RESEARCH WITH:
    PETER VAN ROY (UCL)
    5

    View Slide

  6. MOTIVATION
    6

    View Slide

  7. EXPENSIVE
    SYNCHRONIZATION IS
    7

    View Slide

  8. SOMETIMES IMPRACTICAL
    SYNCHRONIZATION IS
    8

    View Slide

  9. MOBILE GAMES:
    SHARED STATE BETWEEN CLIENTS
    CLIENTS GO OFFLINE
    9
    http://www.rovio.com/en/news/blog/261/263-million-monthly-active-users-in-december/

    View Slide

  10. DISJOINT STATE AGGREGATED UPSTREAM
    CLIENTS GO OFFLINE
    INTERNET OF THINGS:
    10
    Gubbi, Jayavardhana, et al. "Internet of Things (IoT): A vision, architectural elements, and future directions." Future Generation Computer Systems 29.7 (2013): 1645-1660.

    View Slide

  11. NO TOTAL ORDER:
    REPLICATED SHARED STATE WITH OFFLINE CLIENTS
    CLIENTS NEED TO MAKE PROGRESS
    11
    Gilbert, Seth, and Nancy Lynch. "Brewer's conjecture and the feasibility of consistent, available, partition-tolerant web services." ACM SIGACT News 33.2 (2002): 51-59.

    View Slide

  12. WALL CLOCKS:
    UNRELIABLE AT BEST
    NON-DETERMINISTIC IF USED IN COMPUTATIONS
    12
    Corbett, James C., et al. "Spanner: Google’s globally distributed database." ACM Transactions on Computer Systems (TOCS) 31.3 (2013): 8.

    View Slide

  13. RECONCILED BY USER
    CONCURRENCY
    13

    View Slide

  14. RA
    RB
    1
    1 3
    2
    ?
    ?
    14

    View Slide

  15. RA
    RB
    1
    1 3
    2
    ?
    ?
    15

    View Slide

  16. RA
    RB
    1
    1 3
    2
    ?
    ?
    16

    View Slide

  17. RA
    RB
    1
    1 3
    2
    ?
    ?
    17

    View Slide

  18. CRDTs
    18

    View Slide

  19. DETERMINISTIC RESOLUTION
    CRDTs PROVIDE
    19

    View Slide

  20. CRDTs:
    MAPS, SETS, COUNTERS, REGISTERS, GRAPHS
    DETERMINISTIC RESOLUTION
    20

    View Slide

  21. STRONG EVENTUAL CONSISTENCY
    CRDTs REALIZE
    21

    View Slide

  22. “CORRECT REPLICAS THAT HAVE DELIVERED THE
    SAME UPDATES HAVE EQUIVALENT STATE”
    22
    Shapiro, Marc, et al. "Conflict-free replicated data types." Stabilization, Safety, and Security of Distributed Systems. Springer Berlin Heidelberg, 2011. 386-400.

    View Slide

  23. ‘MAX’ REGISTER
    CRDTs EXAMPLE
    23

    View Slide

  24. RA
    RB
    1
    1 3
    2
    3
    3
    24

    View Slide

  25. ‘ORSET’ SET
    CRDTs EXAMPLE
    25

    View Slide

  26. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {1}
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {b}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    26

    View Slide

  27. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {1}
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {b}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    27

    View Slide

  28. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {1}
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {b}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    28

    View Slide

  29. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {1}
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {b}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    29

    View Slide

  30. NONTRIVIAL
    COMPOSITION IS
    30

    View Slide

  31. RC {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    (1, {a, b}, {b})
    {1}
    (1, {a, b}, {b})
    fun(X) -> 2 end F(RC) {2} {} {2} {2}
    31

    View Slide

  32. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {1}
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {b}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    32

    View Slide

  33. RA
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {b}, {})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    33

    View Slide

  34. RA
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    F(RA) {2} {2} {2}
    (1, {a, b}, {b})
    F(RC) {2} {} {2} {2}
    34

    View Slide

  35. RA
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    F(RA) {2} {2} {2}
    (1, {a, b}, {b})
    F(RC) {2} {} {2} {2}
    35

    View Slide

  36. RA
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    F(RA) {2} {2} {2}
    (1, {a, b}, {b})
    F(RC) {2} {} {2} {2}
    36

    View Slide

  37. RA
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    F(RA) {2} {2} {2}
    (1, {a, b}, {b})
    F(RC) {2} {} {2} {2}
    37

    View Slide

  38. COMPOSITION:
    USER OBSERVABLE VALUE VS. STATE
    METADATA MAPPING IS NONTRIVIAL
    WITHOUT MAPPING METADATA; UNMERGABLE
    38
    Brown, Russell, et al. "Riak dt map: A composable, convergent replicated dictionary." Proceedings of the First Workshop on Principles and Practice of Eventual Consistency. ACM, 2014.
    Conway, Neil, et al. "Logic and lattices for distributed programming." Proceedings of the Third ACM Symposium on Cloud Computing. ACM, 2012.
    Meiklejohn, Christopher. "On the composability of the Riak DT map: expanding from embedded to multi-key structures." Proceedings of the First Workshop on Principles and Practice of Eventual Consistency. ACM, 2014.

    View Slide

  39. LASP
    39

    View Slide

  40. LASP
    WHAT IS
    40

    View Slide

  41. LATTICE PROCESSING
    LASP
    41

    View Slide

  42. CENTRALIZED SEMANTICS:
    DATATYPE COMPOSITION
    42

    View Slide

  43. R {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    (1, {a, b}, {b})
    {1}
    (1, {a, b}, {b})
    fun(X) -> 2 end F(R) {2} {} {2} {2}
    (2, {b}, {}) (2, {b}, {b}) (2, {a, b}, {b}) (2, {a, b}, {b})
    43

    View Slide

  44. DISTRIBUTED SEMANTICS:
    DATATYPE COMPOSITION
    44

    View Slide

  45. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {1}
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {b}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    fun(X) -> 2 end F(RC) {2} {} {2} {2}
    (2, {b}, {}) (2, {b}, {b}) (2, {a, b}, {b}) (2, {a, b}, {b})
    F(RB) {2}
    (2, {b}, {})
    {2}
    (2, {a, b}, {b})
    {2}
    (2, {a, b}, {b})
    fun(X) -> 2 end
    F(RA) {2}
    (2, {a}, {})
    {2}
    (2, {a, b}, {b})
    {2}
    (2, {a, b}, {b})
    fun(X) -> 2 end
    45

    View Slide

  46. DISTRIBUTED SEMANTICS:
    SYSTEM COMPOSITION
    46

    View Slide

  47. CENTRALIZED RUNTIME:
    SINGLE NODE MODEL
    47

    View Slide

  48. DISTRIBUED RUNTIME:
    MULTI-NODE MODEL
    48

    View Slide

  49. SEMANTICS
    49

    View Slide

  50. STREAMS
    50

    View Slide

  51. STREAMS:
    CENTRALIZED EXECUTION
    51

    View Slide

  52. RA {1}
    (1, {a}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    (1, {a, b}, {b})
    52

    View Slide

  53. STREAMS:
    DISTRIBUTED EXECUTION
    53

    View Slide

  54. RA {1}
    (1, {a}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    (1, {a, b}, {b})
    RB {1}
    (1, {a}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    (1, {a, b}, {b})
    RC {1}
    (1, {a}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    (1, {a, b}, {b})
    54

    View Slide

  55. STREAMS:
    CONCURRENCY; FAILURE; ANTI-ENTROPY
    55

    View Slide

  56. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {1}
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {b}, {})
    {1}
    (1, {a, b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    {1}
    (1, {a, b}, {b})
    {}
    56

    View Slide

  57. STREAMS:
    DISTRIBUTED EXECUTION DETERMINISTIC
    REQUIRES EVENTUAL DELIVERY; ANTI-ENTROPY
    57

    View Slide

  58. DECLARE:
    CREATE A STREAM OF A GIVEN CRDT TYPE
    INITIALIZE STATE AT BOTTOM VALUE
    58

    View Slide

  59. BIND:
    ASSIGN A VALUE TO THE STREAM
    MERGE OF CURRENT AND NEW VALUE
    59

    View Slide

  60. MONOTONIC READ
    60

    View Slide

  61. MONOTONIC READ:
    ENSURES FORWARD PROGRESS
    BLOCKS ON INFLATIONS (OR STRICT INFLATIONS)
    61

    View Slide

  62. COMPOSITIONS ARE PROCESSES:
    BLOCK FOR CHANGE IN INPUT
    COMPUTE CHANGE
    PROPAGATE CHANGE TO OUTPUT
    62

    View Slide

  63. FUNCTIONAL
    63

    View Slide

  64. FUNCTIONAL:
    MAP; FILTER; FOLD
    64

    View Slide

  65. SET-THEORETIC
    65

    View Slide

  66. SET-THEORETIC:
    PRODUCT; INTERSECTION; UNION
    66

    View Slide

  67. ARCHITECTURE
    67

    View Slide

  68. SHARED VARIABLE STORE
    LASP STORE
    68

    View Slide

  69. LEVELDB, BITCASK, ETS
    LASP BACKENDS
    69

    View Slide

  70. PROVIDED BY RIAK DT
    LASP CRDTs
    70

    View Slide

  71. CENTRALIZED SEMANTICS
    LASP ARCHITECTURE
    71

    View Slide

  72. STORE:
    SHARED VARIABLE STORE
    PROCESSESS SYNCHRONIZE ON VARIABLES
    72

    View Slide

  73. DISTRIBUTED SEMANTICS
    LASP ARCHITECTURE
    73

    View Slide

  74. STORE:
    REPLICATED, SHARDED VARIABLE STORE
    PROCESSESS SYNCHRONIZE ON VARIABLES
    74

    View Slide

  75. REPLICATED:
    DISTRIBUTED WITH RIAK CORE
    QUORUM REQUESTS; ANTI-ENTROPY PROTOCOL
    75

    View Slide

  76. HYBRID:
    DISTRIBUTE PROGRAMS; R/W WITH LOCAL STORE
    CENTRALIZED EXECUTION
    76

    View Slide

  77. EXAMPLES
    77

    View Slide

  78. %% Create initial set.
    {ok, S1} = lasp:declare(Type),
    %% Add elements to initial set and update.
    {ok, _} = lasp:update(S1, {add_all, [1,2,3]}, a),
    %% Create second set.
    {ok, S2} = lasp:declare(Type),
    %% Apply map.
    ok = lasp:map(S1, fun(X) -> X * 2 end, S2),

    View Slide

  79. %% Create initial set.
    {ok, S1} = lasp_core:declare(Type, Store),
    %% Add elements to initial set and update.
    {ok, _} = lasp_core:update(S1, {add_all, [1,2,3]}, a, Store),
    %% Create second set.
    {ok, S2} = lasp_core:declare(Type, Store),
    %% Apply map.
    ok = lasp_core:map(S1, fun(X) -> X * 2 end, S2, Store),

    View Slide

  80. AD COUNTER
    80

    View Slide

  81. AD COUNTER:
    TRACKS AD IMPRESSIONS
    PUSHES ADVERTISEMENTS TO THE CLIENT
    DISABLES AD AT 50,000+ IMPRESSIONS
    CLIENTS DISPLAY ADS WHEN OFFLINE
    81

    View Slide

  82. INFORMATION FLOW
    AD COUNTER
    82

    View Slide

  83. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    83

    View Slide

  84. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    84

    View Slide

  85. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    85

    View Slide

  86. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    86

    View Slide

  87. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    87

    View Slide

  88. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    88

    View Slide

  89. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    89

    View Slide

  90. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    90

    View Slide

  91. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    91

    View Slide

  92. INFORMATION FLOW:
    MONOTONIC
    METADATA TO PREVENT DUPLICATE PROPAGATION
    92
    Title Text

    View Slide

  93. DISTRIBUTION
    AD COUNTER
    93

    View Slide

  94. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    94

    View Slide

  95. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    95

    View Slide

  96. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    96

    View Slide

  97. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Clients
    Clients
    Clients
    Clients
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Client Process
    97

    View Slide

  98. DISTRIBUTION BOUNDARIES:
    ARBITRARY
    ALLOWS COMPOSITION OF ENTIRE SYSTEM
    98

    View Slide

  99. EXAMPLE CODE
    AD COUNTER
    99

    View Slide

  100. %% @doc Client process; standard recursive looping server.
    client(Id, AdsWithContracts, PreviousValue) ->
    receive
    view_ad ->
    %% Get current ad list.
    {ok, {_, _, AdList0}} = lasp:read(AdsWithContracts, PreviousValue),
    AdList = riak_dt_orset:value(AdList0),
    case length(AdList) of
    0 ->
    %% No advertisements left to display; ignore
    %% message.
    client(Id, AdsWithContracts, AdList0);
    _ ->
    %% Select a random advertisement from the list of
    %% active advertisements.
    {#ad{counter=Ad}, _} = lists:nth(
    random:uniform(length(AdList)), AdList),
    %% Increment it.
    {ok, _} = lasp:update(Ad, increment, Id),
    lager:info("Incremented ad counter: ~p", [Ad]),
    client(Id, AdsWithContracts, AdList0)
    end
    end.

    View Slide

  101. %% @doc Server functions for the advertisement counter. After 5 views,
    %% disable the advertisement.
    %%
    server({#ad{counter=Counter}=Ad, _}, Ads) ->
    %% Blocking threshold read for 5 advertisement impressions.
    {ok, _} = lasp:read(Counter, 5),
    %% Remove the advertisement.
    {ok, _} = lasp:update(Ads, {remove, Ad}, Ad),
    lager:info("Removing ad: ~p", [Ad]).

    View Slide

  102. %% Generate a series of unique identifiers.
    RovioAdIds = lists:map(fun(_) -> druuid:v4() end, lists:seq(1, 10)),
    lager:info("Rovio Ad Identifiers are: ~p", [RovioAdIds]),
    TriforkAdIds = lists:map(fun(_) -> druuid:v4() end, lists:seq(1, 10)),
    lager:info("Trifork Ad Identifiers are: ~p", [TriforkAdIds]),
    Ids = RovioAdIds ++ TriforkAdIds,
    lager:info("Ad Identifiers are: ~p", [Ids]),
    %% Generate Rovio's advertisements.
    {ok, RovioAds} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    %% Generate a G-Counter.
    {ok, CounterId} = lasp:declare(?COUNTER),
    %% Add it to the advertisement set.
    {ok, _} = lasp:update(RovioAds,
    {add, #ad{id=Id, counter=CounterId}},
    undefined)
    end, RovioAdIds),
    %% Generate Trifork's advertisements.
    {ok, TriforkAds} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    %% Generate a G-Counter.
    {ok, CounterId} = lasp:declare(?COUNTER),
    %% Add it to the advertisement set.
    {ok, _} = lasp:update(TriforkAds,
    {add, #ad{id=Id, counter=CounterId}},
    undefined)
    end, TriforkAdIds),
    %% Union ads.
    {ok, Ads} = lasp:declare(?SET),
    ok = lasp:union(RovioAds, TriforkAds, Ads),
    %% For each identifier, generate a contract.
    {ok, Contracts} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    {ok, _} = lasp:update(Contracts,
    {add, #contract{id=Id}},
    undefined)
    end, Ids),
    %% Compute the Cartesian product of both ads and contracts.
    {ok, AdsContracts} = lasp:declare(?SET),
    ok = lasp:product(Ads, Contracts, AdsContracts),
    %% Filter items by join on item it.
    {ok, AdsWithContracts} = lasp:declare(?SET),
    FilterFun = fun({#ad{id=Id1}, #contract{id=Id2}}) ->
    Id1 =:= Id2
    end,
    ok = lasp:filter(AdsContracts, FilterFun, AdsWithContracts),
    %% Launch a series of client processes, each of which is responsible
    %% for displaying a particular advertisement.
    %% Generate a OR-set for tracking clients.
    {ok, Clients} = lasp:declare(?SET),
    %% Each client takes the full list of ads when it starts, and reads
    %% from the variable store.
    lists:map(fun(Id) ->
    ClientPid = spawn_link(?MODULE, client,
    [Id, AdsWithContracts, undefined]),
    {ok, _} = lasp:update(Clients,
    {add, ClientPid},
    undefined)
    end, lists:seq(1,5)),
    %% Launch a server process for each advertisement, which will block
    %% until the advertisement should be disabled.
    %% Create a OR-set for the server list.
    {ok, Servers} = lasp:declare(?SET),
    %% Get the current advertisement list.
    {ok, {_, _, AdList0}} = lasp:read(AdsWithContracts),
    AdList = riak_dt_orset:value(AdList0),
    %% For each advertisement, launch one server for tracking it's
    %% impressions and wait to disable.
    lists:map(fun(Ad) ->
    ServerPid = spawn_link(?MODULE, server, [Ad, Ads]),
    {ok, _} = lasp:update(Servers,
    {add, ServerPid},
    undefined)
    end, AdList),

    View Slide

  103. %% Generate a series of unique identifiers.
    RovioAdIds = lists:map(fun(_) -> druuid:v4() end, lists:seq(1, 10)),
    lager:info("Rovio Ad Identifiers are: ~p", [RovioAdIds]),
    TriforkAdIds = lists:map(fun(_) -> druuid:v4() end, lists:seq(1, 10)),
    lager:info("Trifork Ad Identifiers are: ~p", [TriforkAdIds]),
    Ids = RovioAdIds ++ TriforkAdIds,
    lager:info("Ad Identifiers are: ~p", [Ids]),
    %% Generate Rovio's advertisements.
    {ok, RovioAds} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    %% Generate a G-Counter.
    {ok, CounterId} = lasp:declare(?COUNTER),
    %% Add it to the advertisement set.
    {ok, _} = lasp:update(RovioAds,
    {add, #ad{id=Id, counter=CounterId}},
    undefined)
    end, RovioAdIds),
    %% Generate Trifork's advertisements.
    {ok, TriforkAds} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    %% Generate a G-Counter.
    {ok, CounterId} = lasp:declare(?COUNTER),
    %% Add it to the advertisement set.
    {ok, _} = lasp:update(TriforkAds,
    {add, #ad{id=Id, counter=CounterId}},
    undefined)
    end, TriforkAdIds),
    %% Union ads.
    {ok, Ads} = lasp:declare(?SET),
    ok = lasp:union(RovioAds, TriforkAds, Ads),
    %% For each identifier, generate a contract.
    {ok, Contracts} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    {ok, _} = lasp:update(Contracts,
    {add, #contract{id=Id}},
    undefined)
    end, Ids),
    %% Compute the Cartesian product of both ads and contracts.
    {ok, AdsContracts} = lasp:declare(?SET),
    ok = lasp:product(Ads, Contracts, AdsContracts),
    %% Filter items by join on item it.
    {ok, AdsWithContracts} = lasp:declare(?SET),
    FilterFun = fun({#ad{id=Id1}, #contract{id=Id2}}) ->
    Id1 =:= Id2
    end,
    ok = lasp:filter(AdsContracts, FilterFun, AdsWithContracts),
    %% Launch a series of client processes, each of which is responsible
    %% for displaying a particular advertisement.
    %% Generate a OR-set for tracking clients.
    {ok, Clients} = lasp:declare(?SET),
    %% Each client takes the full list of ads when it starts, and reads
    %% from the variable store.
    lists:map(fun(Id) ->
    ClientPid = spawn_link(?MODULE, client,
    [Id, AdsWithContracts, undefined]),
    {ok, _} = lasp:update(Clients,
    {add, ClientPid},
    undefined)
    end, lists:seq(1,5)),
    %% Launch a server process for each advertisement, which will block
    %% until the advertisement should be disabled.
    %% Create a OR-set for the server list.
    {ok, Servers} = lasp:declare(?SET),
    %% Get the current advertisement list.
    {ok, {_, _, AdList0}} = lasp:read(AdsWithContracts),
    AdList = riak_dt_orset:value(AdList0),
    %% For each advertisement, launch one server for tracking it's
    %% impressions and wait to disable.
    lists:map(fun(Ad) ->
    ServerPid = spawn_link(?MODULE, server, [Ad, Ads]),
    {ok, _} = lasp:update(Servers,
    {add, ServerPid},
    undefined)
    end, AdList),

    View Slide

  104. %% Generate a series of unique identifiers.
    RovioAdIds = lists:map(fun(_) -> druuid:v4() end, lists:seq(1, 10)),
    lager:info("Rovio Ad Identifiers are: ~p", [RovioAdIds]),
    TriforkAdIds = lists:map(fun(_) -> druuid:v4() end, lists:seq(1, 10)),
    lager:info("Trifork Ad Identifiers are: ~p", [TriforkAdIds]),
    Ids = RovioAdIds ++ TriforkAdIds,
    lager:info("Ad Identifiers are: ~p", [Ids]),
    %% Generate Rovio's advertisements.
    {ok, RovioAds} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    %% Generate a G-Counter.
    {ok, CounterId} = lasp:declare(?COUNTER),
    %% Add it to the advertisement set.
    {ok, _} = lasp:update(RovioAds,
    {add, #ad{id=Id, counter=CounterId}},
    undefined)
    end, RovioAdIds),
    %% Generate Trifork's advertisements.
    {ok, TriforkAds} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    %% Generate a G-Counter.
    {ok, CounterId} = lasp:declare(?COUNTER),
    %% Add it to the advertisement set.
    {ok, _} = lasp:update(TriforkAds,
    {add, #ad{id=Id, counter=CounterId}},
    undefined)
    end, TriforkAdIds),
    %% Union ads.
    {ok, Ads} = lasp:declare(?SET),
    ok = lasp:union(RovioAds, TriforkAds, Ads),
    %% For each identifier, generate a contract.
    {ok, Contracts} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    {ok, _} = lasp:update(Contracts,
    {add, #contract{id=Id}},
    undefined)
    end, Ids),
    %% Compute the Cartesian product of both ads and contracts.
    {ok, AdsContracts} = lasp:declare(?SET),
    ok = lasp:product(Ads, Contracts, AdsContracts),
    %% Filter items by join on item it.
    {ok, AdsWithContracts} = lasp:declare(?SET),
    FilterFun = fun({#ad{id=Id1}, #contract{id=Id2}}) ->
    Id1 =:= Id2
    end,
    ok = lasp:filter(AdsContracts, FilterFun, AdsWithContracts),
    %% Launch a series of client processes, each of which is responsible
    %% for displaying a particular advertisement.
    %% Generate a OR-set for tracking clients.
    {ok, Clients} = lasp:declare(?SET),
    %% Each client takes the full list of ads when it starts, and reads
    %% from the variable store.
    lists:map(fun(Id) ->
    ClientPid = spawn_link(?MODULE, client,
    [Id, AdsWithContracts, undefined]),
    {ok, _} = lasp:update(Clients,
    {add, ClientPid},
    undefined)
    end, lists:seq(1,5)),
    %% Launch a server process for each advertisement, which will block
    %% until the advertisement should be disabled.
    %% Create a OR-set for the server list.
    {ok, Servers} = lasp:declare(?SET),
    %% Get the current advertisement list.
    {ok, {_, _, AdList0}} = lasp:read(AdsWithContracts),
    AdList = riak_dt_orset:value(AdList0),
    %% For each advertisement, launch one server for tracking it's
    %% impressions and wait to disable.
    lists:map(fun(Ad) ->
    ServerPid = spawn_link(?MODULE, server, [Ad, Ads]),
    {ok, _} = lasp:update(Servers,
    {add, ServerPid},
    undefined)
    end, AdList),

    View Slide

  105. %% Generate a series of unique identifiers.
    RovioAdIds = lists:map(fun(_) -> druuid:v4() end, lists:seq(1, 10)),
    lager:info("Rovio Ad Identifiers are: ~p", [RovioAdIds]),
    TriforkAdIds = lists:map(fun(_) -> druuid:v4() end, lists:seq(1, 10)),
    lager:info("Trifork Ad Identifiers are: ~p", [TriforkAdIds]),
    Ids = RovioAdIds ++ TriforkAdIds,
    lager:info("Ad Identifiers are: ~p", [Ids]),
    %% Generate Rovio's advertisements.
    {ok, RovioAds} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    %% Generate a G-Counter.
    {ok, CounterId} = lasp:declare(?COUNTER),
    %% Add it to the advertisement set.
    {ok, _} = lasp:update(RovioAds,
    {add, #ad{id=Id, counter=CounterId}},
    undefined)
    end, RovioAdIds),
    %% Generate Trifork's advertisements.
    {ok, TriforkAds} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    %% Generate a G-Counter.
    {ok, CounterId} = lasp:declare(?COUNTER),
    %% Add it to the advertisement set.
    {ok, _} = lasp:update(TriforkAds,
    {add, #ad{id=Id, counter=CounterId}},
    undefined)
    end, TriforkAdIds),
    %% Union ads.
    {ok, Ads} = lasp:declare(?SET),
    ok = lasp:union(RovioAds, TriforkAds, Ads),
    %% For each identifier, generate a contract.
    {ok, Contracts} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    {ok, _} = lasp:update(Contracts,
    {add, #contract{id=Id}},
    undefined)
    end, Ids),
    %% Compute the Cartesian product of both ads and contracts.
    {ok, AdsContracts} = lasp:declare(?SET),
    ok = lasp:product(Ads, Contracts, AdsContracts),
    %% Filter items by join on item it.
    {ok, AdsWithContracts} = lasp:declare(?SET),
    FilterFun = fun({#ad{id=Id1}, #contract{id=Id2}}) ->
    Id1 =:= Id2
    end,
    ok = lasp:filter(AdsContracts, FilterFun, AdsWithContracts),
    %% Launch a series of client processes, each of which is responsible
    %% for displaying a particular advertisement.
    %% Generate a OR-set for tracking clients.
    {ok, Clients} = lasp:declare(?SET),
    %% Each client takes the full list of ads when it starts, and reads
    %% from the variable store.
    lists:map(fun(Id) ->
    ClientPid = spawn_link(?MODULE, client,
    [Id, AdsWithContracts, undefined]),
    {ok, _} = lasp:update(Clients,
    {add, ClientPid},
    undefined)
    end, lists:seq(1,5)),
    %% Launch a server process for each advertisement, which will block
    %% until the advertisement should be disabled.
    %% Create a OR-set for the server list.
    {ok, Servers} = lasp:declare(?SET),
    %% Get the current advertisement list.
    {ok, {_, _, AdList0}} = lasp:read(AdsWithContracts),
    AdList = riak_dt_orset:value(AdList0),
    %% For each advertisement, launch one server for tracking it's
    %% impressions and wait to disable.
    lists:map(fun(Ad) ->
    ServerPid = spawn_link(?MODULE, server, [Ad, Ads]),
    {ok, _} = lasp:update(Servers,
    {add, ServerPid},
    undefined)
    end, AdList),

    View Slide

  106. %% Generate a series of unique identifiers.
    RovioAdIds = lists:map(fun(_) -> druuid:v4() end, lists:seq(1, 10)),
    lager:info("Rovio Ad Identifiers are: ~p", [RovioAdIds]),
    TriforkAdIds = lists:map(fun(_) -> druuid:v4() end, lists:seq(1, 10)),
    lager:info("Trifork Ad Identifiers are: ~p", [TriforkAdIds]),
    Ids = RovioAdIds ++ TriforkAdIds,
    lager:info("Ad Identifiers are: ~p", [Ids]),
    %% Generate Rovio's advertisements.
    {ok, RovioAds} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    %% Generate a G-Counter.
    {ok, CounterId} = lasp:declare(?COUNTER),
    %% Add it to the advertisement set.
    {ok, _} = lasp:update(RovioAds,
    {add, #ad{id=Id, counter=CounterId}},
    undefined)
    end, RovioAdIds),
    %% Generate Trifork's advertisements.
    {ok, TriforkAds} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    %% Generate a G-Counter.
    {ok, CounterId} = lasp:declare(?COUNTER),
    %% Add it to the advertisement set.
    {ok, _} = lasp:update(TriforkAds,
    {add, #ad{id=Id, counter=CounterId}},
    undefined)
    end, TriforkAdIds),
    %% Union ads.
    {ok, Ads} = lasp:declare(?SET),
    ok = lasp:union(RovioAds, TriforkAds, Ads),
    %% For each identifier, generate a contract.
    {ok, Contracts} = lasp:declare(?SET),
    lists:map(fun(Id) ->
    {ok, _} = lasp:update(Contracts,
    {add, #contract{id=Id}},
    undefined)
    end, Ids),
    %% Compute the Cartesian product of both ads and contracts.
    {ok, AdsContracts} = lasp:declare(?SET),
    ok = lasp:product(Ads, Contracts, AdsContracts),
    %% Filter items by join on item it.
    {ok, AdsWithContracts} = lasp:declare(?SET),
    FilterFun = fun({#ad{id=Id1}, #contract{id=Id2}}) ->
    Id1 =:= Id2
    end,
    ok = lasp:filter(AdsContracts, FilterFun, AdsWithContracts),
    %% Launch a series of client processes, each of which is responsible
    %% for displaying a particular advertisement.
    %% Generate a OR-set for tracking clients.
    {ok, Clients} = lasp:declare(?SET),
    %% Each client takes the full list of ads when it starts, and reads
    %% from the variable store.
    lists:map(fun(Id) ->
    ClientPid = spawn_link(?MODULE, client,
    [Id, AdsWithContracts, undefined]),
    {ok, _} = lasp:update(Clients,
    {add, ClientPid},
    undefined)
    end, lists:seq(1,5)),
    %% Launch a server process for each advertisement, which will block
    %% until the advertisement should be disabled.
    %% Create a OR-set for the server list.
    {ok, Servers} = lasp:declare(?SET),
    %% Get the current advertisement list.
    {ok, {_, _, AdList0}} = lasp:read(AdsWithContracts),
    AdList = riak_dt_orset:value(AdList0),
    %% For each advertisement, launch one server for tracking it's
    %% impressions and wait to disable.
    lists:map(fun(Ad) ->
    ServerPid = spawn_link(?MODULE, server, [Ad, Ads]),
    {ok, _} = lasp:update(Servers,
    {add, ServerPid},
    undefined)
    end, AdList),

    View Slide

  107. RELATED WORK
    107

    View Slide

  108. DISTRIBUTED OZ
    RELATED WORK
    108

    View Slide

  109. DERFLOWL
    RELATED WORK
    109

    View Slide

  110. BLOOML
    RELATED WORK
    110

    View Slide

  111. LVARS
    RELATED WORK
    111

    View Slide

  112. D-STREAMS
    RELATED WORK
    112

    View Slide

  113. SUMMINGBIRD
    RELATED WORK
    113

    View Slide

  114. FUTURE WORK
    114

    View Slide

  115. INVARIANT PRESERVATION
    FUTURE WORK
    115

    View Slide

  116. CAUSAL+ CONSISTENCY
    FUTURE WORK
    116

    View Slide

  117. ORSWOT OPTIMIZATION
    FUTURE WORK
    117

    View Slide

  118. DELTA STATE-CRDTs
    FUTURE WORK
    118

    View Slide

  119. OPERATION-BASED CRDTs
    FUTURE WORK
    119

    View Slide

  120. DEFORESTATION
    FUTURE WORK
    120

    View Slide

  121. GITHUB.COM/CMEIKLEJOHN/LASP
    SOURCE
    121

    View Slide

  122. DERFLOW
    DISTRIBUTED DETERMINISTIC DATAFLOW
    PROGRAMMING FOR ERLANG
    ERLANG WORKSHOP 2014
    122

    View Slide

  123. LASP
    A LANGUAGE FOR DISTRIBUTED, EVENTUALLY
    CONSISTENT COMPUTATIONS WITH CRDTs
    PAPOC / EUROSYS 2015
    123

    View Slide

  124. SYNCFREE IS A EUROPEAN RESEARCH PROJECT TAKING PLACE
    FOR 3 YEARS, STARING OCTOBER 2013, AND IS FUNDED BY
    THE EUROPEAN UNION, GRANT AGREEMENT N°609551.
    SYNCFREE
    124

    View Slide

  125. FIN
    125

    View Slide