Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

LASP 2

Slide 3

Slide 3 text

EVENTUALLY CONSISTENT COMPUTATIONS DISTRIBUTED 3

Slide 4

Slide 4 text

CHRISTOPHER MEIKLEJOHN EN TAL AV 4

Slide 5

Slide 5 text

RESEARCH WITH: PETER VAN ROY (UCL) 5

Slide 6

Slide 6 text

MOTIVATION 6

Slide 7

Slide 7 text

EXPENSIVE SYNCHRONIZATION IS 7

Slide 8

Slide 8 text

SOMETIMES IMPRACTICAL SYNCHRONIZATION IS 8

Slide 9

Slide 9 text

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/

Slide 10

Slide 10 text

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.

Slide 11

Slide 11 text

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.

Slide 12

Slide 12 text

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.

Slide 13

Slide 13 text

RECONCILED BY USER CONCURRENCY 13

Slide 14

Slide 14 text

RA RB 1 1 3 2 ? ? 14

Slide 15

Slide 15 text

RA RB 1 1 3 2 ? ? 15

Slide 16

Slide 16 text

RA RB 1 1 3 2 ? ? 16

Slide 17

Slide 17 text

RA RB 1 1 3 2 ? ? 17

Slide 18

Slide 18 text

CRDTs 18

Slide 19

Slide 19 text

DETERMINISTIC RESOLUTION CRDTs PROVIDE 19

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

STRONG EVENTUAL CONSISTENCY CRDTs REALIZE 21

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

‘MAX’ REGISTER CRDTs EXAMPLE 23

Slide 24

Slide 24 text

RA RB 1 1 3 2 3 3 24

Slide 25

Slide 25 text

‘ORSET’ SET CRDTs EXAMPLE 25

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

NONTRIVIAL COMPOSITION IS 30

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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.

Slide 39

Slide 39 text

LASP 39

Slide 40

Slide 40 text

LASP WHAT IS 40

Slide 41

Slide 41 text

LATTICE PROCESSING LASP 41

Slide 42

Slide 42 text

CENTRALIZED SEMANTICS: DATATYPE COMPOSITION 42

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

DISTRIBUTED SEMANTICS: DATATYPE COMPOSITION 44

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

DISTRIBUTED SEMANTICS: SYSTEM COMPOSITION 46

Slide 47

Slide 47 text

CENTRALIZED RUNTIME: SINGLE NODE MODEL 47

Slide 48

Slide 48 text

DISTRIBUED RUNTIME: MULTI-NODE MODEL 48

Slide 49

Slide 49 text

SEMANTICS 49

Slide 50

Slide 50 text

STREAMS 50

Slide 51

Slide 51 text

STREAMS: CENTRALIZED EXECUTION 51

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

STREAMS: DISTRIBUTED EXECUTION 53

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

STREAMS: CONCURRENCY; FAILURE; ANTI-ENTROPY 55

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

MONOTONIC READ 60

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

FUNCTIONAL 63

Slide 64

Slide 64 text

FUNCTIONAL: MAP; FILTER; FOLD 64

Slide 65

Slide 65 text

SET-THEORETIC 65

Slide 66

Slide 66 text

SET-THEORETIC: PRODUCT; INTERSECTION; UNION 66

Slide 67

Slide 67 text

ARCHITECTURE 67

Slide 68

Slide 68 text

SHARED VARIABLE STORE LASP STORE 68

Slide 69

Slide 69 text

LEVELDB, BITCASK, ETS LASP BACKENDS 69

Slide 70

Slide 70 text

PROVIDED BY RIAK DT LASP CRDTs 70

Slide 71

Slide 71 text

CENTRALIZED SEMANTICS LASP ARCHITECTURE 71

Slide 72

Slide 72 text

STORE: SHARED VARIABLE STORE PROCESSESS SYNCHRONIZE ON VARIABLES 72

Slide 73

Slide 73 text

DISTRIBUTED SEMANTICS LASP ARCHITECTURE 73

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

EXAMPLES 77

Slide 78

Slide 78 text

%% 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),

Slide 79

Slide 79 text

%% 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),

Slide 80

Slide 80 text

AD COUNTER 80

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

INFORMATION FLOW AD COUNTER 82

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

DISTRIBUTION AD COUNTER 93

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

DISTRIBUTION BOUNDARIES: ARBITRARY ALLOWS COMPOSITION OF ENTIRE SYSTEM 98

Slide 99

Slide 99 text

EXAMPLE CODE AD COUNTER 99

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

%% @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]).

Slide 102

Slide 102 text

%% 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),

Slide 103

Slide 103 text

%% 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),

Slide 104

Slide 104 text

%% 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),

Slide 105

Slide 105 text

%% 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),

Slide 106

Slide 106 text

%% 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),

Slide 107

Slide 107 text

RELATED WORK 107

Slide 108

Slide 108 text

DISTRIBUTED OZ RELATED WORK 108

Slide 109

Slide 109 text

DERFLOWL RELATED WORK 109

Slide 110

Slide 110 text

BLOOML RELATED WORK 110

Slide 111

Slide 111 text

LVARS RELATED WORK 111

Slide 112

Slide 112 text

D-STREAMS RELATED WORK 112

Slide 113

Slide 113 text

SUMMINGBIRD RELATED WORK 113

Slide 114

Slide 114 text

FUTURE WORK 114

Slide 115

Slide 115 text

INVARIANT PRESERVATION FUTURE WORK 115

Slide 116

Slide 116 text

CAUSAL+ CONSISTENCY FUTURE WORK 116

Slide 117

Slide 117 text

ORSWOT OPTIMIZATION FUTURE WORK 117

Slide 118

Slide 118 text

DELTA STATE-CRDTs FUTURE WORK 118

Slide 119

Slide 119 text

OPERATION-BASED CRDTs FUTURE WORK 119

Slide 120

Slide 120 text

DEFORESTATION FUTURE WORK 120

Slide 121

Slide 121 text

GITHUB.COM/CMEIKLEJOHN/LASP SOURCE 121

Slide 122

Slide 122 text

DERFLOW DISTRIBUTED DETERMINISTIC DATAFLOW PROGRAMMING FOR ERLANG ERLANG WORKSHOP 2014 122

Slide 123

Slide 123 text

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

Slide 124

Slide 124 text

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

Slide 125

Slide 125 text

FIN 125