• No results found

Collaborative Editing of Graphical Network using Eventual Consistency

N/A
N/A
Protected

Academic year: 2021

Share "Collaborative Editing of Graphical Network using Eventual Consistency"

Copied!
52
0
0

Loading.... (view fulltext now)

Full text

(1)

Linköpings universitet SE–581 83 Linköping

Linköping University | Department of Computer and Information Science

Master thesis, 30 ECTS | Datateknik

202017 | LIU-IDA/LITH-EX-A--2017/001--SE

Collaborative Editing of a

Graph-ical Network using Eventual

Con-sistency

Samverkande Redigering Av Grafiskt Nätverk med Eventuell

Kon-sekvens

Pierre Hedkvist

Supervisor :

Examiner : Petru Eles

(2)

Detta dokument hålls tillgängligt på Internet - eller dess framtida ersättare - under 25 år från publicer-ingsdatum under förutsättning att inga extraordinära omständigheter uppstår.

Tillgång till dokumentet innebär tillstånd för var och en att läsa, ladda ner, skriva ut enstaka ko-pior för enskilt bruk och att använda det oförändrat för ickekommersiell forskning och för undervis-ning. Överföring av upphovsrätten vid en senare tidpunkt kan inte upphäva detta tillstånd. All annan användning av dokumentet kräver upphovsmannens medgivande. För att garantera äktheten, säker-heten och tillgängligsäker-heten finns lösningar av teknisk och administrativ art.

Upphovsmannens ideella rätt innefattar rätt att bli nämnd som upphovsman i den omfattning som god sed kräver vid användning av dokumentet på ovan beskrivna sätt samt skydd mot att dokumentet ändras eller presenteras i sådan form eller i sådant sammanhang som är kränkande för upphovsman-nens litterära eller konstnärliga anseende eller egenart.

För ytterligare information om Linköping University Electronic Press se förlagets hemsida http://www.ep.liu.se/.

Copyright

The publishers will keep this document online on the Internet - or its possible replacement - for a period of 25 years starting from the date of publication barring exceptional circumstances.

The online availability of the document implies permanent permission for anyone to read, to down-load, or to print out single copies for his/hers own use and to use it unchanged for non-commercial research and educational purpose. Subsequent transfers of copyright cannot revoke this permission. All other uses of the document are conditional upon the consent of the copyright owner. The publisher has taken technical and administrative measures to assure authenticity, security and accessibility.

According to intellectual property law the author has the right to be mentioned when his/her work is accessed as described above and to be protected against infringement.

For additional information about the Linköping University Electronic Press and its procedures for publication and for assurance of document integrity, please refer to its www home page: http://www.ep.liu.se/.

(3)

Abstract

This thesis compares different approaches of creating a collaborative editing applica-tion using different methods such as OT, CRDT and Locking. After a comparison between these methods an implementation based on CRDT was done. The implementation of a collaborative graphical network was made such that consistency is guaranteed. The imple-mentation uses the 2P2P-Graph which was extended in order to support moving of nodes, and uses the client-server communication model. An evaluation of the implementation was made by creating a time-complexity and a space complexity analysis. The result of the thesis includes a comparison between different methods and by an evaluation of the Extended 2P2P-Graph.

(4)

I would like to thank my family for all the support throughout the years, without you this would not have been possible. Thank you Senion for the support with the thesis. Thank you Linköping University for giving me a great education.

(5)

Contents

Abstract iii

Acknowledgments iv

Contents v

List of Figures vii

List of Tables viii

1 Introduction 2 1.1 Motivation . . . 2 1.2 Aim . . . 3 1.3 Research questions . . . 3 1.4 Delimitations . . . 3 2 Theory 4 2.1 Consistency Models . . . 4

2.2 Conflict Free Replicated Data type . . . 6

2.3 Operational Transformation . . . 11

2.4 Transparent Adaptation . . . 13

2.5 Locking . . . 13

2.6 Synchronization Techniques . . . 14

2.7 Undo and Redo . . . 15

2.8 Implementation Technologies . . . 15

3 Method 17 3.1 Achieving Consistency in a Distributed Application . . . 17

3.2 Comparison of CRDT and OT . . . 18

3.3 Creating a Collaborative Graph Editing System . . . 18

3.4 Evaluation . . . 25

4 Results 30 4.1 Achieving consistency in a distributed application . . . 30

4.2 Comparison of CRDT and OT . . . 31

4.3 Creating a collaborative graph system . . . 31

5 Discussion 36 5.1 Results . . . 36

5.2 Method . . . 37

5.3 The work in a wider context . . . 38

6 Conclusion 39 6.1 Research questions . . . 39

(6)
(7)

List of Figures

2.1 Join-semilattice counter . . . 7

2.2 Join-semilattice set . . . 7

2.3 Naive set implementation . . . 8

2.4 2P-Set . . . 9

2.5 OR-Set . . . 10

2.6 Without OT . . . 12

2.7 OT using transform function . . . 12

3.1 Concurrent add edge and remove node . . . 19

3.2 Concurrent add edge and remove node diagram . . . 19

3.3 Concurrent move operation adding deltas . . . 20

3.4 Concurrent move operation using counter . . . 20

3.5 UML class diagram . . . 23

3.6 Server-client model . . . 25

3.7 Partition graph with version vectors . . . 26

4.1 User Interface . . . 33

4.2 Alice start . . . 34

4.3 Bob start . . . 34

4.4 Alice created an edge offline . . . 34

4.5 Bob removes a node . . . 34

4.6 Alice reconnects and receives Bob’s change . . . 34

4.7 Bob receives Alice’s change . . . 34

(8)

3.1 Time complexity of graph methods . . . 28 3.2 Space complexity of graph . . . 28 4.1 Comparison of Locking, OT and CRDT . . . 31

(9)

Glossary

CAP Theorem A theorem that says its impossible to achieve consistency, availability and partition-tolerance at the same time.

CmRDT Commutative Replicated Data Type. CRDT Conflict Free Replicated Data Type. CvRDT Convergent Replicated Data Type.

EC Eventual Consistency.

LUB Least Upper Bound.

OT Operational Transform.

Replica A single system running a program which is a part of a larger cluster where each replica is running the same program.

SEC Strong Eventual Consistency.

TA Transparent Adaptation applies OT in single user applications in order to support collabo-rative editing without modifying the applica-tion.

(10)

Collaborative editing of applications has been studied since the 1980s. [10] Popular products such as Google Docs, AWS Cloud9 and Dropbox Paper are available today. A collaborative editing application allows multiple users the ability to edit the same application at the same time from different locations, were the edits are merged into the same state for all users. This allows users to work more efficiently. If two users want to collaborate with each other, they should not have to send a copy of a document via email for instance. This is time consuming and error prone, since users might have to manually resolve any potential conflict. Techno-logical advancements have now made it possible for users to use the internet to effectively communicate and collaborate in a new way.

The algorithms that solve the problem of collaborative editing revolve around handling conflicting updates that can occur when users make updates concurrently. Two algorithms of this kind have been studied in this thesis, including Conflict Free Replicated Data type (CRDT) [29] [39] [22] and Operational Transform (OT) [21][37][10]. Both algorithms are used in the industry today. Other means of collaboration are also discussed, such as Locking [5] and Transparent Adaptation [11].

An implementation consisting of a collaborative graph editor based on CRDT has been implemented, based on the CRDT 2P2P-Graph which was extended to support the ability to move nodes. The implementation allows edits to be merged, using WebSockets and Version Vectors in order to handle synchronization between clients and server. The implementation allows users to work offline, and when they are connected to the server the updates will merge into the same state for all connected users.

Eventual consistency (EC) is a consistency model which is used in distributed computing, where connected replicas may diverge temporarily, but will eventually merge into the same state. Keeping a consistent state is important, otherwise two users may work on different states as their local replica has diverged.

1.1

Motivation

Distributed systems is an important field of computer science. As more and more devices are connected to the internet, communicating and coordinating systems is of greater interest. Distributed systems are used in network applications such as multiplayer online games and

(11)

1.2. Aim

network file systems. Distributed systems are also used in real-time process control such as aircraft control systems and industrial control systems. [8]

This thesis was done in collaboration with Senion, an Indoor Positioning System (IPS) company. The company uses a tool for installing their systems consisting of a graph (i.e. nodes and edges). The tool is not able to handle multiple users editing the graph at the same time without overwriting data, thus valuable work is lost. This thesis is motivated by the fact that multiple users should be able work together collaboratively without overwriting each others changes.

1.2

Aim

The aim of this thesis is to describe and evaluate different ways of creating a collaborative editing system. Different ways of solving this type of issue have been researched. In this thesis a comparison of two algorithms, namely CRDT and OT have been done. The compar-ison of the two algorithms resulted in an implementation of a graph editing system where multiple users can collaborate together using an algorithm based on CRDT.

1.3

Research questions

In order to achieve consistency in a collaborative application, three research questions have been answered in this thesis. The first and second research question is answered using theory from relevant research on this topic. The first research question asks what algorithms and methodologies exist that can be used to achieve consistency in a distributed application. The second question investigate the differences between two algorithms, which have been widely studied in the research community. The final research question answers how a collaborative application can be implemented. The three research questions are the following.

1. What are the alternatives for achieving consistency in a distributed application? 2. What are the differences between eventual consistency algorithms CRDT and OT? 3. How can a collaborative editing system of a graphical network be implemented such

that consistency is guaranteed?

1.4

Delimitations

This thesis was done in collaboration with Senion, a company developing Indoor Positioning Systems. Therefore the presented algorithms are described from the perspective of being applied in a collaborative graph system.

(12)

Replication of data has been a fundamental research topic in the distributed algorithms com-munity. Previous work has focused on maintaining a global state of order of operations. [18] Using a global state of order of operations negatively impacts the performance of an application, since internet users can have a high latency, slow bandwidth and unstable ac-cess. According to the CAP Theorem [13] [12] it is impossible to achieve the following three guarantees: consistency, availability and partition-tolerance in distributed web services.

• Consistency: A read is guaranteed to always return the most recent write.

• Availability: A non-failing node will return a response within a reasonable time limit. • Partition Tolerance: When a network partition occur the system will continue to

func-tion.

Only two of the three properties can be guaranteed in a distributed data store at the same time. No collaborative editing system can avoid network failures, due to users being con-nected to the internet. Availability and partition tolerance must be used. Availability is key for user experience in a collaborative application, in order for users to work offline. The col-laborative document system allows users to work offline. 1 When a user disconnects, the system must continue to function according to the partition tolerance criteria.

2.1

Consistency Models

A consistency model is an abstraction of rules tied to how memory in a system functions. If the programmer follows these rules, the system will function in the designated way. A number of different consistency models are presented in the following subsections. Eventual Consistency and Strong Eventual Consistency is of interest in a collaborative application.

Eventual Consistency

Eventual consistency (EC) is a consistency model which aims to solve consistency issues when replicating data. The model informally guarantees to return the same state of a storage

(13)

2.1. Consistency Models

system eventually, under the condition that no update is made to this storage under a time period. A Replica consists of the same data stored in a separate system. A mechanism must be used which handles any potential conflicts. Methods allow edits to execute immediately on the local replica and asynchronously send the edits to other replicas where eventually all replicas merge the edits without any conflicts, even if the edits are applied in different or-ders. [38] Allowing the user to edit the local replica immediately is important to achieve a good user experience. The most widely used system that implements EC is the domain name system (DNS). OT is an algorithm that uses the EC model.

Strong Consistency

Strong Consistency is also known as linearisability or serialisability. An informal description of the consistency model is that it always follows a sequential execution. In a distributed environment it assigns a node as a leader, which dictates the order of operations, which in turn prevents conflicts from occurring. The problem with strong consistency is that in order to modify data, the leading node (server) must approve the modification, which can take hundreds of milliseconds. [19]

Strong Eventual Consistency

Strong Eventual Consistency (SEC) is a subset of EC. It aims to improve upon EC, since EC can be error-prone and ad-hoc. SEC is a model that uses strict rules that must be followed, which in turn guarantees convergence. Section 2.2 will further elaborate on SEC. Gomes et al [14] created a network model in order to prove the correctness of SEC. The model reorders, drops and delays messages sent between computers. The network model was used to prove convergence for a number of different CRDT implementations, including the OR-Set and PN-Counter which will be discussed in section 2.2.

Causal Consistency

A causal consistency model captures operations that have causal relationships between them, where the operations are applied in a common causal order. The system therefor agrees in which order certain operations should be executed. If operation A causes another operation B, then the causal consistency model can guarantee that the system observes operation A before B, since these two operations are causally related. [2]

Explicit Consistency

A consistency model which handles application correctness has been introduced by Balegs et al [6]. The model describes a method for identifying operations that are unsafe to con-current updates, and which operations that are not. The unsafe operations can make use of invariant-repair techniques to handle a possible conflict. In each case local operations are applied immediately. The consistency model has the following three steps:

1. Detect all the operations such that when applied concurrently, can lead to invariant violation; these are called I-invariant sets.

2. Use an appropriate mechanism that solves the operations in the I-invariant set.

3. Apply the mechanism that solves the issues with the operations in the I-invariant set in the application code.

In the second step there exists two possible strategies which the developer can chose from. The first being invariant-repair, where operations are applied concurrently and the handling of the conflict resolution merges together changes which are in conflict in such a way that the

(14)

state convergence is maintained. The second option is violation avoidance, where possible operations that can cause concurrency issues are restricted. In the third step a possible mech-anism is suggested to make use of any CRDT, or the last-writer-wins strategy, both which lead to state convergence.

2.2

Conflict Free Replicated Data type

Approaches to establish EC are error prone and ad-hoc, as demonstrated by the issues with the Amazon Shopping Cart [9]. Items in the shopping cart were not removed when users tried to remove them, causing inconsistencies, when users were shopping using multiple devices. Because of these types of issues a new model called Strong Eventual Consistency (SEC) has been presented, which is a subset of EC. SEC is only valid for certain data types. CRDT has been presented to support SEC. [28] [29]

Mathematical properties of CRDT

The merge function of a CRDT uses the following mathematical properties to ensure consis-tency.

Commutative : a ˚ b=b ˚ a f o r a l l x , y PS .

A s s o c i a t i v e : (x ˚ y)˚z=x ˚(y ˚ z) f o r a l l x , y , z P S . Idempotent : x ˚ x=x f o r a l l x P S .

Listing 2.1: Mathematical properties

The commutative and associative properties ensure that operations can be delivered out of order.

An idempotent operation yields the same results regardless of the number of times it is applied. In computer science an idempotent function is a function which has the same effect regardless of how many calls are made. In a state-based CRDT it is possible to apply the same operation multiple times and converge to the same state.

The three properties (associative, commutative, and idempotent) in listing 2.1 form a join-semilattice, see figure 2.1 and figure 2.2. A join-semilattice is a partially ordered set which for every subset has a join, a least upper bound (LUB). For any two given elements there exists a single LUB. All elements are ordered according to a binary relation. In a CRDT the merge function uses the join-semilattice, meaning for any given set of elements, there exists one LUB, which will move the two elements towards the same state.

Two operations that can be used in listing 2.1 are the max operation, and the union opera-tion, since both max and union operation are commutative, associative and idempotent. For instance max(a, b) = max(b, a), max(max(x, y), z) = max(x, max(y, z)) and max(x, x) = x. This is demonstrated in the join-semilattice in figure 2.1. The union operation can also be applied, for instance tau Y tbu = tbu Y tau,((txu Y tyu)Y tzu) = (txu Y(tyu Y tzu)) and

(txu Y txu) =txu. This is demonstrated in the join-semilattice in figure 2.2 containing a set, were the merge function applies the union operation, elements tau and tbu form the LUB containing ta, bu.

State-based CRDT

In state-based CRDTs an update occurs on the local replica directly and the full state is prop-agated to the other replicas, where the receivers merge the state using a merge function. A state-based CRDT is also know as Convergent Replicated Data Type (CvRDT). The merge function must follow the following mathematical properties: commutative, associative, and idempotent. The merge function, therefore, forms a join-semilattice were the merge function provides a LUB according to the partial order in a join-semilattice. In order to optimize the state-based CRDT, it is possible to only send deltas, were only the recent change is sent to

(15)

2.2. Conflict Free Replicated Data type

Figure 2.1: Join-semilattice counter Figure 2.2: Join-semilattice set

other replicas instead of the full state. [3] The state-based approach has been used in file-systems such as NFC, Coda and AFS. Key-value stores Dynamo and Riak use a state-based approach.2[9] [29]

Operation-based CRDT

In an operation-based CRDT only the update operations are transmitted. The replicas re-ceive update operations and execute these at the local replica. Operation-based CRDT is also known as Commutative Replicated Data Type (CmRDT). The update operation is commuta-tive which means it can be executed out-of-order. But it is not idempotent, therefore every message must be unique. An update operation contains two phases, atSource describes what will execute at the local replica, the second phase marked downstream describes what will asynchronously execute at all other replicas. [29]

Counters

In order to introduce the basic concept and design issues that are present in CRDTs, some examples of how counters can be designed are presented.

Operation-based Counter

A simple counter that propagates increments and decrements to all replicas will eventually converge to the same state, following the commutative property of subtraction and addition. State-based G-Counter

A state-based counter that can handle both increments and decrements is not trivial. If two replicas start from the same state consisting of 0, then followed by a concurrent increment at both replicas, if the merge function uses the max function, the two states will converge to 1 instead of 2. If the merge function uses the addition of both states, it will not converge, as it is not idempotent.

A Grow Only counter (G-Counter) can only handle increments. By using the mechanics of a vector clock, each replica can have a dedicated space in a vector, where additions can accumulate. The G-counter can merge between replicas by taking the max value between each element in two vectors, i.e. pairwise max between two vectors. Assume that the number of replicas is known. The value of the counter is the sum of all the elements that exists in the vector. A state based G-Counter is described in listing 2.2 as described by Shapiro et al. [28] The join-semilattice in figure 2.1 demonstrates a state-based G-Counter.

(16)

Figure 2.3: Naive set implementation 1 payload i n t e g e r [ n ] P 2 i n i t i a l [ 0 , 0 , . . . , 0 ] 3 update increment ( ) 4 l e t g = myID ( ) 5 P [ g ] : = P [ g ] + 1 6 query value ( ) : i n t e g e r v 7 l e t v = ř i P[i] 8 compare ( X , Y ) : boolean b 9 l e t b = (@i P[0, n ´ 1]: X.P[i]ďY.P[i]) 10 merge ( X , Y ) : payload Z 11 l e t (@i P[0, n ´ 1]: Z.P[i] =max(X.P[i], Y.P[i])

Listing 2.2: State-based G-Counter

PN-Counter

In order for a counter to contain negative increments (ie decrements), the state-based G-Counter can be extended to also include a vector for all the decrements. Each replica will contain two vectors, one for increments and another for decrements, where each replica has a dedicated space for its own value in each vector. The merge function will take the max value for each element in the vectors, creating a LUB. The final value of the counter is by subtracting the increments with the decrements. [28]

Set

A naive implementation of a distributed set could function as described in figure 2.3, where two replicas add an element twice and remove the element in different order. The result of applying the operations in different orders is that the two replicas, the blue and the green end up in a different state in the end. Hence this set can not work in a distributed environment. In the following section a number of different CRDT based set data types are described. Since a graph uses a set for both the nodes and edges that constitute a graph, these are of inter-est. Each set contains a lookup function, which for any element returns whether or not the element is still active and can be used, in other words the element has not been removed. [28] G-Set

In a Grow Only Set (G-Set), the only operation that is allowed is the addition of an element. The CvRDT merge function between two replicas is the union of the two sets. The lookup

(17)

2.2. Conflict Free Replicated Data type

Figure 2.4: 2P-Set

function returns true for any element that is in the set. The join-semilattice in figure 2.2 consists of a G-Set. [28]

PN-Set

A PN-Set associates two counters for each element in the set, P stores the number of additions, N store the number of decrements. The merge is simple since all operations, add or remove simply update the counter at every replica. The lookup function for a specific element returns true if the number of additions are greater than the number of decrements. [28]

LWW-Set

Last Writer Wins Set (LWW-Set) is a set where the elements are tagged with a timestamp and a visibility flag. Updates that occur on the local replica add the element if it does not exist already, and its associated timestamp and a visibility flag (true for add, false for remove). The merge function in CvRDT uses the union operation of all the elements between two replicas. The lookup function returns true for a specified element if the operation with the highest timestamp is an add-operation. [28]

2P-Set (Two-Phase Set)

In a 2P-Set an element can be added and removed. Once something has been added, it cannot be added again. To avoid diverging states, a tombstone is used when an element is removed, which can only occur if the element has been added before the removal. If a remove element is sent by a downstream replica before the added element, the remove still has precedence. If an element is added multiple times, it has no effect nor does removing the same element twice. Listing 2.3 shows a state-based 2P-Set. Figure 2.4 displays a 2P-Set. [28]

1 payload s e t A, s e t R 2 i n i t i a l ,

3 query lookup ( element e ) : boolean b 4 l e t b = (e P A ^e R R)

5 update add ( element e ) 6 A : = A Y { e }

7 update remove ( element e ) 8 pre lookup ( e ) 9 R : = R Y { e } 10 compare ( S , T ) : boolean b 11 l e t b = ( S .A Ď T .A ^ S . R Ď T . R) 12 merge ( S , T ) : payload U 13 l e t U.A = S .A Y T .A 14 l e t U. R + S . R Y T . R Listing 2.3: 2P-Set

(18)

Figure 2.5: OR-Set

Observed-Remove Set

The Observed-Remove Set (OR-Set) allows the update and removal of an element. It handles the concurrent add and remove of an element differently than in a 2P-Set, by giving prece-dence to the add operation. Internally each element has a unique id which is hidden from the user interface. The payload for each element consists of (element, unique-id). When an element is added at a local replica, the local replica creates a unique-id for the element and the change is propagated downstream. An element with a specified id can be removed once when a client calls the remove function, which is propagated downstream. The lookup for each element returns true if no removal of that element containing the specific unique-id is present. When a element is added again after a removal, a new unique-id is produced and thus it gives the impression that the same element is added again. Figure 2.5 shows how two replicas add the same element twice and both replicas converge to the same state. [28]

This approach gives the user the impression that an element which has already been re-moved can be re-added again, while the set is consistent with the properties behind CRDT. 2P2P-Graph

A 2P2P-Graph uses two 2P-Sets, one for nodes and another one for edges. Hence an edge or a node can only be added and removed once. An operation-based 2P2P-Graph is shown in listing 2.4. VA and EA is used for adding nodes (vertices) and edges while VR and ER is used for removing nodes and edges. It can be noted that in order to create an edge, the nodes the edge is connected to must exist, therefore a lookup method is used. [28]

(19)

2.3. Operational Transformation

1 payload set VA, VR, EA, ER 2 i n i t i a l ,,,

3 query lookup ( v e r t e x v ) : boolean b 4 l e t b = (v P(VAzVR))

5 query lookup ( edge ( u , v ) ) : boolean b

6 l e t b = (lookup(u)^lookup(v)^(u, v)P(EAzER))

7 update addVertex ( v e r t e x w) 8 a t S o u r c e (w) 9 downstream (w) 10 VA :=VA Y w 11 update addEdge ( v e r t e x u , v e r t e x v ) 12 a t S o u r c e (u, v)

13 pre lookup(u)^lookup(v)

14 downstream (u, v) 15 EA :=EA Y(u, v) 16 update removeVertex ( v e r t e x w) 17 a t S o u r c e (w) 18 pre lookup(w) 19 pre @(u, v)P(EAzER): u ‰ w Y v ‰ w 20 downstream (w) 21 pre addVertex (w) d e l i v e r e d 22 VR :=VR Y w

23 update removeEdge ( edge ( u , v ) ) 24 a t S o u r c e (u, v) 25 pre lookup((u, v)) 26 downstream (u, v) 27 pre addVertex ( u , v ) d e l i v e r e d 28 ER :=ER Y t(u, v)u Listing 2.4: 2P2P-Graph Industry Use

Redis offers CRDT between Redis databases which are located in multiple data centers which are located in geographically different places. Other companies using CRDTs include Sound-cloud, Riak, Tomtom, Facebook and Atom.

2.3

Operational Transformation

OT offers the ability to collaborate on a wide range of different collaboration software. It was first introduced in 1989 in a system called GROVE (GRoup Outline Viewing Edit) by Ellis et al. [10]

It offers consistency maintenance and concurrency control. It was first used with regards to editing of text documents, but has since been further developed to suit collaborative office suite tools and media design tools. In 2009 it was adopted by Google Docs as a core tech-nology supporting its collaboration features. The basis for OT algorithms is causality and concurrency [10]. Causally related operations are transformed and executed in their causal order, and concurrent operations are transformed before execution.

System Overview

In OT each client has it own replica of the original document or data, where the client can operate immediately on their local replica, without any locking or delay. This allows the

(20)

Figure 2.6: Without OT Figure 2.7: OT using transform function

client to have a highly responsive user interface, since internet can sometimes have high latency. The operation is then propagated to the other client which merges the changes unto their own local replica. Each client transforms the update to ensure that the changes that are applied result in state convergence for all clients.

Basic Example

In figure 2.6, a basic example demonstrating an issue of concurrent editing of a text document is displayed, were two users are editing concurrently. Alice decides to delete the character at index 1, which results in operation O1. At the same instance Bob decides to insert the letter e at position 2, which results in operation O2. Both of their operations executes on their local replica, and the operations propagate to the other clients. When Alice receives the O2 operation, the index is not referring to the intended position, which results in inserting the letter e in the wrong position. Bob receives the delete operation at index 1, which removes the same letter as intended. Both clients are now in two different states, this is because no transform function has been used.

In figure 2.7 a transform function is used, which can handle the fact that Alice removed a letter previously, which causes the transform function to produce O12, which correctly inserts

the letter e in-between the intended characters.

Transform Functions

In OT operations that a client does apply to the local replica immediately, the updates are sent to other clients which have to transform the update to deal with potential conflict or inconsis-tencies. In OT systems there exist two Transform Functions (these can have different names in different implementations). The regular transformation which applies a Transformation unto another is called Inclusion Transformation. Another transformation which traverses the operation is called Exclusion Transformation. This gives the OT system the ability to undo operations and redo operations.

dOPT

The dOPT algorithm was one of the earliest OT algorithms that was introduced. [10] The al-gorithm handles updates that occurred in the past by first transforming them before applying the updates into the current state. An issue with this algorithm, known as the dOPT-puzzle, is that it can not deal with an operation being concurrent with two other operations. Thus,

(21)

2.4. Transparent Adaptation

this algorithm can not guarantee convergence. [33] Due to this known issue, other implemen-tations have been proposed, such as Jupiter and Context-based OT.

Jupiter

Jupiter solves the dOPT-puzzle by using a client-server model, thus having a centralized server. The algorithm, therefore, only has to deal with one operation being concurrent with another operation. All clients are connected to one central server, and once an operation has been executed on the server, all connected clients will receive the operation. [21]

Context-based (COT)

In order improve the quality and correctness of OT a new algorithm called COT was intro-duced [37]. It fixes known issues with the dOPT algorithm, which could handle transforma-tion between a pair of operatransforma-tions, as long has these operatransforma-tions are concurrent. Later it was discovered that another condition must be met which is that the transformation can only be done on two operations which are based on the same document state (DS). [33]

Another issue was introduced when OT algorithms supported undo commands, where the causality issues became a bigger issue. Some patches aiming to solve these issues where developed, but such solutions where inefficient and complicated OT algorithms. [26]

In order to understand the effect of an operation, it must be interpreted in its context. The context in which an operation O is executed in is denoted as C(O). The context represents the state of the document in which O was introduced in. Previous operations that have been executed are stored in C(O). The operations that have been introduced could be executed in different order at different sites/clients, but they must produce the same state according to the convergence requirement. [34]

OT in areas outside of text editing

OT can be used outside of editing text documents. It has been used in 3D Design tools, powerpoint collaboration tools, among others.

Sun et al uses OT in order to resolve conflicts in a 2D editing system, such as a spreadsheet document, thereby extending the capabilities of OT from one- to two-dimensional conflict resolution. [35]

2.4

Transparent Adaptation

Transparent Adaptation (TA) is a technique used in order to make existing single user appli-cations work in a collaborative environment. It makes use of existing API of the application, and builds the collaborative system on top of it. The reason it is called transparent is because it does not require any changes to the application it is applied to. This has been used in order make Microsoft Word, Microsoft Powerpoint and Autodesk Maya collaborative. [36]. It uses OT in order to bring the collaborative feature to the applications.

Hongfei et al [11] created a real-time collaborative programming environment called Co-Eclipse, based on the single-user IDE Eclipse. The programming environment used TA in order to introduce consistence maintenance.

2.5

Locking

Another way of dealing with concurrency issues is by using locking. In such a system users request access to modify data, and if no other users in the system is using the resource, only then the user can acquire the lock during a time period. In such a scenario, only one user at a time can edit the shared data. And once the user is finished editing the data, the lock is

(22)

released and other users can gain privilege to modify the data. The use of locking has been used in multiple collaborative editing systems. [5] [17].

Newman-Wolfe et al uses locking in a object-oriented graphical editing application where multiple users can edit the shared data. [20] Sun et al uses locking in a collaborative text editor, where locks are acquired in certain regions of a document, but if users are editing the same documents in different regions no conflict will occur. Therefore locks are only used to prohibit multiple users from editing the same region at the same time, which can cause conflicting updates. [32]

Greenberg et al [15] describes the use of different levels of optimism in a lock-based ap-proach. Non-optimistic locking forces users to wait until the request to edit data has been approved. If and only if the system gives the user the lock, editing of the shared data can occur. Optimistic locking makes a request to edit data, but it acquires a tentative approval of the lock, meaning the user can edit data before knowing for sure if it has received the lock. If access to the lock is denied, the user must return to the previous state, otherwise the user can keep modifying the data. A fully optimistic lock allows the user to edit data without having access to the lock. In this scenario a "pending release" is made, and the user can keep updating other resources. But if the lock is denied it has to revert back to a previous state, using undo. In a semi-optimistic lock users are allowed to edit data without the lock, but prohibited to move onto editing another object until the lock has been acquired. This method does not allow multiple users to collaborate simultaneously in real-time.

2.6

Synchronization Techniques

There exist different methods of solving the issue of having version conflicts. The use of time-stamp schemes is a possible solution to the problem. However the use of a global network time using physical clocks has been demonstrated to be non-trivial. [18] [30]

Version Vectors

A version vector is a mechanism for knowing whether or not two versions of a shared data-structure are in conflict with each other. A version vector contains an element for each replica in the vector of size n, where n is the number of replicas. Each replica starts with the number zero in their space in the vector. Whenever an update occurs at the replica, the vector must be incremented by one in the designated position.

The vector ă A : 1, B : 0, C : 2 ą says that replica A has made one update, and replica C two updates. Each replica contains its own vector, which is used in order to know the state of the replica. In order to know how many updates a replica is missing, two version vectors can be compared, and missing updates can now be sent to the replica, which will make the version vectors equivalent. If replica A contains the following version vector ă A : 1, B : 0, C : 2 ą and replica B contains ă A : 1, B : 3, C : 2 ą, then it can be determined that replica A is missing three updates made by replica B, this can be resolved by sending replica A the missing updates, now the version vectors are the same, i.e. ă A : 1, B : 3, C : 2 ą.

The pairwise maximum of two vectors is the resulting vector that should exists at the replicas after a merge, i.e. Va[x] =Vb[x] =max(Va[x], Vb[x]). [24]

Dotted Version Vectors

Since a version vector grows with the number of connected replicas, a more efficient solution has been by proposed called dotted version vector (DVV). In a dotted version vector the vector grows only by the number of servers that are used instead of the number of replicas.

(23)

2.7. Undo and Redo

Since the number of connected replicas is usually much larger than the number of servers, hence a DVV is more efficient than a Version Vector. [25]

2.7

Undo and Redo

The undo and redo of operations is a common feature in editing applications. The expected effects of undo in a collaborative environment has been studied in human computer interac-tion research. The results shows that neither a global undo or a personal undo of operainterac-tions is expected from users in a collaborative editing process, but rather the undo of regional oper-ation that the user is currently working on. The second most expected operoper-ation is a personal undo. [27]

Loogot-Undo

Loogot-Undo is a collaborative CRDT editing system that can handle undo and redo of oper-ations. It consists of a global undo and redo mechanism, meaning any user can undo or redo operations made by another user. It uses a visibility degree on each change, were an undo will decrement the degree, a redo will increment the visibility degree. The operation will only be visible if the visibility degree is 1 or higher. [39] Loogot uses the PN-Set described in subsection 2.2.

Automerge

Automerge is an open source library that offers an general CRDT data structure that can handle editing of text, sets and maps. The library handles Undo and Redo by applying the inverse operation to cancel the original operation. If data was added, the undo applies the inverse, i.e. the removal of data. [4]

2.8

Implementation Technologies

The following technologies were used in order to create the implementation.

React

React is a JavaScript library for creating user interfaces. It is maintained by Facebook and is available as an open source project. It is used in order to create single page applications on the web, but can also be used to create mobile apps.3

TypeScript

TypeScript offers the ability to use static type-checking in JavaScript. It transpiles into JavaScript, and any JavaScript code is valid Typescript code.4

Kotlin

Kotlin is a programming language built upon the Java virtual machine (JVM). The language can interoperate with Java code, while its syntax is different from it. It is a general-purpose programming language and uses type-inference. Kotlin is targeting the JVM mostly, but can be compiled to native-code or JavaScript.5

3https://reactjs.org/

4https://www.typescriptlang.org/ 5https://kotlinlang.org/

(24)

WebSocket

WebSocket is a communication protocol which uses a TCP connection, which offers a full-duplex connection. A full-full-duplex communication system allows the server to initiate com-munication with the client when necessary. In a HTTP connection the server cannot initiate communication with the client, unless some workaround such as long-polling is used. There-fore a WebSocket is ideal for a real-time application where the webserver at any time needs to communicate with connected clients, and when the clients needs to communicate with the server and, in turn, other clients.

(25)

3

Method

In section 3.1 a broad overview of how a distributed application can achieve consistency is described, what kind of mechanism can be used such a locking, OT and CRDT. Existing collaborative graph editing systems is described, along with how these systems handle con-current updates.

In section 3.2 a comparison is made between CRDT and OT in order to understand what differentiates the two methods.

Implementation details is presented in section 3.3. First the requirements that were set from the beginning are defined. How these requirements have been solved in the implemen-tation is described.

3.1

Achieving Consistency in a Distributed Application

A collaborative graph tool has been made by Zimmer et al [40]. In the tool the authors choose not to use a sophisticated concurrency control mechanism, instead handling potential conflicts using a simple locking mechanism. The users are able to create and edit nodes, as well as creating edges between nodes, and edit or remove these edges. The conflict handling is resolved by sending all user actions to a central server which handles any potential conflict and returns to the user an appropriate event. All actions performed by users are put into a queue on the central server which performs each action, and updates the local user, if the action was successfully performed.

Open Street Map (OSM) is a collaborative tool used in order to create geographical data. Map data is created by users who submit geographical information, such as street names, cafés, railway stations, roads and pathways. An application called Java OpenStreetMap Ed-itor (JOSM) exists, where users can submit data, where potential merge conflicts can occur [16]. Users download data from OSM, which can be edited locally and later be submitted to the OSM servers. If two users are editing the same data, the first user who submits their data will have their data merged to the servers, while the second user will be presented with a merge conflict, where the user can overwrite the conflict with their own data, or it can try to resolve the changes before finally being able to submit their changes successfully.

No collaborative graph editing system using eventual consistency could be found in the literature, except the 2P2P-Graph described in section 2.2.

(26)

3.2

Comparison of CRDT and OT

By gathering research made on the the two methods, an analysis could be made regarding their differences.

In order to reason about the use of certain methods in the implementation a comparison between CRDT and OT will be presented below.

A CRDT uses mathematical properties that ensures convergence. This is because every CRDT must base its implementation on the join-semilattice described in 2.2. The LUB pro-duced by a pair of elements in the join-semilattice ensures that the outcome of the merge will converge to the same state for both replicas. A CRDT is able to produce a replicated data type that will always converge to the same state according to the SEC model the algorithm is based upon.

In this thesis the 2P2P-Graph as seen in subsection 2.2 is of most interest. The implemen-tation of a 2P2P-Graph is simple, and will converge to the same state when merging states among replicas in a distributed environment. As described, it uses two sets for adding and removing nodes (VA, VR), and two sets for adding and removing Edges (EA, ER). Since an edge or node can only be added and removed once, the capabilities of using redo and undo operations are not trivial. The redo and undo of actions must be able to add and remove nodes and edges multiple times, as the user can redo and undo any operation as many times as they see fit. Due to these restrictions, the strategy for handling the undo and redo oper-ations is cumbersome. One solution is to keep a visibility degree as described in subsection 2.7. Another solution is to apply the inverse of the operation that should cancel out what was done previously, as used by open-source library Automerge described in subsection 2.7.

An OT algorithm, deals with potential conflicts by transforming operations that are sent by other clients onto a local state. The research that has been found explains OT on a theo-retical level, where it is up the developer to define how transformation functions and control algorithms should be designed in order to fit the application needs. Therefore, it requires the application developer to specify the transformation function and implement a control algorithm in order to produce a functional implementation of an OT algorithm. Some OT algorithms such as the COT algorithm described in 2.3 support redo and undo of operations. No resources of previously implemented graph systems based on OT were found and, thus, it is not clear how OT can be used in a graph system. OT was invented with the intention of being used in text editing applications. OT has only been proven to be correct when used in a client-server model. [21]

3.3

Creating a Collaborative Graph Editing System

The requirements for creating the Graph Editing System are the following: 1. It should have a history of changes made by any user.

2. It should be possible to comment or annotate changes. The users should be able to explain why they made a change.

3. It should be possible for a user to temporarily go offline and upon reconnecting the changes should be synchronized.

4. It should display a unique color for the nodes and edges created by a specific user. 5. It should be possible to mark a graph as done, and a version number should be given. 6. It should be possible to undo, redo changes (time travel).

(27)

3.3. Creating a Collaborative Graph Editing System

Figure 3.1: Concurrent add edge and remove node

Figure 3.2: Concurrent add edge and remove node diagram

How the implementation was made such that the requirements could be satisfied is de-scribed in this chapter. First, related research on collaborative graph editing systems will be presented.

Concurrency Issues In a Graph

The concurrency issues that can occur in the graph implemented in this thesis are the follow-ing.

1. A user is removing a node while another user is creating an edge from that node. 2. Multiple users are concurrently moving a node from one position to another.

There a three potential ways of handling the first issue which was described by Shapiro et al. [29]

• The first is by removing both the node and edge once both operations have reached each replica. The lookup function that checks if an edge is active, also checks if any of the connected nodes have been removed; if so, the edge is not active as described in the 2P2P-Graph in 2.2. This solution is trivial and is described in figure 3.2 using a sequence diagram, and in figure 3.1.

• The second possibility is to re-add the node that was removed. This is non-trivial in a 2P2P-Graph were a remove operation can occur once, then if it is added again, the

(28)

Figure 3.3: Concurrent move operation adding deltas

Figure 3.4: Concurrent move operation using counter

edges that are connected to the old node must be assigned with the new id of the new node. Although in this implementation, it is possible to insert a previous node with a new id, using the properties of the OR-Set.

• The third option is to re-add the node and then remove both the node and edge. The first solution is trivial. The other two options require more operations to be inserted into the CRDT. CRDTs can grow quickly, therefore it is undesirable to add more operations than necessary. CRDTs are known for having unbounded growth. This will be discussed in chapter 5. It should be stated that the user will always have access to a history log where all actions are recorded. Even if an unwanted operation occurs, the users have the ability to fix any issues. In the history log it can be made explicitly clear that the operation conducted by another user may have affected the operations made by the local user.

Another concurrency issue occurs when two users move a node simultaneously. This was not considered in the 2P2P-Graph described in subsection 2.2. This issue can be solved in the following two ways.

• Give precedence to one of the replica’s move operation. This can be implemented by giving each replica a universally unique ID. A node should contain the id of the last replica that made an update, and a counter. The counter starts at 1, and increments by one when a move operation is applied to it. A concurrent move operation occurs when two users change a node with the same counter value. This is resolved by giving precedence to the replica with the highest ID.

• Another possibility is to add the delta x and y coordinates from both replicas. Even if these are applied in different order, they will converge to the same coordinate in the end, following the commutative properties of addition.

(29)

3.3. Creating a Collaborative Graph Editing System

The first method gives one of the user the desired outcome, while the other user’s change will be disregarded, this is demonstrated in figure 3.4. The second possibility is a combination of both of the deltas, which is not the intention of either user. Even if a unwanted concurrent move operation occurred, the users can always move the node to the intended position. Both methods ensures that the replicas converge to the same state. Both methods were tested in the implementation, and the first method is described in the Extended 2P2P-Graph in 3.1.

Implementation Details

In this section a detailed description of how the system was realized in order to achieve all of the requirements that are documented in section 3.3, is given.

The 2P2P-Graph in listing 2.4 was considered the most appropriate method, as it is based on the CRDT data type, and it was specifically designed for graphs. It is also clear why such an algorithm converges to the same state eventually according to the LUB and the merge function of a join semi-lattice. In such a system all changes can simply be propagated to all users and the consistency can be maintained. A difference between 2P2P-Graph and OT is that objects can never be removed in a 2P2P-Graph, they can only be disabled. A node which has been removed, can not be added again. Therefore, the only way to undo an action using 2P2P-Graph is to bring back a new node which has similar properties as the previous one, except it must have a unique ID which is different from the old one. Inspiration from the OR-Set was used in order to re-add objects when using undo and redo. Since a 2P2P-Graph is not dependent on which order any changes are made, once an node is added, then removed, the undo operation will re-add the node, but with a new ID with the same properties as the initial node. The same logic is applied to edges.

An Extended 2P2P-Graph as described in listing 3.1 was implemented. This version also deals with the ability for nodes being moved, i.e. change their x,y and coordinates. The ability for nodes to be moved could be applied before the node has been added. When a move operation has been received and it has not been added, the move operation could add the node and set the counter to the one sent by the move operation. Any previous operations with a lower counter will have no effect. All operations in 3.1 are commutative and associative.

(30)

1 payload set VA, VR, EA, ER, replicaID 2 i n i t i a l ,,,

3 query lookup ( v e r t e x v ) : boolean b 4 l e t b = (v P(VAzVR))

5 query lookup ( edge ( u , v ) ) : boolean b

6 l e t b = (lookup(u)^lookup(v)^(u, v)P(EAzER))

7 query movePrecedence ( v e r t e x wold, v e r t e x wnew) : boolean

8 l e t b = DwoldYVA ^ wnew.counter ą wold.counter _ wnew.counter = wold.counter ^

wnew.lastReplicaID ą wold.lastReplicaID

9 update moveVertex ( v e r t e x w, number x , number y ) 10 a t S o u r c e (w) 11 pre lookup(w) 12 w.x=x 13 w.y=y 14 w.counter+ + 15 w.lastReplicaID=replicaID 16 downstream (wnew, x, y)

17 pre movePrecedence(wold, wnew)

18 wold.x=wnew.x

19 wold.y=wnew.y

20 wold.counter=wnew.counter

21 wold.lastReplicaID=wnew.lastReplicaID

22 update addVertex ( v e r t e x w) 23 a t S o u r c e (w) 24 downstream (w) 25 VA :=VA Y w 26 update addEdge ( v e r t e x u , v e r t e x v ) 27 a t S o u r c e (u, v)

28 pre lookup(u)^lookup(v) 29 downstream (u, v) 30 EA :=EA Y(u, v) 31 update removeVertex ( v e r t e x w) 32 a t S o u r c e (w) 33 pre lookup(w) 34 pre @(u, v)P(EAzER): u ‰ w Y v ‰ w 35 downstream (w)

36 pre addVertex(w)delivered

37 VR :=VR Y w

38 update removeEdge ( edge ( u , v ) ) 39 a t S o u r c e (u, v)

40 pre lookup((u, v)) 41 downstream (u, v)

42 pre addVertex(u, v)delivered 43 ER :=ER Y t(u, v)u

Listing 3.1: Extended 2P2P-Graph

The following section will describe the structure of the code on the client side. Some of the structure is plain JavaScript classes which contains details regarding the CRDT implementa-tion. It should be noted that the main logic behind the CRDT implementation is located on the client.

(31)

3.3. Creating a Collaborative Graph Editing System

Figure 3.5: UML class diagram

Change Class

The change class in figure 3.5 represents every single change that the user can apply to the graph. The user can add, remove and move nodes. The user can also add and remove edges. An enum called Action described what type of action that was applied by the user. An enum called ObjectType describes what kind of object the change is targeting. An enum called ChangeType describes whether or not the change originated from a regular change or by pressing the undo or redo button in the user interface. Each change is put into a list, which displays all changes in a history log in the graphical interface. It is necessary to apply some operations in preceding order, for instance a node must exist before a move operation can be applied to the node.

If a change in the graph causes a conflicting update, the InCon f lict boolean will be set to true in the the change class. This is done because a warning to the user should be visualized, in order to notify the user that some changes might have been overwritten. The concurrency issue that can occur has been presented in subsection 3.3. However it was not deemed neces-sary to notify the user when a concurrent move operation has occurred.

(32)

Graph Class

The graph class in figure 3.5 is based on the 2P2P-Graph presented in subsection 2.2. It con-tains two maps associated to nodes, namely nodesAdd and nodesRemove. It should be noted that the naming convention here is different from the original 2P2P-Graph, which refers to nodes as vertices. In order to know if a node is still active, the lookup function looks up if the given node exists in the nodesRemove map; if it does, the node is no longer active. Two maps are used for representing the edges that are present in the graph, i.e. edgesAdd and edgesRemove. The lookup function which checks if an edge is still active looks for an edge containing a given id inside of edgesRemove; if it does not exist, the function also checks if both nodes connected to the edge are still active, only then the edge can be considered active. The 2P2P-Graph in 2.2 uses the data type set instead of maps. Maps store key-value pairs, were it is possible to efficiently lookup if an element with specified key exists. The key in the map is the uuid of the object, i.e. the node or edge.

History Class

The history class in figure 3.5 contains all the changes the local user and other connected users have made to the graph and puts them into the array called changes. The changes made by the local user can also be used to execute a redo and an undo action. Once a regular change is added to the changes array, the inverse of said change is put into the undoStack. Once an undo operation is called upon from the user interface, the last change in the undoStack is added to the changes array and removed from the undoStack. Once an undo operation is executed the inverse of that operation is added to the redoStack which works in the same way. Undo and Redo

The undo and redo of operations is not trivial in a CRDT. The use of undo and redo is limited by the fact that an object can only be added and removed once. This means that any object that must be added a second time after it has been removed, must be added with a new id but with the same properties as the original object. Therefore, the objects that exist in the undoStack and redoStack must be updated continuously as changes are made. Consider the addition of a node, now the undoStack has added the inverse of this operation, i.e. the removal of said node. If the user removes this node with a regular action, i.e. precisely the same operation that was stored in the undoStack. Now the undoStack must also be updated with another item that can add the removed node, but now with a new id, and the last item in the undoStack must be updated to refer to the first element in the undoStack. If the user now decides to undo the last two actions, the redoStack must now follow a similar process of continually updating the ids of the inverse operations.

The undo and redo of operations are only with regard to the updates that are made by the local user, not for any other connected users. Using a personal undo was seen as the second most expected result by using undo in a collaborative environment. [27]

Client-Server Model

The implemented solution uses the client-server model, where the server stores all the oper-ations that are applied by the clients as described by figure 3.6. The communication between the client and the server is done using WebSockets. The client code is written using Re-act together with TypeScript, in order to gain the benefits of static type-checking. The server uses Kotlin, and handles incoming changes, as well as synchronizing changes with connected clients. The server makes sure that all operations are sent to each client, by using version vec-tors as described in section 3.3. The server has the same implementation with regard to the Extended 2P2P-Graph on the server side, in order to retrieve the state of the graph. The

(33)

3.4. Evaluation

Figure 3.6: Server-client model

change objects that are created by the client using the class described in section 3.5 are added to a changes array on the server.

Synchronization Using Version Vectors

Considering that each replica can go offline at any given time, there must exist a mechanism that can handle that a replica might miss updates during a time period. In order to track which updates a replica has missed, a version vector is used, containing an element for each replica and a number associated to it. When a local update occurs at user A, it increments its element for user A. When that change is propagated to user B, it applies that change and increments its own element for user A in the vector. Now both users are in the same state. If User B goes offline for a specific time period, and later reconnects, it can send its version vector to the server, which then knows which change User B has missed and sends them over.

The synchronization mechanism using version vectors functions as follows. • A counter representing each replica is set to zero and put into a vector.

• When a local replica makes an update, this replica increments the specified element in the version vector on the local replica.

• When a synchronization between two replicas occurs, the two replicas send their ver-sion of the verver-sion vector. By comparing the vectors it can be determined what changes needs to be passed over in order for both replicas to be in the same state. Thus they will have identical version vectors.

In figure 3.7 a partition graph exemplifying the use of version vectors in the implemen-tation is demonstrated. Three clients A, B and C are connected. All three have a dedicated space in the vector which counts the number of operations that a client has made. Starting from the top, A makes three operations, B makes one operation and C makes two operations. Now consider client A and B is connected to the server. Therefore, the updates between these two clients can be sent to the server. Now client A and B are in equivalent state. Once C reconnects with the server, it can send its own two updates to the server, and receive three updates from client A and one from client B. At this point all three clients are in sync and in a consistent state. Because the CRDT is using the SEC model, the order in which the operations arrived in does not matter.

3.4

Evaluation

(34)

Figure 3.7: Partition graph with version vectors

State-based versus Operation-based CRDT

The implemented algorithm was based on the 2P2P-Graph presented in subsection 2.2, which is based on sending operations between clients and the server, where each change to the graph is described as an operation. It is more complex to maintain the consistency in an operation-based CRDT. Because users can go offline a version vector or similar mechanism must be used to keep track of the state of each replica. The version vector is then used in order to update a replica which has gone offline under a time period during which other replicas have sent new operations.

In a state-based CRDT, the whole state is sent between clients and server, where a merge function uses the join-semilattice in figure 2.2 to produce a LUB, which brings the replicas to a consistent state. The upside of such an implementation is that one does not need to keep track of which updates the replica has received using a version vector.

Undo and Redo Using Inverse Operations

The undo and redo by adding the inverse of the operation is at first glance a trivial solution. When a connected node of an edge is removed, then introduced again with a new id, the undo stack or redo stack containing an edge connected to the outdated node must be updated to the new node id. This becomes cumbersome to keep track of.

Time complexity analysis

In order the understand the time complexity of the Extended 2P2P-Graph an analysis was made. The analysis can be seen as a measurement of how the solution grows as the number of operations increases. For each method of the Extended 2P2P-Graph as seen in listing 3.2 an analysis has been made. The data structure in the implementation was chosen to be maps instead of sets in order to lookup IDs of nodes and edges more efficiently than in a set in JavaScript.

(35)

3.4. Evaluation

1 addNode ( node : Node ) {

2 t h i s . nodesAdd . s e t ( node . uuid , node ) ;

3 }

4

5 removeNode ( node : Node ) {

6 t h i s . nodesRemove . s e t ( node . uuid , node ) ;

7 }

8

9 getNodes ( ) : Array <Node> {

10 l e t livingNodes : Array <Node> = [ ] ;

11 t h i s . nodesAdd . forEach ( ( node : Node , key : s t r i n g ) => { 12 i f ( ! t h i s . nodesRemove . has ( key ) )

13 livingNodes . push ( node ) ; 14 } ) ;

15 r e t u r n livingNodes

16 }

17

18 moveNode ( updatedNode : Node , l a s t U s e r I D : s t r i n g , changeType : ChangeType ) { 19 l e t node = t h i s . nodesAdd . g e t ( updatedNode . uuid ) ;

20 i f ( node !== undefined ) {

21 i f ( changeType !== ChangeType . Regular ) {

22 node . moveNode ( updatedNode . x , updatedNode . y , l a s t U s e r I D , 23 updatedNode . c o u n t e r ) ;

24 }

25 e l s e i f ( updatedNode . c o u n t e r > node . c o u n t e r ||

26 updatedNode . c o u n t e r === node . c o u n t e r && l a s t U s e r I D > node . l a s t U s e r I D ) { 27 node . moveNode ( updatedNode . x , updatedNode . y ,

28 l a s t U s e r I D , updatedNode . c o u n t e r ) ;

29 }

30 }

31 }

32

33 connectedNodesRemoved ( edge : Edge ) {

34 l e t startNodeRemoved = t h i s . nodesRemove . has ( edge . startNode ) ; 35 l e t endNodeRemoved = t h i s . nodesRemove . has ( edge . endNode ) ; 36

37 r e t u r n startNodeRemoved || endNodeRemoved ;

38 }

39

40 addEdge ( edge : Edge ) {

41 t h i s . edgesAdd . s e t ( edge . uuid , edge ) ;

42 }

43

44 removeEdge ( edge : Edge ) {

45 t h i s . edgesRemove . s e t ( edge . uuid , edge ) ;

46 }

47

48 getEdges ( ) : Array <Edge> {

49 l e t l i v i n g E d g e s : Array <Edge> = [ ] ;

50 t h i s . edgesAdd . forEach ( ( edge : Edge , key : s t r i n g ) => { 51 i f ( ! t h i s . edgesRemove . has ( key ) &&

52 ! t h i s . connectedNodesRemoved ( edge ) ) 53 l i v i n g E d g e s . push ( edge ) ; 54 } ) ; 55 r e t u r n l i v i n g E d g e s ; 56 } 27

(36)

Method Time complexity

Add node O(1)

Remove node O(1)

Move node O(1)

Add edge O(1)

Remove edge O(1)

Graph retrieval O(n)

Table 3.1: Time complexity of graph methods

Data type Space complexity

Graph O(n)

Table 3.2: Space complexity of graph

The time complexity for each graph method is presented in table 3.1, were each method except one has time complexity O(1). The run time complexity of the implemented solution for retrieving the state of the graph is O(n), were n is the number of operations that has been applied. Retrieving the state of the graph consists of running the methods named getNodes()

and getEdges() as seen in listing 3.3. A space complexity analysis of the graph has been presented in figure 3.2, were n is the number of operations that have been added. The space required grows linearly with respect to the input size. Garbage collection could be used in order to lower the space complexity, as described in the discussion chapter.

Benchmark analysis

An analysis was done in order to understand the performance of the implemented solution. Specifically the analysis was done with regard to retrieving the state of the graph, i.e. retriev-ing the nodes that are in set VA but not in VR, and for the edges that are in EA but not in VR. The code running the benchmark is shown in listing 3.3. The methods that are invoked can be seen in listing 3.2. In order to make such analysis, a script that inserted nodes at random positions was used, and edges between these nodes were created. All operations were sent to the server where these were stored. The script for inserting these operations is shown in listing 3.4.

1 getGraph ( ) {

2 l e t nodes = t h i s . getNodes ( ) ; 3 l e t edges = t h i s . getEdges ( ) ;

4 }

Listing 3.3: Graph Retrieval

The test was performed by adding a certain number of operations, and using the time tool in JavaScript, which can track how long it takes to run JavaScript code. The number of operations that were added in the benchmark was 10000, 5000 were adding nodes, the other 5000 consisted of adding edges. When each operation was added, the time it took to retreive the graph after the insert was done was collected. The benchmarks ran on a Macbook Pro

(37)

3.4. Evaluation

late 2012, with 2,5 GHz Intel core i5 processor, 8 GB 1600 MHz DDR3 memory and Intel HD Graphics 4000 1536 MB. The tests were run on Chrome 71 on MacOS (Mojave).

1 generateRandomNodes ( ) {

2 l e t prevNode : Node | undefined ; 3 f o r ( l e t i = 0 ; i < 1 0 0 0 ; i ++) {

4 l e t rndX = Math . f l o o r ( Math . random ( ) * 8 0 0 ) ; //800 = width of screen 5 l e t rndY = Math . f l o o r ( Math . random ( ) * 7 0 0 ) ; //700 = height of screen 6 l e t node = t h i s . addNode ( rndX , rndY ) ;

7 i f ( prevNode !== undefined ) {

8 t h i s . addEdge ( prevNode . uuid , node . uuid ) ;

9 }

10 prevNode = node

11 }

12 }

References

Related documents

Other sentiment classifications of Twitter data [15–17] also show higher accuracies using multinomial naïve Bayes classifiers with similar feature extraction, further indicating

Mobile device management is a protocol tool intended to distribute applications such as Data /configuration settings, Firmware updates, Optimize the functionality

And finally a test will be performed on ten different people to compare users memory retention of taught features and get users insights of two different teaching methods, through

46 Konkreta exempel skulle kunna vara främjandeinsatser för affärsänglar/affärsängelnätverk, skapa arenor där aktörer från utbuds- och efterfrågesidan kan mötas eller

Uppgifter för detta centrum bör vara att (i) sprida kunskap om hur utvinning av metaller och mineral påverkar hållbarhetsmål, (ii) att engagera sig i internationella initiativ som

In the latter case, these are firms that exhibit relatively low productivity before the acquisition, but where restructuring and organizational changes are assumed to lead

The other 47,5 percent of respondents who thought that Facebook's popularity has begun to diminish, do think the future has other services coming up that will smash the mighty

The EU exports of waste abroad have negative environmental and public health consequences in the countries of destination, while resources for the circular economy.. domestically