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

Coordination-Free Computations

Coordination-Free Computations

GOTO Chicago 2015
Chicago, IL

Christopher Meiklejohn

May 12, 2015
Tweet

More Decks by Christopher Meiklejohn

Other Decks in Programming

Transcript

  1. Coordination-Free
    Computations
    Christopher Meiklejohn

    View Slide

  2. DISTRIBUTED, EVENTUALLY CONSISTENT COMPUTATIONS
    LASP
    2
    CHRISTOPHER MEIKLEJOHN (BASHO TECHNOLOGIES, INC.)
    PETER VAN ROY (UNIVERSITÉ CATHOLIQUE DE LOUVAIN)

    View Slide

  3. LASP MOTIVATION
    3

    View Slide

  4. EXPENSIVE / IMPRACTICAL
    SYNCHRONIZATION IS
    4

    View Slide

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

    View Slide

  6. DISJOINT STATE AGGREGATED UPSTREAM
    CLIENTS GO OFFLINE
    “INTERNET OF THINGS”:
    6
    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

  7. NO TOTAL ORDER:
    REPLICATED SHARED STATE WITH OFFLINE CLIENTS
    CLIENTS NEED TO MAKE PROGRESS
    7
    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

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

    View Slide

  9. RECONCILED BY USER
    CONCURRENCY
    9

    View Slide

  10. RA
    RB
    1
    3
    2
    ?
    ?
    set(1) set(2)
    set(3)
    10

    View Slide

  11. RA
    RB
    1
    3
    2
    ?
    ?
    set(1) set(2)
    set(3)
    11

    View Slide

  12. RA
    RB
    1
    3
    2
    ?
    ?
    set(1) set(2)
    set(3)
    12

    View Slide

  13. RA
    RB
    1
    3
    2
    ?
    ?
    set(1) set(2)
    set(3)
    13

    View Slide

  14. CRDTs
    14

    View Slide

  15. DETERMINISTIC RESOLUTION
    CRDTs PROVIDE
    15

    View Slide

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

    View Slide

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

    View Slide

  18. ‘MAX’ REGISTER
    CRDTs EXAMPLE
    18

    View Slide

  19. RA
    RB
    1
    3
    2
    3
    3
    set(1) set(2)
    set(3)
    max(2,3)
    max(2,3)
    19

    View Slide

  20. ‘ORSET’ SET
    CRDTs EXAMPLE
    20

    View Slide

  21. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    add(1)
    add(1) remove(1)
    21

    View Slide

  22. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    add(1)
    add(1) remove(1)
    22

    View Slide

  23. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    add(1)
    add(1) remove(1)
    23

    View Slide

  24. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    add(1)
    add(1) remove(1)
    24

    View Slide

  25. FRAGMENTS & PROGRAMS
    25

    View Slide

  26. {1,2,3}
    {3,4,5}
    26

    View Slide

  27. {1,2,3}
    {3,4,5}
    Intersection {3}
    27

    View Slide

  28. {1,2,3}
    {3,4,5}
    Intersection {3} Map {9}
    28

    View Slide

  29. {1,2,3}
    {3,4,5}
    Intersection {3} Map {9}
    29

    View Slide

  30. {1,2,3}
    {3,4,5}
    Intersection {3} Map {9}
    30

    View Slide

  31. {1,2,3}
    {3,4,5}
    Intersection {3} Map {9}
    31

    View Slide

  32. {1,2,3}
    {3,4,5}
    Intersection {3} Map {9}
    {1,2,3}
    {3,4,5}
    Intersection {3} Map {9}
    32

    View Slide

  33. {1,2,3}
    {3,4,5}
    Intersection {3} Map {9}
    {1,2,3}
    {3,4,5}
    Intersection {3} Map {9}
    33

    View Slide

  34. {1,2,3}
    {3,4,5}
    Intersection {3} Map {9}
    {1,2,3}
    {3,4,5}
    Intersection {3} Map {9}
    34

    View Slide

  35. NONTRIVIAL
    FUNCTION APPLICATION AND DATA COMPOSITION IS
    35

    View Slide

  36. RA
    RB
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    add(1)
    add(1) remove(1)
    F(RC) {2}
    fun(X) -> 2 end
    {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})
    add(1)
    add(1) remove(1)
    F(RC) {2}
    fun(X) -> 2 end
    {2} {}
    F(RA) {2}
    fun(X) -> 2 end
    {2} {2} {2}
    37

    View Slide

  38. RA
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    add(1)
    add(1) remove(1)
    F(RC) {2}
    fun(X) -> 2 end
    {2} {}
    F(RA) {2}
    fun(X) -> 2 end
    {2} {2} {2}
    38

    View Slide

  39. RA
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    add(1)
    add(1) remove(1)
    F(RC) {2}
    fun(X) -> 2 end
    {2} {}
    F(RA) {2}
    fun(X) -> 2 end
    {2} {2} {2}
    39

    View Slide

  40. RA
    RC
    {1}
    (1, {a}, {})
    {1}
    (1, {b}, {})
    {}
    (1, {b}, {b})
    {1}
    {1}
    (1, {a, b}, {b})
    (1, {a, b}, {b})
    add(1)
    add(1) remove(1)
    F(RC) {2}
    fun(X) -> 2 end
    {2} {}
    F(RA) {2}
    fun(X) -> 2 end
    {2} {2} {2}
    40

    View Slide

  41. COMPOSITION:
    USER OBSERVABLE VALUE VS. STATE
    METADATA MAPPING IS NONTRIVIAL
    WITHOUT MAPPING METADATA; UNMERGABLE
    41
    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

  42. LASP LANGUAGE
    42

    View Slide

  43. LASP:
    DISTRIBUTED RUNTIME
    IMPLEMENTED AS ERLANG LIBRARY
    USES RIAK-CORE
    43

    View Slide

  44. LASP:
    CRDTS AS STREAMS OF STATE CHANGES
    CRDTS CONNECTED BY MONOTONIC PROCESSES
    MANY TO ONE MAPPING OF CRDTS
    44

    View Slide

  45. PRIMITIVE OPERATIONS:
    MONOTONIC READ, UPDATE
    FUNCTIONAL: MAP, FILTER, FOLD
    SET-THEORETIC: PRODUCT, UNION, INTERSECTION
    LIFTED TO OPERATE OVER METADATA
    45

    View Slide

  46. MAP
    EXAMPLE
    46

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  51. ARCHITECTURE
    51

    View Slide

  52. SHARED VARIABLE STORE
    LASP STORE
    52

    View Slide

  53. LEVELDB, BITCASK, ETS
    LASP BACKENDS
    53

    View Slide

  54. PROVIDED BY RIAK DT
    LASP CRDTs
    54

    View Slide

  55. CENTRALIZED SEMANTICS
    LASP ARCHITECTURE
    55

    View Slide

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

    View Slide

  57. DISTRIBUTED SEMANTICS
    LASP ARCHITECTURE
    57

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  61. EXAMPLES
    61

    View Slide

  62. %% 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

  63. %% 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

  64. AD COUNTER
    64

    View Slide

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

    View Slide

  66. INFORMATION FLOW
    AD COUNTER
    66

    View Slide

  67. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    67

    View Slide

  68. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Riot Ads
    Rovio Ads
    Produ
    Read
    50,000
    Remove
    Increment
    Union
    68

    View Slide

  69. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    69

    View Slide

  70. Ads
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    ds
    Ads
    Filter
    Product
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    70

    View Slide

  71. Ads
    ntracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Filter
    Product
    Read
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    71

    View Slide

  72. Ads
    Contracts
    Ads
    With
    Contracts
    Filter
    Read
    Operation
    Maintained CRDT
    Maintained CRDT
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    72

    View Slide

  73. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove
    Increment
    Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    73

    View Slide

  74. Ads
    Rovio Ad
    Counter
    Rovio Ad
    Counter
    Riot Ad
    Counter
    Riot Ad
    Counter
    Contracts
    Ads
    Contracts
    Riot Ads
    Rovio Ads
    Product
    Read
    50,000
    Remove
    Increment
    Union
    Lasp Operation
    User-Maintained C
    Lasp-Maintained C
    74

    View Slide

  75. Ads
    Contracts
    Ads
    Contracts
    Ads
    With
    Contracts
    Riot Ads
    Rovio Ads
    Filter
    Product
    Read
    50,000
    Remove Read
    Union
    Lasp Operation
    User-Maintained CRDT
    Lasp-Maintained CRDT
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    Counter1 Counter2 Counter3
    75

    View Slide

  76. INFORMATION FLOW:
    MONOTONIC
    METADATA TO PREVENT DUPLICATE PROPAGATION
    76

    View Slide

  77. EXAMPLE CODE
    AD COUNTER
    77

    View Slide

  78. %% @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

  79. %% @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

  80. %% 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

  81. %% 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

  82. %% 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

  83. %% 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

  84. %% 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

  85. DISTRIBUTION
    AD COUNTER
    85

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  91. MATERIALIZED VIEWS
    91

    View Slide

  92. MATERIALIZED VIEWS:
    INCREMENTALLY UPDATING, DELTA PROPAGATION
    SCHEMA BASED OR DYNAMIC; 2I IN RIAK
    92

    View Slide

  93. DATABASE AS STREAM OF UPDATES
    93

    View Slide

  94. Riak
    K1 K2 K3 K1 K2
    94

    View Slide

  95. Riak
    K1 K2 K3 K1 K2
    RS1
    RS2
    RS3
    95

    View Slide

  96. Riak
    K1 K2 K3 K1 K2
    RS1
    RS2
    RS3
    K1
    K1
    K2 K2
    K3
    96

    View Slide

  97. Riak
    K1 K2 K3 K1 K2
    RS2
    RS3
    K1
    K1
    K2 K2
    K3
    N1
    N2
    N3
    97

    View Slide

  98. COMPOSE PROGRAMS
    98

    View Slide

  99. Riak
    K1 K2 K3 K1 K2
    RS2
    RS3
    K1
    K1
    K2 K2
    K3
    N1
    N2
    N3
    Lasp Stream
    Processor
    Template
    99

    View Slide

  100. Riak
    K1 K2 K3 K1 K2
    RS2
    RS3
    K1
    K1
    K2 K2
    K3
    N1
    N2
    N3
    Lasp Stream
    Processor
    Template
    Lasp
    All Objects
    Program
    100

    View Slide

  101. Riak
    K1 K2 K3 K1 K2
    RS2
    RS3
    K1
    K1
    K2 K2
    K3
    N1
    N2
    N3
    Lasp Stream
    Processor
    Template
    Lasp
    All Objects
    Program
    Lasp
    “Over 65”
    Filter
    101

    View Slide

  102. Riak
    K1 K2 K3 K1 K2
    RS2
    RS3
    K1
    K1
    K2 K2
    K3
    N1
    N2
    N3
    Lasp Stream
    Processor
    Template
    Lasp
    All Objects
    Program
    Lasp
    “Over 65”
    Filter
    Lasp
    “Over 80”
    Filter
    102

    View Slide

  103. Riak
    K1 K2 K3 K1 K2
    RS2
    RS3
    K1
    K1
    K2 K2
    K3
    N1
    N2
    N3
    Lasp Stream
    Processor
    Template
    Lasp
    All Objects
    Program
    Lasp
    “Over 65”
    Filter
    Lasp
    “Over 80”
    Filter
    Lasp
    “Named Chris”
    Filter (L)
    103

    View Slide

  104. DISTRIBUTE APPLICATIONS
    104

    View Slide

  105. Riak
    K1 K2 K3 K1 K2
    RS2
    RS3
    K1
    K1
    K2 K2
    K3
    N1
    N2
    N3
    Lasp
    “Named Chris”
    Filter (L)
    L’’’
    L’’
    L’
    105

    View Slide

  106. MERGE
    RESULTS
    (SEC)
    106
    N1
    N2
    N3
    L’
    L’
    L’

    View Slide

  107. SUM RESULTS
    107
    RS1
    L’
    RS2
    L’’

    View Slide

  108. Riak
    K1 K2 K3 K1 K2
    RS2
    RS3
    K1
    K1
    K2 K2
    K3
    N1
    N2
    N3
    Execution of
    Lasp
    “Named Chris”
    Filter (L)
    L’’’
    L’’
    L’
    108

    View Slide

  109. CACHE:
    CACHE RESULTS OF MERGE
    SPECULATIVELY EXECUTE BASED ON DIVERGENCE
    109

    View Slide

  110. “INTERNET OF THINGS”
    110

    View Slide

  111. Riak
    K1 K2 K3 K1 K2
    RS2
    RS3
    K1
    K1
    K2 K2
    K3
    N1
    N2
    N3
    Execution of
    Lasp
    “Named Chris”
    Filter (L)
    L’’’
    L’’
    L’
    111

    View Slide

  112. IoT Network
    K1 K2 K3 K1 K2
    S1
    S2
    S3
    U1
    U1
    U2 U2
    U3
    Execution of
    Lasp
    Temperature
    Sensor > 90 F
    L’’’
    L’’
    L’
    112

    View Slide

  113. IoT Network
    S1
    S2
    S3
    U1
    U1
    U2 U2
    U3
    Execution of
    Lasp
    Temperature
    Sensor > 90 F
    L’’’
    L’’
    L’
    113

    View Slide

  114. IOT:
    EXECUTE AT THE EDGE
    WRITE CODE THINKING ABOUT “ALL” DATA
    114

    View Slide

  115. RELATED WORK
    115

    View Slide

  116. DISTRIBUTED OZ
    RELATED WORK
    116

    View Slide

  117. DERFLOWL
    RELATED WORK
    117

    View Slide

  118. BLOOML
    RELATED WORK
    118

    View Slide

  119. LVARS
    RELATED WORK
    119

    View Slide

  120. D-STREAMS
    RELATED WORK
    120

    View Slide

  121. SUMMINGBIRD
    RELATED WORK
    121

    View Slide

  122. FUTURE WORK
    122

    View Slide

  123. INVARIANT PRESERVATION
    FUTURE WORK
    123

    View Slide

  124. CAUSAL+ CONSISTENCY
    FUTURE WORK
    124

    View Slide

  125. ORSWOT OPTIMIZATION
    FUTURE WORK
    125

    View Slide

  126. DELTA STATE-CRDTs
    FUTURE WORK
    126

    View Slide

  127. OPERATION-BASED CRDTs
    FUTURE WORK
    127

    View Slide

  128. DEFORESTATION
    FUTURE WORK
    128

    View Slide

  129. GITHUB.COM/CMEIKLEJOHN/LASP
    SOURCE
    129

    View Slide

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

    View Slide

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

    View Slide

  132. NOVEMBER 4-6, 2015
    SAN FRANCISCO, CA
    RICON 2015
    132

    View Slide

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

    View Slide

  134. Questions?
    Please remember to evaluate via the GOTO
    Guide App

    View Slide