Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug when performing multiple sync() #603

Open
chacha912 opened this issue Aug 6, 2023 · 0 comments
Open

Bug when performing multiple sync() #603

chacha912 opened this issue Aug 6, 2023 · 0 comments
Labels
bug 🐞 Something isn't working

Comments

@chacha912
Copy link
Contributor

chacha912 commented Aug 6, 2023

What happened:
When performing multiple 'pushpull' requests, the SDK doesn't work correctly. For example, the following test case fails:

for (let i = 0; i < 3; i++) {
it.only('Should work correctly even when "sync" is called multiple times', async function () {
type TestDoc = { k1: Array<number> };
const docKey = toDocKey(`${this.test!.title}-${new Date().getTime()}`);
// 01. c1 attaches d1 and c2 watches same doc.
const c1 = new yorkie.Client(testRPCAddr);
await c1.activate();
const d1 = new yorkie.Document<TestDoc>(docKey);
d1.update((root) => {
root['k1'] = [1, 2];
}, 'set array');
await c1.attach(d1);
assert.equal(d1.toSortedJSON(), '{"k1":[1,2]}');
const c2 = new yorkie.Client(testRPCAddr);
await c2.activate();
const d2 = new yorkie.Document<TestDoc>(docKey);
await c2.attach(d2);
assert.equal(d2.toSortedJSON(), '{"k1":[1,2]}');
// 02. c1 updates d1 and removes it.
d1.update((root) => {
root['k1'].push(3);
});
assert.equal(d1.toSortedJSON(), '{"k1":[1,2,3]}', 'd1');
await c1.sync();
// 03. c2 syncs and checks that d2 is removed.
c2.sync();
await c2.sync();
assert.equal(d2.toSortedJSON(), '{"k1":[1,2,3]}', 'd2');
await c1.deactivate();
await c2.deactivate();
});
}

test fail

Anything else we need to know?:

In the test code, four changes are generated:

  • change (serverSeq 1): d1 update root['k1'] = [1, 2]
  • change (serverSeq 2): c1 initial presence (within c1.attach)
  • change (serverSeq 3): c2 initial presence (within c2.attach)
  • change (serverSeq 4): d1 update root['k1'].push(3)

When c2.sync() is called, it sends two pushpull requests with checkpoint{clientSeq: 1, serverSeq: 3}. The server responds with change (serverSeq 4), then c2 applies the same change twice, resulting in [1, 2, 3, 3] not [1, 2, 3].
(When multiple changes are pushed, the server handles it to prevent duplicate changes from being stored. However, the client needs to handle it when processing the response.)

server log

I think one of the solution is enqueuing 'sync' requests. The next request should be sent after receiving the response to update the server sequence.

Environment:

  • Operating system:
  • Browser and version:
  • Yorkie version (use yorkie version): 0.4.5
  • Yorkie JS SDK version: 0.4.5
@hackerwins hackerwins added the bug 🐞 Something isn't working label Aug 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐞 Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants