dominictarr / crdt

Commutative Replicated Data Types for easy collaborative/distributed systems.
MIT License
836 stars 43 forks source link

Removal of a row which is in a set is not replicated #40

Open simonratner opened 9 years ago

simonratner commented 9 years ago

Here's some code:

var assert = require('assert');
var crdt = require('crdt');

var a = new crdt.Doc();
var b = new crdt.Doc();
crdt.sync(a, b);

a.add({id: '1', foo: 'bar'});
a.add({id: '2', foo: 'baz'});

a.on('row_update', function(r) {
    console.log('a row updated', r.id, r.state);
});
a.on('remove', function(r) {
    console.log('a row removed', r.id, r.state);
});
b.on('row_update', function(r) {
    console.log('b row updated', r.id, r.state);
});
b.on('remove', function(r) {
    console.log('b row removed', r.id, r.state);
});

var bars = b.createSet('foo', 'bar');

setImmediate(function() {
    console.log('--');
    assert.deepEqual(a.toJSON(), b.toJSON());

    a.rm('1');
    setImmediate(function() {
        assert.deepEqual(a.toJSON(), b.toJSON());
    });
});

Here's the output:

b row updated 1 { id: '1', foo: 'bar' }
b row updated 2 { id: '2', foo: 'baz' }
--
a row removed 1 { id: '1', foo: 'bar' }
a row updated 1 { id: '1', foo: null }
b row updated 1 { id: '1', foo: null }
b row removed 1 { id: '1', foo: null }
b row updated 1 { id: '1', foo: null }
a row updated 1 { id: '1', foo: 'bar' }

assert.js:92
  throw new assert.AssertionError({
        ^
AssertionError: {"1":{"id":"1","foo":null},"2":{"id":"2","foo":"baz"}} deepEqual {"2":{"id":"2","foo":"baz"}}
    at Object._onImmediate (crdt.js:32:16)
    at processImmediate [as _immediateCallback] (timers.js:345:15)

If I remove the call to createSet, the output looks like this instead:

b row updated 1 { id: '1', foo: 'bar' }
b row updated 2 { id: '2', foo: 'baz' }
--
a row removed 1 { id: '1', foo: 'bar' }
b row removed 1 { id: '1', foo: 'bar' }
b row updated 1 { id: '1', foo: 'bar' }
a row updated 1 { id: '1', foo: 'bar' }

It looks like the call to set.rm in https://github.com/dominictarr/crdt/blob/master/doc.js#L179 might be causing the row to be re-added with the null set key?

dominictarr commented 9 years ago

hmm, this soundsn like a bug, can you make a failing testcase for this?

simonratner commented 9 years ago

Sure, the code is above, but I've pulled it into a test: https://github.com/dominictarr/crdt/pull/41