SlideShare a Scribd company logo
1 of 181
Download to read offline
Just another to-do app.
Or is it?
Real-time collaboration in distributed systems
for JavaScript developers. 
Dawid Urbański
Technical Leader at CKSource
🎉
I forgot to
mention
The task
Create a todo list application with
synchronization capabilities
The task
In other words: enable real-time
collaboration capabilities for the todo list
The task
Conflicts should be resolved

in a reasonable way
The task
You cannot use any existing libraries to do this.
You are the library creator
The task
For sake of simplicity place two lists on the
same page, simulating both of them being
in offline mode, and make synchronization
to happen on a button click
Node A Node B
Synchronize
Item 1
Node A Node B
Synchronize
Item 1
Node A Node B
Item 1 Item 1
Node A Node B
Synchronize
Item 1
Node A Node B
Synchronize
Item 1
Hey! Here are my items:
[{“label”:”Item 1”,“done”:false}]
Hey! Here are my items:
[]
Node A Node B
Synchronize
Item 1
Hey! Here are my items:
[{“label”:”Item 1”,“done”:false}]
Hey! Here are my items:
[]
Run some merging logic Run some merging logic
Node A Node B
Synchronize
Item 1
Node A Node B
Item 1 Item 1
Hey! Here are my items:
[{“label”:”Item 1”,“done”:false}]
Hey! Here are my items:
[]
Run some merging logic Run some merging logic
Node A Node B
Synchronize
Item 1
Node A Node B
Item 1 Item 1
Hey! Here are my items:
[{“label”:”Item 1”,“done”:false}]
Hey! Here are my items:
[]
Run some merging logic Run some merging logic
Send the

whole state
Node A Node B
Synchronize
Item 1 Item 1
Problem
Node A Node B
Synchronize
Item 1 Item 1
Node A Node B
Item 1
Item 2
Problem
Node A Node B
Synchronize
Item 1 Item 1
Node A Node B
Item 1
Item 2
Problem
Node A Node B
Synchronize
Item 1 Item 1
Node A Node B
Item 1
Item 2
Node A Node B
Item 1
Item 2
Item 1
Item 2
Problem
Node A Node B
Synchronize
Item 1
Node A Node B
Synchronize
Item 1
Hey! Here are my changes:
[{“type”: “add”,“label”:”Item 1”,“done”:false}]
Hey! Here are my changes:
[]
Node A Node B
Synchronize
Item 1
Hey! Here are my changes:
[{“type”: “add”,“label”:”Item 1”,“done”:false}]
Hey! Here are my changes:
[]
Apply received changes Apply received changes
Node A Node B
Synchronize
Item 1
Node A Node B
Item 1 Item 1
Hey! Here are my changes:
[{“type”: “add”,“label”:”Item 1”,“done”:false}]
Hey! Here are my changes:
[]
Apply received changes Apply received changes
Node A Node B
Synchronize
Item 1
Node A Node B
Item 1 Item 1
Hey! Here are my changes:
[{“type”: “add”,“label”:”Item 1”,“done”:false}]
Hey! Here are my changes:
[]
Apply received changes Apply received changes
Send all

local changes
Node A Node B
Synchronize
Item 1 Item 1
Node A Node B
Synchronize
Item 1 Item 1
Node A Node B
Item 1
Item 2
Node A Node B
Synchronize
Item 1 Item 1
Node A Node B
Item 1
Item 2
Node A Node B
Synchronize
Item 1 Item 1
Node A Node B
Item 1
Item 2
Node A Node B
Item 2 Item 2
Order of events
Node A Node B
Synchronize
Node A Node B
Synchronize
Node A Node B
Item 1 Item 2
Node A Node B
Synchronize
Node A Node B
Item 1 Item 2
Node A Node B
Synchronize
Node A Node B
Node A Node B
Item 1 Item 2
Item 1 Item 2
Item 2 Item 1
Happened-before relation
Happened-before relation
Node A Node B
A
Time Time
Happened-before relation
Node A Node B
A
A`
Time Time
Happened-before relation
Node A Node B
A
A`
A happened before A`
Time Time
Happened-before relation
Node A Node B
A
A`
A happened before A`
Time Time
B
A` happened before B
Happened-before relation
Node A Node B
A
A`
A happened before A`
Time Time
B
A` happened before B
A happened before B
Happened-before relation
Node A Node B
A
A`
Time Time
B
B`
Happened-before relation
Node A Node B
A
A`
Time Time
B
B`
A < A` < B < B`
Total order
Happened-before relation
Node A Node B
A
A`
Time Time
B
B`
Happened-before relation
Node A Node B
A
A`
Time Time
B
B`
A < A`
Partial order
B < B` A < B` B < A`
Happened-before relation
Node A Node B
A
A`
Time Time
B
B`
A < A`
Partial order
B < B`
Incomparable (concurrent changes)
A || B A` || B`
A < B` B < A`
Happened-before relation
Node A Node B
A
A`
Time Time
B
B`
A < A`
Partial order
B < B`
Incomparable (concurrent changes)
A || B A` || B`
A < B` B < A`
Happened-before relation
Node A Node B
A1
Time Time
B1
A2
A3
B2
B3
Synchronize
Happened-before relation
Node A Node B
A1
Time Time
B1
B1`
A2
A3
B2
B3
Synchronize
A1`
A2`
A3`
B2`
B3` Incomparable (concurrent changes)
Solutions
Solutions
OT
(Operational transformation)
Solutions
OT
(Operational transformation)
CRDT
(Con
fl
ict-free replicated data type)
Solutions
OT
(Operational transformation)
CRDT
(Con
fl
ict-free replicated data type)
My solution
(Based somehow on CRDT)
OT
Item 1
Item 2
0
1
Item 3 2
OT
Node A Node B
Synchronize
Item 1
Item 1 0 0
OT
Node A Node B
Synchronize
Item 1
Item 1
Item 1
Item 2
0 0
0
1
0
OT
Node A Node B
Synchronize
OP|A1 = [add,”Item 2”,1]
Item 1
Item 1
Item 1
Item 2
OP|B1 = [remove,0]
0 0
0
1
0
OT
Node A Node B
Synchronize
OP|A1 = [add,”Item 2”,1]
OP|A1` = [add,”Item 2”,0]
Item 1
Item 1
Item 1
Item 2
OP|B1 = [remove,0]
OP|B1` = [remove,0]
0 0
0
1
0
OT
Node A Node B
Synchronize
OP|A1 = [add,”Item 2”,1]
OP|A1` = [add,”Item 2”,0]
Item 1
Item 1
Item 1
Item 2
OP|B1 = [remove,0]
OP|B1` = [remove,0]
Item 2 Item 2
0 0
0
1
0 0
0
OT
OP|A1 = [add,”Item 2”,1]
OP|A1` = [add,”Item 2”,0]
OT
Item 1
Item 2
Item 3
Item 4
Item 5
❌
❌
❌
0
1
2
3
4
OT
Item 1
Item 2
Item 3
Item 4
Item 5
❌
❌
❌
0
1
2
3
4
Item 1
Item 4
0
1
2
3
4
OT
Item 1
Item 2
Item 3
Item 4
Item 5
❌
❌
❌
0
1
2
3
4
OP|A1 = [add,”New item 4”,3]
Item 1
Item 4
0
1
2
3
4
OT
Item 1
Item 2
Item 3
Item 4
Item 5
❌
❌
❌
0
1
2
3
4
OP|A1 = [add,”New item 4”,3]
Item 1
Item 4
0
1
2
3
4
OT
Item 1
Item 2
Item 3
Item 4
Item 5
❌
❌
❌
0
1
2
3
4
OP|A1 = [add,”New item 4”,3]
Item 1
Item 4
0
1
2
3
4
OP|A1` = [add,”New item 4”,1]
OT
Item 1
Item 2
Item 3
Item 4
Item 5
❌
❌
❌
0
1
2
3
4
OP|A1 = [add,”New item 4”,3]
Item 1
Item 4
0
1
2
3
4
OP|A1` = [add,”New item 4”,1]
Removals:

[1,2,4]
OT
Item 1
Item 2
Item 3
Item 4
Item 5
❌
❌
❌
0
1
2
3
4
OP|A1 = [add,”New item 4”,3]
Item 1
Item 4
0
1
2
3
4
OP|A1` = [add,”New item 4”,1]
Removals:

[1,2,4] Count of removals for index less than 3 = 2 ( [1,2] )
( 3 - 2 = 1 )
OT - cons and pros
“Operations can be applied in any order
so we don’t have to care about timing”
OT - cons and pros
“OT approach of defining operations
through their offsets … raise serious
issues… resulting combinations of
states and operations are extremely
hard to foresee and understand”
OT - cons and pros
"Unfortunately, implementing OT sucks.
There's a million algorithms with
different tradeoffs, mostly trapped in
academic papers.”
OT - cons and pros
dOPT
Ellis & Gibbs 1989
adOPTed
Ressel et al. 1996
IMDR
Imine et al. 2003
Jupiter
Nichols et al. 1995
SOCT2
Suleiman et al. 1997
SDT
Li & Li 2004
SOCT3/4
Vidot et al. 2000
TTF
Oster et al. 2006 Credit: Martin Kleppmann

https://www.youtube.com/watch?v=B5NULPSiOGw&t=915s
OT - cons and pros
dOPT
Ellis & Gibbs 1989
adOPTed
Ressel et al. 1996
IMDR
Imine et al. 2003
Jupiter
Nichols et al. 1995
SOCT2
Suleiman et al. 1997
SDT
Li & Li 2004
SOCT3/4
Vidot et al. 2000
TTF
Oster et al. 2006
Require

central

server
Credit: Martin Kleppmann

https://www.youtube.com/watch?v=B5NULPSiOGw&t=915s
CRDT
Item 1
Item 2
Unique ID
Unique ID
Item 3 Unique ID
Di
ff
erent algorithms generate IDs in di
ff
erent ways:
Binary tree path, integer + replica ID pair, vectors, logical clock timestamp etc…
0
1000
Item 1 500
0
1000
Item 1
Item 2
500
750
0
1000
Item 1
Item 2
500
750
Item 3 875
0
1000
Item 1
Item 2
500
750
Item 3 875
0
1000
Item 4 937
Item 1
Item 2
500
750
Item 3 875
0
1000
Item 4 937
Item 5 968
Item 1
Item 2
500
750
Item 3 875
0
1000
Item 4 937
Item 5 968
Item 6 984
Item 1
Item 2
500
750
Item 3 875
0
1000
Item 4 937
Item 5 968
Item 6 984
Item 7 992
Item 1
Item 2
500
750
Item 3 875
0
1000
Item 4 937
Item 5 968
Item 6 984
Item 7 992
Item 8 996
Item 1
Item 2
500
750
Item 3 875
0
1000
Item 4 937
Item 5 968
Item 6 984
Item 7 992
Item 8 996
Number.MAX_SAFE_INTEGER
Only 53 IDs before running out of divisions
Item 1
Item 2
0.500
0.750
Item 3 0.875
0
1
Item 1
Item 2
500
750
Item 3 875
0
1000
Item 1 500
0
1000
Item 2 500
0
1000
Item 1 500
0
1000
Item 2 500
0
1000
1000/2 = 500

min = 500-100 = 400

max = 500+100 = 600

id = rand(min, max)
Item 1 500
0
1000
Item 2 500
0
1000
Item 1 485
0
1000
Item 2 513
0
1000
1000/2 = 500

min = 500-100 = 400

max = 500+100 = 600

id = rand(min, max)
Item 1 500
0
1000
Item 2 500
0
1000
Item 1 485
0
1000
Item 2 513
0
1000
1000/2 = 500

min = 500-100 = 400

max = 500+100 = 600

id = rand(min, max)
Item 1 485
0
1000
Item 2 513
0
1000
Item 1 500
0
1000
Item 2 500
0
1000
Item 1 485
0
1000
Item 2 513
0
1000
1000/2 = 500

min = 500-100 = 400

max = 500+100 = 600

id = rand(min, max)
Item 1 485
0
1000
Item 2 513 Item 2
485
0
1000
Item 1
513
Item 1 500
0
1000
Item 2 500
0
1000
Item 1 485
0
1000
Item 2 485
0
1000
1000/2 = 500

min = 500-100 = 400

max = 500+100 = 600

id = rand(min, max)
If we still pick randomly the same ID, then we fall back to
other way of sorting, for example node ID
Node A Node B
CRDT
Node A Node B
Synchronize
Item 1
Item 1 489 489
CRDT
Node A Node B
Synchronize
Item 1
Item 1
Item 1
Item 2
489 489
489
774
CRDT
Node A Node B
Synchronize
OP|A1 = [add,”Item 2”,774]
Item 1
Item 1
Item 1
Item 2
OP|B1 = [remove,489]
489 489
489
774
CRDT
Node A Node B
Synchronize
OP|A1 = [add,”Item 2”,774]
Item 1
Item 1
Item 1
Item 2
OP|B1 = [remove,489]
Item 2 Item 2
489 489
489
774
774 774
Move operation
Item 1
Item 2
489
774
Item 1
Item 2
489
774
OP|A1 = [moveUp,774]
Item 1
Item 2
489
774
OP|A1 = [moveUp,774]
OP|A1.1 = [remove,774]
OP|A1.2 = [add,”Item 2”,221]
Item 1 489
OP|A1 = [moveUp,774]
OP|A1.1 = [remove,774]
Item 2
Item 1
221
489
OP|A1 = [moveUp,774]
OP|A1.1 = [remove,774]
OP|A1.2 = [add,”Item 2”,221]
Item 1
Item 2
489
774
OP|A1 = [moveUp,899]
Item 3 899
Item 1
Item 2
489
774
OP|B1 = [moveUp,899]
Item 3 899
Item 1
Item 2
489
774
OP|A1 = [moveUp,899]
Item 3 899
Item 1
Item 2
489
774
OP|B1 = [moveUp,899]
Item 3 899
Item 1
Item 3
Item 2
Item 3
Item 1
Item 2
or
?
Item 1
Item 2
489
774
OP|A1 = [moveUp,899]
Item 3 899
OP|B1 = [moveUp,899]
Item 1
Item 2
489
774
OP|A1 = [moveUp,899]
Item 3 899
OP|B1 = [moveUp,899]
OP|A1.1 = [remove,899]
OP|A1.2 = [add,”Item 3”,620]
OP|B1.1 = [remove,899]
OP|B1.2 = [add,”Item 3”,661]
Item 1
Item 2
489
774
OP|A1 = [moveUp,899]
Item 3 899
OP|B1 = [moveUp,899]
OP|A1.1 = [remove,899]
OP|A1.2 = [add,”Item 3”,620]
OP|B1.1 = [remove,899]
OP|B1.2 = [add,”Item 3”,661]
OP|A1.1 = [remove,899]
OP|A1.2 = [add,”Item 3”,620]
OP|B1.1 = [remove,899]
OP|B1.2 = [add,”Item 3”,661]
Let’s say we always
pick insertion with
higher random ID
We can apply removal twice
Item 1
Item 2
489
774
OP|A1 = [moveUp,899]
Item 3 899
OP|B1 = [moveUp,899]
OP|A1.1 = [remove,899]
OP|A1.2 = [add,”Item 3”,620]
OP|B1.1 = [remove,899]
OP|B1.2 = [add,”Item 3”,661]
OP|A1.1 = [remove,899]
OP|A1.2 = [add,”Item 3”,620]
OP|B1.1 = [remove,899]
OP|B1.2 = [add,”Item 3”,661]
Let’s say we always
pick insertion with
higher random ID
We can apply removal twice
Item 1
Item 2
489
774 OP|A1.1 = [remove,899]
Item 1
Item 2
489
774
OP|A1 = [moveUp,899]
Item 3 899
OP|B1 = [moveUp,899]
OP|A1.1 = [remove,899]
OP|A1.2 = [add,”Item 3”,620]
OP|B1.1 = [remove,899]
OP|B1.2 = [add,”Item 3”,661]
OP|A1.1 = [remove,899]
OP|A1.2 = [add,”Item 3”,620]
OP|B1.1 = [remove,899]
OP|B1.2 = [add,”Item 3”,661]
Let’s say we always
pick insertion with
higher random ID
We can apply removal twice
Item 1
Item 2
489
774
Item 1
Item 3
489
661
Item 2 774
OP|A1.1 = [remove,899]
OP|B1.2 = [add,”Item 3”,661]
Item 1
Item 2
489
774
OP|A1 = [moveUp,774]
Item 3 899
Item 1
Item 2
489
774
OP|B1 = [moveDown,774]
Item 3 899
Item 2
Item 1
Item 3
Item 1
Item 3
Item 2
or
?
Item 1
Item 2
Item 3
or
Item 1
Item 2
489
774
OP|A1 = [moveUp,774]
Item 3 899
OP|B1 = [moveDown,774]
Item 1
Item 2
489
774
OP|A1 = [moveUp,774]
Item 3 899
OP|B1 = [moveDown,774]
OP|A1.1 = [remove,774]
OP|A1.2 = [add,”Item 2”,245]
OP|B1.1 = [remove,774]
OP|B1.2 = [add,”Item 2”,950]
Item 1
Item 2
489
774
OP|A1 = [moveUp,774]
Item 3 899
OP|B1 = [moveDown,774]
OP|A1.1 = [remove,774]
OP|A1.2 = [add,”Item 2”,245]
OP|B1.1 = [remove,774]
OP|B1.2 = [add,”Item 2”,950]
OP|A1.1 = [remove,774]
OP|A1.2 = [add,”Item 2”,245]
OP|B1.1 = [remove,774]
OP|B1.2 = [add,”Item 2”,950]
Let’s say we always
pick insertion with
smaller node ID

(A < B) so pick A1.2
We can apply removal twice
Item 1
Item 2
489
774
OP|A1 = [moveUp,774]
Item 3 899
OP|B1 = [moveDown,774]
OP|A1.1 = [remove,774]
OP|A1.2 = [add,”Item 2”,245]
OP|B1.1 = [remove,774]
OP|B1.2 = [add,”Item 2”,950]
OP|A1.1 = [remove,774]
OP|A1.2 = [add,”Item 2”,245]
OP|B1.1 = [remove,774]
OP|B1.2 = [add,”Item 2”,950]
Let’s say we always
pick insertion with
smaller node ID

(A < B) so pick A1.2
We can apply removal twice
Item 1
Item 3
489
899 OP|A1.1 = [remove,744]
Item 1
Item 2
489
774
OP|A1 = [moveUp,774]
Item 3 899
OP|B1 = [moveDown,774]
OP|A1.1 = [remove,774]
OP|A1.2 = [add,”Item 2”,245]
OP|B1.1 = [remove,774]
OP|B1.2 = [add,”Item 2”,950]
OP|A1.1 = [remove,774]
OP|A1.2 = [add,”Item 2”,245]
OP|B1.1 = [remove,774]
OP|B1.2 = [add,”Item 2”,950]
Let’s say we always
pick insertion with
smaller node ID

(A < B) so pick A1.2
We can apply removal twice
Item 1
Item 3
489
899
Item 2
Item 1
245
489
Item 3 899
OP|A1.1 = [remove,744]
OP|A1.2 = [add,”Item 2”,245]
Other conflicts
Item 1
Item 2
489
774
OP|A1 = [remove,774]
Item 3 899
Item 1
Item 2
489
774
OP|B1 = [moveDown,774]
Item 3 899
Item 1
Item 2
489
774
OP|A1 = [remove,774]
Item 3 899
Item 1
Item 2
489
774
OP|B1 = [moveDown,774]
Item 3 899
Item 1
Item 3
489
899
Item 1
Item 2
489
774
OP|A1 = [remove,774]
Item 3 899
Item 1
Item 2
489
774
OP|B1 = [markDone,774]
Item 3 899
Item 1
Item 2
489
774
OP|A1 = [remove,774]
Item 3 899
Item 1
Item 2
489
774
OP|B1 = [markDone,774]
Item 3 899
Item 1
Item 3
489
899
Order matters
Item 1
Item 2
489
774
Item 3 899
OP|A1 = [remove,774]
Item 1
Item 3
489
899
Item 1
Item 2
489
774
Item 3 899
OP|A1 = [remove,774]
Item 1
Item 3
489
899
OP|B1 = [moveDown,774]
Item 1
Item 3
489
899
Item 1
Item 2
489
774
Item 3 899
OP|A1 = [remove,774]
Item 1
Item 3
489
899
OP|B1 = [moveDown,774]
Item 1
Item 3
489
899
✅
Item 1
Item 2
489
774
Item 3 899
Item 1
Item 2
489
774
Item 3 899
Item 1
Item 2
489
774
OP|B1 = [moveDown,774]
Item 3 899
Item 1
Item 3
489
899
Item 2 933
Item 1
Item 2
489
774
OP|B1 = [moveDown,774]
Item 3 899
Item 1
Item 3
489
899
OP|A1 = [remove,774]
Item 1
Item 3
489
899
Item 2 933 Item 2 933
Item 1
Item 2
489
774
OP|B1 = [moveDown,774]
Item 3 899
Item 1
Item 3
489
899
OP|A1 = [remove,774]
Item 1
Item 3
489
899
❌
Item 2 933 Item 2 933
Removals
Insertions
Mark as done
Move
My solution
I
TodoList
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Remove 774
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Remove 774 Mark done 899
✅
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 2 774
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Remove 774 Mark done 899
✅ Remove 489
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 2 774
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Remove 774 Mark done 899
✅ Remove 489
Add “Item 5” 976
Item 5 976
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 2 774
Item 3 899
Item 5 911
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Remove 774 Mark done 899
✅ Remove 489
Add “Item 5” 976
Item 4 944 Move up 976
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Item 2 774
Item 3 899
Item 5 911
Item 1 489
Item 2 774
Item 3 899
Item 4 944
Remove 774
Mark done 899
✅
Remove 489
Add “Item 5” 976
Item 4 944
Move up 976
Remove 774
Mark done 899
Remove 489
Add “Item 5” 976
Move up 976
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 1 489
Item 3 899
Item 4 944
Item 2 774
Item 3 899
Item 5 911
Item 1 489
Item 3 899
Item 4 944
Mark done 899
✅
Remove 489
Add “Item 5” 976
Item 4 944
Move up 976
Mark done 899
Remove 489
Add “Item 5” 976
Move up 976
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 3 899
Item 4 944
Item 2 774
Item 3 899
Item 5 911
Item 3 899
Item 4 944
Mark done 899
✅
Add “Item 5” 976
Item 4 944
Move up 976
Mark done 899
Add “Item 5” 976
Move up 976
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 3 899
Item 4 944
Item 2 774
Item 3 899
Item 5 911
Item 3 899
Item 4 944
Mark done 899
✅
Item 4 944
Move up 976
Mark done 899
Move up 976
Add “Item 5” 976 Add “Item 5” 976
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 3 899
Item 4 944
Item 2 774
Item 3 899
Item 5 911
Item 3 899
Item 4 944
Mark done 899
✅
Item 4 944
Move up 976
Mark done 899
Move up 976
Item 5 976
Item 5 976
Add “Item extra” 971
Item extra 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 3 899
Item 4 944
Item 2 774
Item 3 899
Item 5 911
Item 3 899
Item 4 944
✅
Item 4 944
Move up 976 Move up 976
Item 5 976
Item 5 976
✅ ✅
Add “Item extra” 971
Item extra 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 1 489
Item 3 899
Item 4 944
Item 3 899
Item 5 911
Item 2 774
Item 3 899
Item 5 911
Item 3 899
Item 5 911
✅
Item 4 944
Item 4 944
Item 4 944
✅ ✅
Add “Item extra” 971
Item extra 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 3 899
Item 5 911
Item 3 899
Item 5 911
Item 4 944
Item 4 944
✅ ✅
Add “Item extra” 971
Item 3 899
Item 5 911
Item 4 944
✅ Item 3 899
Item 5 911
Item 4 944
✅
Item extra 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 3 899
Item 5 911
Item 3 899
Item 5 911
Item 4 944
Item 4 944
✅ ✅
Add “Item extra” 971
Item 3 899
Item 5 911
Item 4 944
✅ Item 3 899
Item 5 911
Item 4 944
✅
Item extra 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 3 899
Item 5 911
Item 3 899
Item 5 911
Item 4 944
Item 4 944
✅ ✅
Add “Item extra” 971
Item 3 899
Item 5 911
Item 4 944
✅ Item 3 899
Item 5 911
Item 4 944
✅
Item extra 971
Add “Item extra” 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 3 899
Item 5 911
Item 3 899
Item 5 911
Item 4 944
Item 4 944
✅ ✅
Item 3 899
Item 5 911
Item 4 944
✅ Item 3 899
Item 5 911
Item 4 944
✅
Item extra 971
Item extra 971 Item extra 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 3 899
Item 5 911
Item 3 899
Item 5 911
Item 4 944
Item 4 944
✅ ✅
Item 3 899
Item 5 911
Item 4 944
✅ Item 3 899
Item 5 911
Item 4 944
✅
Item extra 971
Item extra 971 Item extra 971
Item extra 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 3 899
Item 5 911
Item 3 899
Item 5 911
Item 4 944
Item 4 944
✅ ✅
Item 3 899
Item 5 911
Item extra 920
✅ Item 3 899
Item 5 911
Item extra 925
✅
Item 4 944
Item extra 971 Item extra 971
Item 4 944
Move up 971 Move up 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 3 899
Item 5 911
Item 3 899
Item 5 911
Item 4 944
Item 4 944
✅ ✅
Item 3 899
Item 5 911
Item extra 920
✅ Item 3 899
Item 5 911
Item extra 925
✅
Item 4 944
Item extra 971 Item extra 971
Item 4 944
Move up 971 Move up 971
Move up 971 Move up 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 3 899
Item 5 911
Item 3 899
Item 5 911
Item extra 920
Item extra 920
✅ ✅
Item 3 899
Item 5 911
Item extra 920
✅ Item 3 899
Item 5 911
Item extra 925
✅
Item 4 944
Item 4 944 Item 4 944
Item 4 944
Move up 971 Move up 971
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 3 899
Item 5 911
Item 3 899
Item 5 911
Item extra 920
Item extra 920
✅ ✅
Item 3 899
Item 5 911
Item extra 920
✅ Item 3 899
Item 5 911
Item extra 925
✅
Item 4 944
Item 4 944 Item 4 944
Item 4 944
I
Items Changes
Snapshot ChangesBu
ff
er
I
Items Changes
Snapshot ChangesBu
ff
er
Synchronize
Item 3 899
Item 5 911
Item 3 899
Item 5 911
Item extra 920
Item extra 920
✅ ✅
Item 3 899
Item 5 911
Item extra 920
✅ Item 3 899
Item 5 911
Item extra 920
✅
Item 4 944
Item 4 944 Item 4 944
Item 4 944
…
This was a take-home project 

in a recruitment process

for a technical leader role

in CKSource
But not any more! So don’t hesitate and join us :)
(Especially if you like challenges and vanilla JS!)
d.urbanski@cksource.com
Thanks!

More Related Content

Similar to Real-time collaboration in distributed systems for JavaScript developers. 

Nikolai Boiko "NodeJS Refactoring: How to kill a Dragon and stay alive"
Nikolai Boiko "NodeJS Refactoring: How to kill a Dragon and stay alive"Nikolai Boiko "NodeJS Refactoring: How to kill a Dragon and stay alive"
Nikolai Boiko "NodeJS Refactoring: How to kill a Dragon and stay alive"NodeUkraine
 
Stream-based Data Synchronization
Stream-based Data SynchronizationStream-based Data Synchronization
Stream-based Data SynchronizationKlemen Verdnik
 
Introduction to Python Language and Data Types
Introduction to Python Language and Data TypesIntroduction to Python Language and Data Types
Introduction to Python Language and Data TypesRavi Shankar
 
Make everything realtime & collaborative - JS Summit 2014
Make everything realtime & collaborative - JS Summit 2014Make everything realtime & collaborative - JS Summit 2014
Make everything realtime & collaborative - JS Summit 2014Joseph Gentle
 
The future will be Realtime & Collaborative
The future will be Realtime & CollaborativeThe future will be Realtime & Collaborative
The future will be Realtime & CollaborativeJoseph Gentle
 
Operational transformation
Operational transformationOperational transformation
Operational transformationMatteo Collina
 
Going Reactive with Relational Databases
Going Reactive with Relational DatabasesGoing Reactive with Relational Databases
Going Reactive with Relational DatabasesIvaylo Pashov
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz
 
React - render() to DOM - Boris Dinkevich - Codemotion Milan 2016
React - render() to DOM - Boris Dinkevich - Codemotion Milan 2016React - render() to DOM - Boris Dinkevich - Codemotion Milan 2016
React - render() to DOM - Boris Dinkevich - Codemotion Milan 2016Codemotion
 
Using Simplicity to Make Hard Big Data Problems Easy
Using Simplicity to Make Hard Big Data Problems EasyUsing Simplicity to Make Hard Big Data Problems Easy
Using Simplicity to Make Hard Big Data Problems Easynathanmarz
 
Ruby and rails - Advanced Training (Cybage)
Ruby and rails - Advanced Training (Cybage)Ruby and rails - Advanced Training (Cybage)
Ruby and rails - Advanced Training (Cybage)Gautam Rege
 
Frege - consequently functional programming for the JVM
Frege - consequently functional programming for the JVMFrege - consequently functional programming for the JVM
Frege - consequently functional programming for the JVMDierk König
 
MongoDB World 2019: Event Horizon: Meet Albert Einstein As You Move To The Cloud
MongoDB World 2019: Event Horizon: Meet Albert Einstein As You Move To The CloudMongoDB World 2019: Event Horizon: Meet Albert Einstein As You Move To The Cloud
MongoDB World 2019: Event Horizon: Meet Albert Einstein As You Move To The CloudMongoDB
 
Guaranteeing Consensus in Distriubuted Systems with CRDTs
Guaranteeing Consensus in Distriubuted Systems with CRDTsGuaranteeing Consensus in Distriubuted Systems with CRDTs
Guaranteeing Consensus in Distriubuted Systems with CRDTsSun-Li Beatteay
 
Architecture for scalable Angular applications
Architecture for scalable Angular applicationsArchitecture for scalable Angular applications
Architecture for scalable Angular applicationsPaweł Żurowski
 
Back to Basics 3: Scaling 30,000 Requests a Second with MongoDB
Back to Basics 3: Scaling 30,000 Requests a Second with MongoDBBack to Basics 3: Scaling 30,000 Requests a Second with MongoDB
Back to Basics 3: Scaling 30,000 Requests a Second with MongoDBMongoDB
 
Scaling to 30,000 Requests Per Second and Beyond with MongoDB
Scaling to 30,000 Requests Per Second and Beyond with MongoDBScaling to 30,000 Requests Per Second and Beyond with MongoDB
Scaling to 30,000 Requests Per Second and Beyond with MongoDBmchesnut
 
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...Databricks
 
P1.a&bGraftanns Metal work companyVariables u of metal allocat.docx
P1.a&bGraftanns Metal work companyVariables u  of metal allocat.docxP1.a&bGraftanns Metal work companyVariables u  of metal allocat.docx
P1.a&bGraftanns Metal work companyVariables u of metal allocat.docxalfred4lewis58146
 
Introduction to AngularJS
Introduction to AngularJSIntroduction to AngularJS
Introduction to AngularJSPat Cito
 

Similar to Real-time collaboration in distributed systems for JavaScript developers.  (20)

Nikolai Boiko "NodeJS Refactoring: How to kill a Dragon and stay alive"
Nikolai Boiko "NodeJS Refactoring: How to kill a Dragon and stay alive"Nikolai Boiko "NodeJS Refactoring: How to kill a Dragon and stay alive"
Nikolai Boiko "NodeJS Refactoring: How to kill a Dragon and stay alive"
 
Stream-based Data Synchronization
Stream-based Data SynchronizationStream-based Data Synchronization
Stream-based Data Synchronization
 
Introduction to Python Language and Data Types
Introduction to Python Language and Data TypesIntroduction to Python Language and Data Types
Introduction to Python Language and Data Types
 
Make everything realtime & collaborative - JS Summit 2014
Make everything realtime & collaborative - JS Summit 2014Make everything realtime & collaborative - JS Summit 2014
Make everything realtime & collaborative - JS Summit 2014
 
The future will be Realtime & Collaborative
The future will be Realtime & CollaborativeThe future will be Realtime & Collaborative
The future will be Realtime & Collaborative
 
Operational transformation
Operational transformationOperational transformation
Operational transformation
 
Going Reactive with Relational Databases
Going Reactive with Relational DatabasesGoing Reactive with Relational Databases
Going Reactive with Relational Databases
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
 
React - render() to DOM - Boris Dinkevich - Codemotion Milan 2016
React - render() to DOM - Boris Dinkevich - Codemotion Milan 2016React - render() to DOM - Boris Dinkevich - Codemotion Milan 2016
React - render() to DOM - Boris Dinkevich - Codemotion Milan 2016
 
Using Simplicity to Make Hard Big Data Problems Easy
Using Simplicity to Make Hard Big Data Problems EasyUsing Simplicity to Make Hard Big Data Problems Easy
Using Simplicity to Make Hard Big Data Problems Easy
 
Ruby and rails - Advanced Training (Cybage)
Ruby and rails - Advanced Training (Cybage)Ruby and rails - Advanced Training (Cybage)
Ruby and rails - Advanced Training (Cybage)
 
Frege - consequently functional programming for the JVM
Frege - consequently functional programming for the JVMFrege - consequently functional programming for the JVM
Frege - consequently functional programming for the JVM
 
MongoDB World 2019: Event Horizon: Meet Albert Einstein As You Move To The Cloud
MongoDB World 2019: Event Horizon: Meet Albert Einstein As You Move To The CloudMongoDB World 2019: Event Horizon: Meet Albert Einstein As You Move To The Cloud
MongoDB World 2019: Event Horizon: Meet Albert Einstein As You Move To The Cloud
 
Guaranteeing Consensus in Distriubuted Systems with CRDTs
Guaranteeing Consensus in Distriubuted Systems with CRDTsGuaranteeing Consensus in Distriubuted Systems with CRDTs
Guaranteeing Consensus in Distriubuted Systems with CRDTs
 
Architecture for scalable Angular applications
Architecture for scalable Angular applicationsArchitecture for scalable Angular applications
Architecture for scalable Angular applications
 
Back to Basics 3: Scaling 30,000 Requests a Second with MongoDB
Back to Basics 3: Scaling 30,000 Requests a Second with MongoDBBack to Basics 3: Scaling 30,000 Requests a Second with MongoDB
Back to Basics 3: Scaling 30,000 Requests a Second with MongoDB
 
Scaling to 30,000 Requests Per Second and Beyond with MongoDB
Scaling to 30,000 Requests Per Second and Beyond with MongoDBScaling to 30,000 Requests Per Second and Beyond with MongoDB
Scaling to 30,000 Requests Per Second and Beyond with MongoDB
 
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
Ray: A Cluster Computing Engine for Reinforcement Learning Applications with ...
 
P1.a&bGraftanns Metal work companyVariables u of metal allocat.docx
P1.a&bGraftanns Metal work companyVariables u  of metal allocat.docxP1.a&bGraftanns Metal work companyVariables u  of metal allocat.docx
P1.a&bGraftanns Metal work companyVariables u of metal allocat.docx
 
Introduction to AngularJS
Introduction to AngularJSIntroduction to AngularJS
Introduction to AngularJS
 

Recently uploaded

Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxJoão Esperancinha
 
Comparative Analysis of Text Summarization Techniques
Comparative Analysis of Text Summarization TechniquesComparative Analysis of Text Summarization Techniques
Comparative Analysis of Text Summarization Techniquesugginaramesh
 
8251 universal synchronous asynchronous receiver transmitter
8251 universal synchronous asynchronous receiver transmitter8251 universal synchronous asynchronous receiver transmitter
8251 universal synchronous asynchronous receiver transmitterShivangiSharma879191
 
TechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor Catchers
TechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor CatchersTechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor Catchers
TechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor Catcherssdickerson1
 
Biology for Computer Engineers Course Handout.pptx
Biology for Computer Engineers Course Handout.pptxBiology for Computer Engineers Course Handout.pptx
Biology for Computer Engineers Course Handout.pptxDeepakSakkari2
 
Risk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdfRisk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdfROCENODodongVILLACER
 
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube ExchangerStudy on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube ExchangerAnamika Sarkar
 
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdfCCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdfAsst.prof M.Gokilavani
 
Software and Systems Engineering Standards: Verification and Validation of Sy...
Software and Systems Engineering Standards: Verification and Validation of Sy...Software and Systems Engineering Standards: Verification and Validation of Sy...
Software and Systems Engineering Standards: Verification and Validation of Sy...VICTOR MAESTRE RAMIREZ
 
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionSachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionDr.Costas Sachpazis
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile servicerehmti665
 
Introduction to Machine Learning Unit-3 for II MECH
Introduction to Machine Learning Unit-3 for II MECHIntroduction to Machine Learning Unit-3 for II MECH
Introduction to Machine Learning Unit-3 for II MECHC Sai Kiran
 
main PPT.pptx of girls hostel security using rfid
main PPT.pptx of girls hostel security using rfidmain PPT.pptx of girls hostel security using rfid
main PPT.pptx of girls hostel security using rfidNikhilNagaraju
 
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsyncWhy does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsyncssuser2ae721
 
Past, Present and Future of Generative AI
Past, Present and Future of Generative AIPast, Present and Future of Generative AI
Past, Present and Future of Generative AIabhishek36461
 

Recently uploaded (20)

young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
 
Comparative Analysis of Text Summarization Techniques
Comparative Analysis of Text Summarization TechniquesComparative Analysis of Text Summarization Techniques
Comparative Analysis of Text Summarization Techniques
 
Call Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCR
Call Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCRCall Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCR
Call Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCR
 
8251 universal synchronous asynchronous receiver transmitter
8251 universal synchronous asynchronous receiver transmitter8251 universal synchronous asynchronous receiver transmitter
8251 universal synchronous asynchronous receiver transmitter
 
TechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor Catchers
TechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor CatchersTechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor Catchers
TechTAC® CFD Report Summary: A Comparison of Two Types of Tubing Anchor Catchers
 
Biology for Computer Engineers Course Handout.pptx
Biology for Computer Engineers Course Handout.pptxBiology for Computer Engineers Course Handout.pptx
Biology for Computer Engineers Course Handout.pptx
 
Risk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdfRisk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdf
 
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube ExchangerStudy on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
 
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdfCCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
 
Software and Systems Engineering Standards: Verification and Validation of Sy...
Software and Systems Engineering Standards: Verification and Validation of Sy...Software and Systems Engineering Standards: Verification and Validation of Sy...
Software and Systems Engineering Standards: Verification and Validation of Sy...
 
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
 
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionSachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile service
 
Introduction to Machine Learning Unit-3 for II MECH
Introduction to Machine Learning Unit-3 for II MECHIntroduction to Machine Learning Unit-3 for II MECH
Introduction to Machine Learning Unit-3 for II MECH
 
main PPT.pptx of girls hostel security using rfid
main PPT.pptx of girls hostel security using rfidmain PPT.pptx of girls hostel security using rfid
main PPT.pptx of girls hostel security using rfid
 
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsyncWhy does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
 
Design and analysis of solar grass cutter.pdf
Design and analysis of solar grass cutter.pdfDesign and analysis of solar grass cutter.pdf
Design and analysis of solar grass cutter.pdf
 
Past, Present and Future of Generative AI
Past, Present and Future of Generative AIPast, Present and Future of Generative AI
Past, Present and Future of Generative AI
 
Exploring_Network_Security_with_JA3_by_Rakesh Seal.pptx
Exploring_Network_Security_with_JA3_by_Rakesh Seal.pptxExploring_Network_Security_with_JA3_by_Rakesh Seal.pptx
Exploring_Network_Security_with_JA3_by_Rakesh Seal.pptx
 

Real-time collaboration in distributed systems for JavaScript developers. 

  • 1. Just another to-do app. Or is it? Real-time collaboration in distributed systems for JavaScript developers. 
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17. 🎉
  • 19.
  • 20.
  • 21.
  • 22. The task Create a todo list application with synchronization capabilities
  • 23. The task In other words: enable real-time collaboration capabilities for the todo list
  • 24. The task Conflicts should be resolved
 in a reasonable way
  • 25. The task You cannot use any existing libraries to do this. You are the library creator
  • 26. The task For sake of simplicity place two lists on the same page, simulating both of them being in offline mode, and make synchronization to happen on a button click
  • 27.
  • 28. Node A Node B Synchronize Item 1
  • 29. Node A Node B Synchronize Item 1 Node A Node B Item 1 Item 1
  • 30. Node A Node B Synchronize Item 1
  • 31. Node A Node B Synchronize Item 1 Hey! Here are my items: [{“label”:”Item 1”,“done”:false}] Hey! Here are my items: []
  • 32. Node A Node B Synchronize Item 1 Hey! Here are my items: [{“label”:”Item 1”,“done”:false}] Hey! Here are my items: [] Run some merging logic Run some merging logic
  • 33. Node A Node B Synchronize Item 1 Node A Node B Item 1 Item 1 Hey! Here are my items: [{“label”:”Item 1”,“done”:false}] Hey! Here are my items: [] Run some merging logic Run some merging logic
  • 34. Node A Node B Synchronize Item 1 Node A Node B Item 1 Item 1 Hey! Here are my items: [{“label”:”Item 1”,“done”:false}] Hey! Here are my items: [] Run some merging logic Run some merging logic Send the
 whole state
  • 35. Node A Node B Synchronize Item 1 Item 1 Problem
  • 36. Node A Node B Synchronize Item 1 Item 1 Node A Node B Item 1 Item 2 Problem
  • 37. Node A Node B Synchronize Item 1 Item 1 Node A Node B Item 1 Item 2 Problem
  • 38. Node A Node B Synchronize Item 1 Item 1 Node A Node B Item 1 Item 2 Node A Node B Item 1 Item 2 Item 1 Item 2 Problem
  • 39. Node A Node B Synchronize Item 1
  • 40. Node A Node B Synchronize Item 1 Hey! Here are my changes: [{“type”: “add”,“label”:”Item 1”,“done”:false}] Hey! Here are my changes: []
  • 41. Node A Node B Synchronize Item 1 Hey! Here are my changes: [{“type”: “add”,“label”:”Item 1”,“done”:false}] Hey! Here are my changes: [] Apply received changes Apply received changes
  • 42. Node A Node B Synchronize Item 1 Node A Node B Item 1 Item 1 Hey! Here are my changes: [{“type”: “add”,“label”:”Item 1”,“done”:false}] Hey! Here are my changes: [] Apply received changes Apply received changes
  • 43. Node A Node B Synchronize Item 1 Node A Node B Item 1 Item 1 Hey! Here are my changes: [{“type”: “add”,“label”:”Item 1”,“done”:false}] Hey! Here are my changes: [] Apply received changes Apply received changes Send all
 local changes
  • 44. Node A Node B Synchronize Item 1 Item 1
  • 45. Node A Node B Synchronize Item 1 Item 1 Node A Node B Item 1 Item 2
  • 46. Node A Node B Synchronize Item 1 Item 1 Node A Node B Item 1 Item 2
  • 47. Node A Node B Synchronize Item 1 Item 1 Node A Node B Item 1 Item 2 Node A Node B Item 2 Item 2
  • 49. Node A Node B Synchronize
  • 50. Node A Node B Synchronize Node A Node B Item 1 Item 2
  • 51. Node A Node B Synchronize Node A Node B Item 1 Item 2
  • 52. Node A Node B Synchronize Node A Node B Node A Node B Item 1 Item 2 Item 1 Item 2 Item 2 Item 1
  • 54. Happened-before relation Node A Node B A Time Time
  • 55. Happened-before relation Node A Node B A A` Time Time
  • 56. Happened-before relation Node A Node B A A` A happened before A` Time Time
  • 57. Happened-before relation Node A Node B A A` A happened before A` Time Time B A` happened before B
  • 58. Happened-before relation Node A Node B A A` A happened before A` Time Time B A` happened before B A happened before B
  • 59. Happened-before relation Node A Node B A A` Time Time B B`
  • 60. Happened-before relation Node A Node B A A` Time Time B B` A < A` < B < B` Total order
  • 61. Happened-before relation Node A Node B A A` Time Time B B`
  • 62. Happened-before relation Node A Node B A A` Time Time B B` A < A` Partial order B < B` A < B` B < A`
  • 63. Happened-before relation Node A Node B A A` Time Time B B` A < A` Partial order B < B` Incomparable (concurrent changes) A || B A` || B` A < B` B < A`
  • 64. Happened-before relation Node A Node B A A` Time Time B B` A < A` Partial order B < B` Incomparable (concurrent changes) A || B A` || B` A < B` B < A`
  • 65. Happened-before relation Node A Node B A1 Time Time B1 A2 A3 B2 B3 Synchronize
  • 66. Happened-before relation Node A Node B A1 Time Time B1 B1` A2 A3 B2 B3 Synchronize A1` A2` A3` B2` B3` Incomparable (concurrent changes)
  • 70. Solutions OT (Operational transformation) CRDT (Con fl ict-free replicated data type) My solution (Based somehow on CRDT)
  • 71. OT
  • 73. OT Node A Node B Synchronize Item 1 Item 1 0 0
  • 74. OT Node A Node B Synchronize Item 1 Item 1 Item 1 Item 2 0 0 0 1 0
  • 75. OT Node A Node B Synchronize OP|A1 = [add,”Item 2”,1] Item 1 Item 1 Item 1 Item 2 OP|B1 = [remove,0] 0 0 0 1 0
  • 76. OT Node A Node B Synchronize OP|A1 = [add,”Item 2”,1] OP|A1` = [add,”Item 2”,0] Item 1 Item 1 Item 1 Item 2 OP|B1 = [remove,0] OP|B1` = [remove,0] 0 0 0 1 0
  • 77. OT Node A Node B Synchronize OP|A1 = [add,”Item 2”,1] OP|A1` = [add,”Item 2”,0] Item 1 Item 1 Item 1 Item 2 OP|B1 = [remove,0] OP|B1` = [remove,0] Item 2 Item 2 0 0 0 1 0 0 0
  • 78. OT OP|A1 = [add,”Item 2”,1] OP|A1` = [add,”Item 2”,0]
  • 79. OT Item 1 Item 2 Item 3 Item 4 Item 5 ❌ ❌ ❌ 0 1 2 3 4
  • 80. OT Item 1 Item 2 Item 3 Item 4 Item 5 ❌ ❌ ❌ 0 1 2 3 4 Item 1 Item 4 0 1 2 3 4
  • 81. OT Item 1 Item 2 Item 3 Item 4 Item 5 ❌ ❌ ❌ 0 1 2 3 4 OP|A1 = [add,”New item 4”,3] Item 1 Item 4 0 1 2 3 4
  • 82. OT Item 1 Item 2 Item 3 Item 4 Item 5 ❌ ❌ ❌ 0 1 2 3 4 OP|A1 = [add,”New item 4”,3] Item 1 Item 4 0 1 2 3 4
  • 83. OT Item 1 Item 2 Item 3 Item 4 Item 5 ❌ ❌ ❌ 0 1 2 3 4 OP|A1 = [add,”New item 4”,3] Item 1 Item 4 0 1 2 3 4 OP|A1` = [add,”New item 4”,1]
  • 84. OT Item 1 Item 2 Item 3 Item 4 Item 5 ❌ ❌ ❌ 0 1 2 3 4 OP|A1 = [add,”New item 4”,3] Item 1 Item 4 0 1 2 3 4 OP|A1` = [add,”New item 4”,1] Removals:
 [1,2,4]
  • 85. OT Item 1 Item 2 Item 3 Item 4 Item 5 ❌ ❌ ❌ 0 1 2 3 4 OP|A1 = [add,”New item 4”,3] Item 1 Item 4 0 1 2 3 4 OP|A1` = [add,”New item 4”,1] Removals:
 [1,2,4] Count of removals for index less than 3 = 2 ( [1,2] ) ( 3 - 2 = 1 )
  • 86. OT - cons and pros “Operations can be applied in any order so we don’t have to care about timing”
  • 87. OT - cons and pros “OT approach of defining operations through their offsets … raise serious issues… resulting combinations of states and operations are extremely hard to foresee and understand”
  • 88. OT - cons and pros "Unfortunately, implementing OT sucks. There's a million algorithms with different tradeoffs, mostly trapped in academic papers.”
  • 89. OT - cons and pros dOPT Ellis & Gibbs 1989 adOPTed Ressel et al. 1996 IMDR Imine et al. 2003 Jupiter Nichols et al. 1995 SOCT2 Suleiman et al. 1997 SDT Li & Li 2004 SOCT3/4 Vidot et al. 2000 TTF Oster et al. 2006 Credit: Martin Kleppmann https://www.youtube.com/watch?v=B5NULPSiOGw&t=915s
  • 90. OT - cons and pros dOPT Ellis & Gibbs 1989 adOPTed Ressel et al. 1996 IMDR Imine et al. 2003 Jupiter Nichols et al. 1995 SOCT2 Suleiman et al. 1997 SDT Li & Li 2004 SOCT3/4 Vidot et al. 2000 TTF Oster et al. 2006 Require
 central
 server Credit: Martin Kleppmann https://www.youtube.com/watch?v=B5NULPSiOGw&t=915s
  • 91.
  • 92. CRDT
  • 93. Item 1 Item 2 Unique ID Unique ID Item 3 Unique ID Di ff erent algorithms generate IDs in di ff erent ways: Binary tree path, integer + replica ID pair, vectors, logical clock timestamp etc…
  • 98. Item 1 Item 2 500 750 Item 3 875 0 1000 Item 4 937
  • 99. Item 1 Item 2 500 750 Item 3 875 0 1000 Item 4 937 Item 5 968
  • 100. Item 1 Item 2 500 750 Item 3 875 0 1000 Item 4 937 Item 5 968 Item 6 984
  • 101. Item 1 Item 2 500 750 Item 3 875 0 1000 Item 4 937 Item 5 968 Item 6 984 Item 7 992
  • 102. Item 1 Item 2 500 750 Item 3 875 0 1000 Item 4 937 Item 5 968 Item 6 984 Item 7 992 Item 8 996
  • 103. Item 1 Item 2 500 750 Item 3 875 0 1000 Item 4 937 Item 5 968 Item 6 984 Item 7 992 Item 8 996 Number.MAX_SAFE_INTEGER Only 53 IDs before running out of divisions
  • 105. Item 1 Item 2 500 750 Item 3 875 0 1000
  • 106. Item 1 500 0 1000 Item 2 500 0 1000
  • 107. Item 1 500 0 1000 Item 2 500 0 1000 1000/2 = 500
 min = 500-100 = 400
 max = 500+100 = 600
 id = rand(min, max)
  • 108. Item 1 500 0 1000 Item 2 500 0 1000 Item 1 485 0 1000 Item 2 513 0 1000 1000/2 = 500
 min = 500-100 = 400
 max = 500+100 = 600
 id = rand(min, max)
  • 109. Item 1 500 0 1000 Item 2 500 0 1000 Item 1 485 0 1000 Item 2 513 0 1000 1000/2 = 500
 min = 500-100 = 400
 max = 500+100 = 600
 id = rand(min, max) Item 1 485 0 1000 Item 2 513 0 1000
  • 110. Item 1 500 0 1000 Item 2 500 0 1000 Item 1 485 0 1000 Item 2 513 0 1000 1000/2 = 500
 min = 500-100 = 400
 max = 500+100 = 600
 id = rand(min, max) Item 1 485 0 1000 Item 2 513 Item 2 485 0 1000 Item 1 513
  • 111. Item 1 500 0 1000 Item 2 500 0 1000 Item 1 485 0 1000 Item 2 485 0 1000 1000/2 = 500
 min = 500-100 = 400
 max = 500+100 = 600
 id = rand(min, max) If we still pick randomly the same ID, then we fall back to other way of sorting, for example node ID Node A Node B
  • 112. CRDT Node A Node B Synchronize Item 1 Item 1 489 489
  • 113. CRDT Node A Node B Synchronize Item 1 Item 1 Item 1 Item 2 489 489 489 774
  • 114. CRDT Node A Node B Synchronize OP|A1 = [add,”Item 2”,774] Item 1 Item 1 Item 1 Item 2 OP|B1 = [remove,489] 489 489 489 774
  • 115. CRDT Node A Node B Synchronize OP|A1 = [add,”Item 2”,774] Item 1 Item 1 Item 1 Item 2 OP|B1 = [remove,489] Item 2 Item 2 489 489 489 774 774 774
  • 118. Item 1 Item 2 489 774 OP|A1 = [moveUp,774]
  • 119. Item 1 Item 2 489 774 OP|A1 = [moveUp,774] OP|A1.1 = [remove,774] OP|A1.2 = [add,”Item 2”,221]
  • 120. Item 1 489 OP|A1 = [moveUp,774] OP|A1.1 = [remove,774]
  • 121. Item 2 Item 1 221 489 OP|A1 = [moveUp,774] OP|A1.1 = [remove,774] OP|A1.2 = [add,”Item 2”,221]
  • 122. Item 1 Item 2 489 774 OP|A1 = [moveUp,899] Item 3 899 Item 1 Item 2 489 774 OP|B1 = [moveUp,899] Item 3 899
  • 123. Item 1 Item 2 489 774 OP|A1 = [moveUp,899] Item 3 899 Item 1 Item 2 489 774 OP|B1 = [moveUp,899] Item 3 899 Item 1 Item 3 Item 2 Item 3 Item 1 Item 2 or ?
  • 124. Item 1 Item 2 489 774 OP|A1 = [moveUp,899] Item 3 899 OP|B1 = [moveUp,899]
  • 125. Item 1 Item 2 489 774 OP|A1 = [moveUp,899] Item 3 899 OP|B1 = [moveUp,899] OP|A1.1 = [remove,899] OP|A1.2 = [add,”Item 3”,620] OP|B1.1 = [remove,899] OP|B1.2 = [add,”Item 3”,661]
  • 126. Item 1 Item 2 489 774 OP|A1 = [moveUp,899] Item 3 899 OP|B1 = [moveUp,899] OP|A1.1 = [remove,899] OP|A1.2 = [add,”Item 3”,620] OP|B1.1 = [remove,899] OP|B1.2 = [add,”Item 3”,661] OP|A1.1 = [remove,899] OP|A1.2 = [add,”Item 3”,620] OP|B1.1 = [remove,899] OP|B1.2 = [add,”Item 3”,661] Let’s say we always pick insertion with higher random ID We can apply removal twice
  • 127. Item 1 Item 2 489 774 OP|A1 = [moveUp,899] Item 3 899 OP|B1 = [moveUp,899] OP|A1.1 = [remove,899] OP|A1.2 = [add,”Item 3”,620] OP|B1.1 = [remove,899] OP|B1.2 = [add,”Item 3”,661] OP|A1.1 = [remove,899] OP|A1.2 = [add,”Item 3”,620] OP|B1.1 = [remove,899] OP|B1.2 = [add,”Item 3”,661] Let’s say we always pick insertion with higher random ID We can apply removal twice Item 1 Item 2 489 774 OP|A1.1 = [remove,899]
  • 128. Item 1 Item 2 489 774 OP|A1 = [moveUp,899] Item 3 899 OP|B1 = [moveUp,899] OP|A1.1 = [remove,899] OP|A1.2 = [add,”Item 3”,620] OP|B1.1 = [remove,899] OP|B1.2 = [add,”Item 3”,661] OP|A1.1 = [remove,899] OP|A1.2 = [add,”Item 3”,620] OP|B1.1 = [remove,899] OP|B1.2 = [add,”Item 3”,661] Let’s say we always pick insertion with higher random ID We can apply removal twice Item 1 Item 2 489 774 Item 1 Item 3 489 661 Item 2 774 OP|A1.1 = [remove,899] OP|B1.2 = [add,”Item 3”,661]
  • 129. Item 1 Item 2 489 774 OP|A1 = [moveUp,774] Item 3 899 Item 1 Item 2 489 774 OP|B1 = [moveDown,774] Item 3 899 Item 2 Item 1 Item 3 Item 1 Item 3 Item 2 or ? Item 1 Item 2 Item 3 or
  • 130. Item 1 Item 2 489 774 OP|A1 = [moveUp,774] Item 3 899 OP|B1 = [moveDown,774]
  • 131. Item 1 Item 2 489 774 OP|A1 = [moveUp,774] Item 3 899 OP|B1 = [moveDown,774] OP|A1.1 = [remove,774] OP|A1.2 = [add,”Item 2”,245] OP|B1.1 = [remove,774] OP|B1.2 = [add,”Item 2”,950]
  • 132. Item 1 Item 2 489 774 OP|A1 = [moveUp,774] Item 3 899 OP|B1 = [moveDown,774] OP|A1.1 = [remove,774] OP|A1.2 = [add,”Item 2”,245] OP|B1.1 = [remove,774] OP|B1.2 = [add,”Item 2”,950] OP|A1.1 = [remove,774] OP|A1.2 = [add,”Item 2”,245] OP|B1.1 = [remove,774] OP|B1.2 = [add,”Item 2”,950] Let’s say we always pick insertion with smaller node ID
 (A < B) so pick A1.2 We can apply removal twice
  • 133. Item 1 Item 2 489 774 OP|A1 = [moveUp,774] Item 3 899 OP|B1 = [moveDown,774] OP|A1.1 = [remove,774] OP|A1.2 = [add,”Item 2”,245] OP|B1.1 = [remove,774] OP|B1.2 = [add,”Item 2”,950] OP|A1.1 = [remove,774] OP|A1.2 = [add,”Item 2”,245] OP|B1.1 = [remove,774] OP|B1.2 = [add,”Item 2”,950] Let’s say we always pick insertion with smaller node ID
 (A < B) so pick A1.2 We can apply removal twice Item 1 Item 3 489 899 OP|A1.1 = [remove,744]
  • 134. Item 1 Item 2 489 774 OP|A1 = [moveUp,774] Item 3 899 OP|B1 = [moveDown,774] OP|A1.1 = [remove,774] OP|A1.2 = [add,”Item 2”,245] OP|B1.1 = [remove,774] OP|B1.2 = [add,”Item 2”,950] OP|A1.1 = [remove,774] OP|A1.2 = [add,”Item 2”,245] OP|B1.1 = [remove,774] OP|B1.2 = [add,”Item 2”,950] Let’s say we always pick insertion with smaller node ID
 (A < B) so pick A1.2 We can apply removal twice Item 1 Item 3 489 899 Item 2 Item 1 245 489 Item 3 899 OP|A1.1 = [remove,744] OP|A1.2 = [add,”Item 2”,245]
  • 136. Item 1 Item 2 489 774 OP|A1 = [remove,774] Item 3 899 Item 1 Item 2 489 774 OP|B1 = [moveDown,774] Item 3 899
  • 137. Item 1 Item 2 489 774 OP|A1 = [remove,774] Item 3 899 Item 1 Item 2 489 774 OP|B1 = [moveDown,774] Item 3 899 Item 1 Item 3 489 899
  • 138. Item 1 Item 2 489 774 OP|A1 = [remove,774] Item 3 899 Item 1 Item 2 489 774 OP|B1 = [markDone,774] Item 3 899
  • 139. Item 1 Item 2 489 774 OP|A1 = [remove,774] Item 3 899 Item 1 Item 2 489 774 OP|B1 = [markDone,774] Item 3 899 Item 1 Item 3 489 899
  • 142. OP|A1 = [remove,774] Item 1 Item 3 489 899 Item 1 Item 2 489 774 Item 3 899
  • 143. OP|A1 = [remove,774] Item 1 Item 3 489 899 OP|B1 = [moveDown,774] Item 1 Item 3 489 899 Item 1 Item 2 489 774 Item 3 899
  • 144. OP|A1 = [remove,774] Item 1 Item 3 489 899 OP|B1 = [moveDown,774] Item 1 Item 3 489 899 ✅ Item 1 Item 2 489 774 Item 3 899
  • 146. Item 1 Item 2 489 774 OP|B1 = [moveDown,774] Item 3 899 Item 1 Item 3 489 899 Item 2 933
  • 147. Item 1 Item 2 489 774 OP|B1 = [moveDown,774] Item 3 899 Item 1 Item 3 489 899 OP|A1 = [remove,774] Item 1 Item 3 489 899 Item 2 933 Item 2 933
  • 148. Item 1 Item 2 489 774 OP|B1 = [moveDown,774] Item 3 899 Item 1 Item 3 489 899 OP|A1 = [remove,774] Item 1 Item 3 489 899 ❌ Item 2 933 Item 2 933
  • 151.
  • 153. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize
  • 154. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944
  • 155. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Remove 774
  • 156. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Remove 774 Mark done 899 ✅
  • 157. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 2 774 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Remove 774 Mark done 899 ✅ Remove 489
  • 158. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 2 774 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Remove 774 Mark done 899 ✅ Remove 489 Add “Item 5” 976 Item 5 976
  • 159. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 2 774 Item 3 899 Item 5 911 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Remove 774 Mark done 899 ✅ Remove 489 Add “Item 5” 976 Item 4 944 Move up 976
  • 160. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Item 2 774 Item 3 899 Item 5 911 Item 1 489 Item 2 774 Item 3 899 Item 4 944 Remove 774 Mark done 899 ✅ Remove 489 Add “Item 5” 976 Item 4 944 Move up 976 Remove 774 Mark done 899 Remove 489 Add “Item 5” 976 Move up 976
  • 161. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 1 489 Item 3 899 Item 4 944 Item 2 774 Item 3 899 Item 5 911 Item 1 489 Item 3 899 Item 4 944 Mark done 899 ✅ Remove 489 Add “Item 5” 976 Item 4 944 Move up 976 Mark done 899 Remove 489 Add “Item 5” 976 Move up 976
  • 162. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 3 899 Item 4 944 Item 2 774 Item 3 899 Item 5 911 Item 3 899 Item 4 944 Mark done 899 ✅ Add “Item 5” 976 Item 4 944 Move up 976 Mark done 899 Add “Item 5” 976 Move up 976
  • 163. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 3 899 Item 4 944 Item 2 774 Item 3 899 Item 5 911 Item 3 899 Item 4 944 Mark done 899 ✅ Item 4 944 Move up 976 Mark done 899 Move up 976 Add “Item 5” 976 Add “Item 5” 976
  • 164. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 3 899 Item 4 944 Item 2 774 Item 3 899 Item 5 911 Item 3 899 Item 4 944 Mark done 899 ✅ Item 4 944 Move up 976 Mark done 899 Move up 976 Item 5 976 Item 5 976 Add “Item extra” 971 Item extra 971
  • 165. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 3 899 Item 4 944 Item 2 774 Item 3 899 Item 5 911 Item 3 899 Item 4 944 ✅ Item 4 944 Move up 976 Move up 976 Item 5 976 Item 5 976 ✅ ✅ Add “Item extra” 971 Item extra 971
  • 166. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 1 489 Item 3 899 Item 4 944 Item 3 899 Item 5 911 Item 2 774 Item 3 899 Item 5 911 Item 3 899 Item 5 911 ✅ Item 4 944 Item 4 944 Item 4 944 ✅ ✅ Add “Item extra” 971 Item extra 971
  • 167. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 3 899 Item 5 911 Item 3 899 Item 5 911 Item 4 944 Item 4 944 ✅ ✅ Add “Item extra” 971 Item 3 899 Item 5 911 Item 4 944 ✅ Item 3 899 Item 5 911 Item 4 944 ✅ Item extra 971
  • 168. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 3 899 Item 5 911 Item 3 899 Item 5 911 Item 4 944 Item 4 944 ✅ ✅ Add “Item extra” 971 Item 3 899 Item 5 911 Item 4 944 ✅ Item 3 899 Item 5 911 Item 4 944 ✅ Item extra 971
  • 169. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 3 899 Item 5 911 Item 3 899 Item 5 911 Item 4 944 Item 4 944 ✅ ✅ Add “Item extra” 971 Item 3 899 Item 5 911 Item 4 944 ✅ Item 3 899 Item 5 911 Item 4 944 ✅ Item extra 971 Add “Item extra” 971
  • 170. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 3 899 Item 5 911 Item 3 899 Item 5 911 Item 4 944 Item 4 944 ✅ ✅ Item 3 899 Item 5 911 Item 4 944 ✅ Item 3 899 Item 5 911 Item 4 944 ✅ Item extra 971 Item extra 971 Item extra 971
  • 171. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 3 899 Item 5 911 Item 3 899 Item 5 911 Item 4 944 Item 4 944 ✅ ✅ Item 3 899 Item 5 911 Item 4 944 ✅ Item 3 899 Item 5 911 Item 4 944 ✅ Item extra 971 Item extra 971 Item extra 971 Item extra 971
  • 172. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 3 899 Item 5 911 Item 3 899 Item 5 911 Item 4 944 Item 4 944 ✅ ✅ Item 3 899 Item 5 911 Item extra 920 ✅ Item 3 899 Item 5 911 Item extra 925 ✅ Item 4 944 Item extra 971 Item extra 971 Item 4 944 Move up 971 Move up 971
  • 173. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 3 899 Item 5 911 Item 3 899 Item 5 911 Item 4 944 Item 4 944 ✅ ✅ Item 3 899 Item 5 911 Item extra 920 ✅ Item 3 899 Item 5 911 Item extra 925 ✅ Item 4 944 Item extra 971 Item extra 971 Item 4 944 Move up 971 Move up 971 Move up 971 Move up 971
  • 174. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 3 899 Item 5 911 Item 3 899 Item 5 911 Item extra 920 Item extra 920 ✅ ✅ Item 3 899 Item 5 911 Item extra 920 ✅ Item 3 899 Item 5 911 Item extra 925 ✅ Item 4 944 Item 4 944 Item 4 944 Item 4 944 Move up 971 Move up 971
  • 175. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 3 899 Item 5 911 Item 3 899 Item 5 911 Item extra 920 Item extra 920 ✅ ✅ Item 3 899 Item 5 911 Item extra 920 ✅ Item 3 899 Item 5 911 Item extra 925 ✅ Item 4 944 Item 4 944 Item 4 944 Item 4 944
  • 176. I Items Changes Snapshot ChangesBu ff er I Items Changes Snapshot ChangesBu ff er Synchronize Item 3 899 Item 5 911 Item 3 899 Item 5 911 Item extra 920 Item extra 920 ✅ ✅ Item 3 899 Item 5 911 Item extra 920 ✅ Item 3 899 Item 5 911 Item extra 920 ✅ Item 4 944 Item 4 944 Item 4 944 Item 4 944
  • 177.
  • 178. This was a take-home project 
 in a recruitment process
 for a technical leader role
 in CKSource
  • 179. But not any more! So don’t hesitate and join us :) (Especially if you like challenges and vanilla JS!)