DISTRIBUTED EVENTUALLY CONSISTENT COMPUTATIONS

Similar documents
Coordination-Free Computations. Christopher Meiklejohn

Lasp: A Language for Distributed, Coordination-Free Programming

Selective Hearing: An Approach to Distributed, Eventually Consistent Edge Computation

Designing and Evaluating a Distributed Computing Language Runtime. Christopher Meiklejohn Université catholique de Louvain, Belgium

The Implementation and Use of a Generic Dataflow Behaviour in Erlang

Conflict-free Replicated Data Types in Practice

Riak. Distributed, replicated, highly available

Mutual consistency, what for? Replication. Data replication, consistency models & protocols. Difficulties. Execution Model.

Why distributed databases suck, and what to do about it. Do you want a database that goes down or one that serves wrong data?"

Eventual Consistency Today: Limitations, Extensions and Beyond

Self-healing Data Step by Step

SCALABLE CONSISTENCY AND TRANSACTION MODELS

The CAP theorem. The bad, the good and the ugly. Michael Pfeiffer Advanced Networking Technologies FG Telematik/Rechnernetze TU Ilmenau

CS Amazon Dynamo

Strong Eventual Consistency and CRDTs

Strong Eventual Consistency and CRDTs

Just-Right Consistency. Centralised data store. trois bases. As available as possible As consistent as necessary Correct by design

LightKone: Towards General Purpose Computations on the Edge

Distributed Systems (5DV147)

Eventually Consistent HTTP with Statebox and Riak

Genie. Distributed Systems Synthesis and Verification. Marc Rosen. EN : Advanced Distributed Systems and Networks May 1, 2017

Computing Parable. The Archery Teacher. Courtesy: S. Keshav, U. Waterloo. Computer Science. Lecture 16, page 1

Eventual Consistency Today: Limitations, Extensions and Beyond

Strong Consistency & CAP Theorem

TARDiS: A branch and merge approach to weak consistency

CS6450: Distributed Systems Lecture 11. Ryan Stutsman

Large-Scale Key-Value Stores Eventual Consistency Marco Serafini

Building Consistent Transactions with Inconsistent Replication

CAP Theorem, BASE & DynamoDB

Towards a Proof Framework for Information Systems with Weak Consistency

DYNAMO: AMAZON S HIGHLY AVAILABLE KEY-VALUE STORE. Presented by Byungjin Jun

Conflict-free Replicated Data Types (CRDTs)

Consistency and Replication. Some slides are from Prof. Jalal Y. Kawash at Univ. of Calgary

Chapter 7 Consistency And Replication

Dynamo: Amazon s Highly Available Key-Value Store

What Came First? The Ordering of Events in

Using Erlang, Riak and the ORSWOT CRDT at bet365 for Scalability and Performance. Michael Owen Research and Development Engineer

CS6450: Distributed Systems Lecture 15. Ryan Stutsman

Dynamo. Smruti R. Sarangi. Department of Computer Science Indian Institute of Technology New Delhi, India. Motivation System Architecture Evaluation

There is a tempta7on to say it is really used, it must be good

CSE 5306 Distributed Systems. Consistency and Replication

Eventual Consistency 1

Distributed systems. Lecture 6: distributed transactions, elections, consensus and replication. Malte Schwarzkopf

Advanced Databases ( CIS 6930) Fall Instructor: Dr. Markus Schneider. Group 17 Anirudh Sarma Bhaskara Sreeharsha Poluru Ameya Devbhankar

Dynamo: Key-Value Cloud Storage

Important Lessons. Today's Lecture. Two Views of Distributed Systems

Dynamo: Amazon s Highly Available Key-value Store

Weak Consistency and Disconnected Operation in git. Raymond Cheng

Managing Update Conflicts in Bayou. Lucy Youxuan Jiang, Hiwot Tadese Kassa

Chapter 11 - Data Replication Middleware

Dynamo: Amazon s Highly Available Key-value Store

Conflict-Free Replicated Data Types (basic entry)

SMAC: State Management for Geo-Distributed Containers

NoSQL systems: sharding, replication and consistency. Riccardo Torlone Università Roma Tre

Spanner: Google's Globally-Distributed Database. Presented by Maciej Swiech

INF-5360 Presentation

Large-Scale Geo-Replicated Conflict-free Replicated Data Types

CONSISTENT FOCUS. Building reliable distributed systems at a worldwide scale demands trade-offs between consistency and availability.

Lecture 6 Consistency and Replication

Bloom: Big Systems, Small Programs. Neil Conway UC Berkeley

DISTRIBUTED SYSTEMS Principles and Paradigms Second Edition ANDREW S. TANENBAUM MAARTEN VAN STEEN. Chapter 7 Consistency And Replication

Distributed Systems. replication Johan Montelius ID2201. Distributed Systems ID2201

Basic vs. Reliable Multicast

Distributed Data Management Replication

Towards a Solution to the Red Wedding Problem

Consistency and Replication

G Bayou: A Weakly Connected Replicated Storage System. Robert Grimm New York University

MUTE: A Peer-to-Peer Web-based Real-time Collaborative Editor

DISTRIBUTED COMPUTER SYSTEMS

What am I? Bryan Hunt Basho Client Services Engineer Erlang neophyte JVM refugee Be gentle

Deterministic Threshold Queries of Distributed Data Structures

4/9/2018 Week 13-A Sangmi Lee Pallickara. CS435 Introduction to Big Data Spring 2018 Colorado State University. FAQs. Architecture of GFS

CSE 544 Principles of Database Management Systems. Magdalena Balazinska Winter 2015 Lecture 14 NoSQL

Extending Eventually Consistent Cloud Databases for Enforcing Numeric Invariants

CISC 7610 Lecture 5 Distributed multimedia databases. Topics: Scaling up vs out Replication Partitioning CAP Theorem NoSQL NewSQL

#IoT #BigData. 10/31/14

Horizontal or vertical scalability? Horizontal scaling is challenging. Today. Scaling Out Key-Value Storage

Consistency and Replication. Why replicate?

Scaling Out Key-Value Storage

Distributed Systems. 19. Spanner. Paul Krzyzanowski. Rutgers University. Fall 2017

(It s the invariants, stupid)

Consistency and Replication

MINIMIZING TRANSACTION LATENCY IN GEO-REPLICATED DATA STORES

SCALABLE CONSISTENCY AND TRANSACTION MODELS THANKS TO M. GROSSNIKLAUS

Certified Program Models for Eventual Consistency

Replication in Distributed Systems

Abstract Specifications for Weakly Consistent Data

11/5/2018 Week 12-A Sangmi Lee Pallickara. CS435 Introduction to Big Data FALL 2018 Colorado State University

DEMYSTIFYING BIG DATA WITH RIAK USE CASES. Martin Schneider Basho Technologies!

Module 7 - Replication

DSMW: Distributed Semantic MediaWiki

Last time. Distributed systems Lecture 6: Elections, distributed transactions, and replication. DrRobert N. M. Watson

Spanner : Google's Globally-Distributed Database. James Sedgwick and Kayhan Dursun

Höllische Programmiersprachen Hauptseminar im Wintersemester 2014/2015 Determinism and reliability in the context of parallel programming

Coordination 2. Today. How can processes agree on an action or a value? l Group communication l Basic, reliable and l ordered multicast

Spanner: Google s Globally- Distributed Database

CS 655 Advanced Topics in Distributed Systems

Consistency and Replication (part b)

Distributed Systems. Characteristics of Distributed Systems. Lecture Notes 1 Basic Concepts. Operating Systems. Anand Tripathi

Distributed Systems. Characteristics of Distributed Systems. Characteristics of Distributed Systems. Goals in Distributed System Designs

Transcription:

LASP 2

DISTRIBUTED EVENTUALLY CONSISTENT COMPUTATIONS 3

EN TAL AV CHRISTOPHER MEIKLEJOHN 4

RESEARCH WITH: PETER VAN ROY (UCL) 5

MOTIVATION 6

SYNCHRONIZATION IS EXPENSIVE 7

SYNCHRONIZATION IS SOMETIMES IMPRACTICAL 8

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

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

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

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

CONCURRENCY RECONCILED BY USER 13

R A 1 2? R B 1 3? 14

R A 1 2? R B 1 3? 15

R A 1 2? R B 1 3? 16

R A 1 2? R B 1 3? 17

CRDTs 18

CRDTs PROVIDE DETERMINISTIC RESOLUTION 19

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

CRDTs REALIZE STRONG EVENTUAL CONSISTENCY 21

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

CRDTs EXAMPLE MAX REGISTER 23

R A 1 2 3 R B 1 3 3 24

CRDTs EXAMPLE ORSET SET 25

(1, {a}, {}) R A (1, {b}, {}) R B R C {} (1, {b}, {}) (1, {b}, {b}) 26

(1, {a}, {}) R A (1, {b}, {}) R B R C {} (1, {b}, {}) (1, {b}, {b}) 27

(1, {a}, {}) R A (1, {b}, {}) R B R C {} (1, {b}, {}) (1, {b}, {b}) 28

(1, {a}, {}) R A (1, {b}, {}) R B R C {} (1, {b}, {}) (1, {b}, {b}) 29

COMPOSITION IS NONTRIVIAL 30

R C {} (1, {b}, {}) (1, {b}, {b}) fun(x) -> 2 end F(R C ) {2} {} {2} {2} 31

(1, {a}, {}) R A (1, {b}, {}) R B R C {} (1, {b}, {}) (1, {b}, {b}) 32

(1, {a}, {}) R A (1, {b}, {}) R C {} (1, {b}, {}) (1, {b}, {b}) 33

(1, {a}, {}) R A F(R A ) {2} {2} {2} R C {} (1, {b}, {}) (1, {b}, {b}) F(R C ) {2} {} {2} {2} 34

(1, {a}, {}) R A F(R A ) {2} {2} {2} R C {} (1, {b}, {}) (1, {b}, {b}) F(R C ) {2} {} {2} {2} 35

(1, {a}, {}) R A F(R A ) {2} {2} {2} R C {} (1, {b}, {}) (1, {b}, {b}) F(R C ) {2} {} {2} {2} 36

(1, {a}, {}) R A F(R A ) {2} {2} {2} R C {} (1, {b}, {}) (1, {b}, {b}) F(R C ) {2} {} {2} {2} 37

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

LASP 39

WHAT IS LASP 40

LASP LATTICE PROCESSING 41

CENTRALIZED SEMANTICS: DATATYPE COMPOSITION 42

R {} (1, {b}, {}) (1, {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

DISTRIBUTED SEMANTICS: DATATYPE COMPOSITION 44

R A (1, {a}, {}) fun(x) -> 2 end F(R A) {2} {2} {2} (2, {a}, {}) (2, {a, b}, {b}) (2, {a, b}, {b}) R B (1, {b}, {}) fun(x) -> 2 end F(R B) {2} {2} {2} (2, {b}, {}) (2, {a, b}, {b}) (2, {a, b}, {b}) R C {} (1, {b}, {}) (1, {b}, {b}) fun(x) -> 2 end F(R C ) {2} {} {2} {2} (2, {b}, {}) (2, {b}, {b}) (2, {a, b}, {b}) (2, {a, b}, {b}) 45

DISTRIBUTED SEMANTICS: SYSTEM COMPOSITION 46

CENTRALIZED RUNTIME: SINGLE NODE MODEL 47

DISTRIBUED RUNTIME: MULTI-NODE MODEL 48

SEMANTICS 49

STREAMS 50

STREAMS: CENTRALIZED EXECUTION 51

R A (1, {a}, {}) 52

STREAMS: DISTRIBUTED EXECUTION 53

R A (1, {a}, {}) R B (1, {a}, {}) R C (1, {a}, {}) 54

STREAMS: CONCURRENCY; FAILURE; ANTI-ENTROPY 55

R A (1, {a}, {}) R B {} (1, {b}, {}) R C {} (1, {b}, {}) (1, {b}, {b}) 56

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

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

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

MONOTONIC READ 60

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

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

FUNCTIONAL 63

FUNCTIONAL: MAP; FILTER; FOLD 64

SET-THEORETIC 65

SET-THEORETIC: PRODUCT; INTERSECTION; UNION 66

ARCHITECTURE 67

LASP STORE SHARED VARIABLE STORE 68

LASP BACKENDS LEVELDB, BITCASK, ETS 69

LASP CRDTs PROVIDED BY RIAK DT 70

LASP ARCHITECTURE CENTRALIZED SEMANTICS 71

STORE: SHARED VARIABLE STORE PROCESSESS SYNCHRONIZE ON VARIABLES 72

LASP ARCHITECTURE DISTRIBUTED SEMANTICS 73

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

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

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

EXAMPLES 77

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

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

AD COUNTER 80

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

AD COUNTER INFORMATION FLOW 82

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

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

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

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

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

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

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

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

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

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

AD COUNTER DISTRIBUTION 93

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

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

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

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

DISTRIBUTION BOUNDARIES: ARBITRARY ALLOWS COMPOSITION OF ENTIRE SYSTEM 98

AD COUNTER EXAMPLE CODE 99

%% @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]), end. end client(id, AdsWithContracts, AdList0)

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

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

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

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

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

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

RELATED WORK 107

RELATED WORK DISTRIBUTED OZ 108

RELATED WORK DERFLOW L 109

RELATED WORK BLOOM L 110

RELATED WORK LVARS 111

RELATED WORK D-STREAMS 112

RELATED WORK SUMMINGBIRD 113

FUTURE WORK 114

FUTURE WORK INVARIANT PRESERVATION 115

FUTURE WORK CAUSAL+ CONSISTENCY 116

FUTURE WORK ORSWOT OPTIMIZATION 117

FUTURE WORK DELTA STATE-CRDTs 118

FUTURE WORK OPERATION-BASED CRDTs 119

FUTURE WORK DEFORESTATION 120

SOURCE GITHUB.COM/CMEIKLEJOHN/LASP 121

ERLANG WORKSHOP 2014 DERFLOW DISTRIBUTED DETERMINISTIC DATAFLOW PROGRAMMING FOR ERLANG 122

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

SYNCFREE 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. 124

FIN 125