From 3914e4e4087ebeb6b40fd134da95c274b880b1c1 Mon Sep 17 00:00:00 2001 From: Romain Courteaud <romain@nexedi.com> Date: Fri, 29 May 2015 16:46:54 +0200 Subject: [PATCH] ReplicateStorage: allow to reduce number of checks during synchronization --- src/jio.storage/replicatestorage.js | 69 +++- test/jio.storage/replicatestorage.tests.js | 408 ++++++++++++++++++++- 2 files changed, 465 insertions(+), 12 deletions(-) diff --git a/src/jio.storage/replicatestorage.js b/src/jio.storage/replicatestorage.js index 5f828c4..e04b71e 100644 --- a/src/jio.storage/replicatestorage.js +++ b/src/jio.storage/replicatestorage.js @@ -53,6 +53,30 @@ }); this._use_remote_post = spec.use_remote_post || false; + this._check_local_modification = spec.check_local_modification; + if (this._check_local_modification === undefined) { + this._check_local_modification = true; + } + this._check_local_creation = spec.check_local_creation; + if (this._check_local_creation === undefined) { + this._check_local_creation = true; + } + this._check_local_deletion = spec.check_local_deletion; + if (this._check_local_deletion === undefined) { + this._check_local_deletion = true; + } + this._check_remote_modification = spec.check_remote_modification; + if (this._check_remote_modification === undefined) { + this._check_remote_modification = true; + } + this._check_remote_creation = spec.check_remote_creation; + if (this._check_remote_creation === undefined) { + this._check_remote_creation = true; + } + this._check_remote_deletion = spec.check_remote_deletion; + if (this._check_remote_deletion === undefined) { + this._check_remote_deletion = true; + } } ReplicateStorage.prototype.remove = function (id) { @@ -304,19 +328,25 @@ signature_dict[result_list[1].data.rows[i].id] = i; } } - for (key in local_dict) { - if (local_dict.hasOwnProperty(key)) { - if (!signature_dict.hasOwnProperty(key)) { - checkLocalCreation(queue, source, destination, key, options); + if (options.check_creation === true) { + for (key in local_dict) { + if (local_dict.hasOwnProperty(key)) { + if (!signature_dict.hasOwnProperty(key)) { + checkLocalCreation(queue, source, destination, key, options); + } } } } for (key in signature_dict) { if (signature_dict.hasOwnProperty(key)) { if (local_dict.hasOwnProperty(key)) { - checkSignatureDifference(queue, source, destination, key); + if (options.check_modification === true) { + checkSignatureDifference(queue, source, destination, key); + } } else { - checkLocalDeletion(queue, destination, key, source); + if (options.check_deletion === true) { + checkLocalDeletion(queue, destination, key, source); + } } } } @@ -360,13 +390,30 @@ }) .push(function () { - return pushStorage(context._local_sub_storage, - context._remote_sub_storage, - {use_post: context._use_remote_post}); + if (context._check_local_modification || + context._check_local_creation || + context._check_local_deletion) { + return pushStorage(context._local_sub_storage, + context._remote_sub_storage, + { + use_post: context._use_remote_post, + check_modification: context._check_local_modification, + check_creation: context._check_local_creation, + check_deletion: context._check_local_deletion + }); + } }) .push(function () { - return pushStorage(context._remote_sub_storage, - context._local_sub_storage, {}); + if (context._check_remote_modification || + context._check_remote_creation || + context._check_remote_deletion) { + return pushStorage(context._remote_sub_storage, + context._local_sub_storage, { + check_modification: context._check_remote_modification, + check_creation: context._check_remote_creation, + check_deletion: context._check_remote_deletion + }); + } }); }; diff --git a/test/jio.storage/replicatestorage.tests.js b/test/jio.storage/replicatestorage.tests.js index bc7bf20..07342aa 100644 --- a/test/jio.storage/replicatestorage.tests.js +++ b/test/jio.storage/replicatestorage.tests.js @@ -46,6 +46,12 @@ deepEqual(jio.__storage._query_options, {}); equal(jio.__storage._use_remote_post, false); + equal(jio.__storage._check_local_creation, true); + equal(jio.__storage._check_local_deletion, true); + equal(jio.__storage._check_local_modification, true); + equal(jio.__storage._check_remote_creation, true); + equal(jio.__storage._check_remote_deletion, true); + equal(jio.__storage._check_remote_modification, true); equal(jio.__storage._signature_hash, "_replicate_7209dfbcaff00f6637f939fdd71fa896793ed385"); @@ -73,7 +79,13 @@ type: "replicatestorage500" }, query: {query: 'portal_type: "Foo"', limit: [0, 1234567890]}, - use_remote_post: true + use_remote_post: true, + check_local_creation: false, + check_local_deletion: false, + check_local_modification: false, + check_remote_creation: false, + check_remote_deletion: false, + check_remote_modification: false }); deepEqual( @@ -81,6 +93,12 @@ {query: 'portal_type: "Foo"', limit: [0, 1234567890]} ); equal(jio.__storage._use_remote_post, true); + equal(jio.__storage._check_local_creation, false); + equal(jio.__storage._check_local_deletion, false); + equal(jio.__storage._check_local_modification, false); + equal(jio.__storage._check_remote_creation, false); + equal(jio.__storage._check_remote_deletion, false); + equal(jio.__storage._check_remote_modification, false); equal(jio.__storage._signature_hash, "_replicate_623653d45a4e770a2c9f6b71e3144d18ee1b5bec"); @@ -434,6 +452,63 @@ }); }); + test("local document creation not checked", function () { + stop(); + expect(6); + + this.jio = jIO.createJIO({ + type: "replicate", + check_local_creation: false, + local_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + }, + remote_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + }); + + var id, + context = this; + + context.jio.post({"title": "foo"}) + .then(function (result) { + id = result; + return context.jio.repair(); + }) + .then(function () { + return context.jio.get(id); + }) + .then(function (result) { + deepEqual(result, { + title: "foo" + }); + }) + .then(function () { + return context.jio.__storage._remote_sub_storage.get(id); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.message, "Cannot find document: " + id); + equal(error.status_code, 404); + }) + .then(function () { + return context.jio.__storage._signature_sub_storage.get(id); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.status_code, 404); + }) + .always(function () { + start(); + }); + }); + test("local document creation and use remote post", function () { stop(); expect(12); @@ -677,6 +752,66 @@ }); }); + test("remote document creation not checked", function () { + stop(); + expect(6); + + var id, + context = this; + + this.jio = jIO.createJIO({ + type: "replicate", + check_remote_creation: false, + local_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + }, + remote_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + }); + + context.jio.__storage._remote_sub_storage.post({"title": "bar"}) + .then(function (result) { + id = result; + return context.jio.repair(); + }) + .then(function () { + return context.jio.__storage._remote_sub_storage.get(id); + }) + .then(function (result) { + deepEqual(result, { + title: "bar" + }); + }) + .then(function () { + return context.jio.get(id); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.message, "Cannot find document: " + id); + equal(error.status_code, 404); + }) + .then(function () { + return context.jio.__storage._signature_sub_storage.get(id); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.status_code, 404); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + test("local and remote document creations", function () { stop(); expect(5); @@ -823,6 +958,73 @@ }); }); + test("local document modification not checked", function () { + stop(); + expect(3); + + var id, + context = this; + + this.jio = jIO.createJIO({ + type: "replicate", + check_local_modification: false, + local_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + }, + remote_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + }); + + context.jio.post({"title": "foo"}) + .then(function (result) { + id = result; + return context.jio.repair(); + }) + .then(function () { + return context.jio.put(id, {"title": "foo2"}); + }) + .then(function () { + return context.jio.repair(); + }) + .then(function () { + return context.jio.get(id); + }) + .then(function (result) { + deepEqual(result, { + title: "foo2" + }); + }) + .then(function () { + return context.jio.__storage._remote_sub_storage.get(id); + }) + .then(function (result) { + deepEqual(result, { + title: "foo" + }); + }) + .then(function () { + return context.jio.__storage._signature_sub_storage.get(id); + }) + .then(function (result) { + deepEqual(result, { + hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5" + }); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + test("remote document modification", function () { stop(); expect(2); @@ -868,6 +1070,76 @@ }); }); + test("remote document modification not checked", function () { + stop(); + expect(3); + + var id, + context = this; + + this.jio = jIO.createJIO({ + type: "replicate", + check_remote_modification: false, + local_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + }, + remote_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + }); + + context.jio.post({"title": "foo"}) + .then(function (result) { + id = result; + return context.jio.repair(); + }) + .then(function () { + return context.jio.__storage._remote_sub_storage.put( + id, + {"title": "foo3"} + ); + }) + .then(function () { + return context.jio.repair(); + }) + .then(function () { + return context.jio.__storage._remote_sub_storage.get(id); + }) + .then(function (result) { + deepEqual(result, { + title: "foo3" + }); + }) + .then(function () { + return context.jio.get(id); + }) + .then(function (result) { + deepEqual(result, { + title: "foo" + }); + }) + .then(function () { + return context.jio.__storage._signature_sub_storage.get(id); + }) + .then(function (result) { + deepEqual(result, { + hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5" + }); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + test("local and remote document modifications", function () { stop(); expect(4); @@ -992,6 +1264,73 @@ }); }); + test("local document deletion not checked", function () { + stop(); + expect(6); + + var id, + context = this; + + this.jio = jIO.createJIO({ + type: "replicate", + check_local_deletion: false, + local_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + }, + remote_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + }); + + context.jio.post({"title": "foo"}) + .then(function (result) { + id = result; + return context.jio.repair(); + }) + .then(function () { + return context.jio.remove(id); + }) + .then(function () { + return context.jio.repair(); + }) + .then(function () { + ok(true, "Removal correctly synced"); + }) + .then(function () { + return context.jio.get(id); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.message, "Cannot find document: " + id); + equal(error.status_code, 404); + }) + .then(function () { + return context.jio.__storage._remote_sub_storage.get(id); + }) + .then(function (result) { + deepEqual(result, { + title: "foo" + }); + }) + .then(function () { + return context.jio.__storage._signature_sub_storage.get(id); + }) + .then(function (result) { + deepEqual(result, { + hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5" + }); + }) + .always(function () { + start(); + }); + }); + test("remote document deletion", function () { stop(); expect(6); @@ -1037,6 +1376,73 @@ }); }); + test("remote document deletion not checked", function () { + stop(); + expect(6); + + var id, + context = this; + + this.jio = jIO.createJIO({ + type: "replicate", + check_remote_deletion: false, + local_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + }, + remote_sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + }); + + context.jio.post({"title": "foo"}) + .then(function (result) { + id = result; + return context.jio.repair(); + }) + .then(function () { + return context.jio.__storage._remote_sub_storage.remove(id); + }) + .then(function () { + return context.jio.repair(); + }) + .then(function () { + ok(true, "Removal correctly synced"); + }) + .then(function () { + return context.jio.__storage._remote_sub_storage.get(id); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.message, "Cannot find document: " + id); + equal(error.status_code, 404); + }) + .then(function () { + return context.jio.get(id); + }) + .then(function (result) { + deepEqual(result, { + title: "foo" + }); + }) + .then(function () { + return context.jio.__storage._signature_sub_storage.get(id); + }) + .then(function (result) { + deepEqual(result, { + hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5" + }); + }) + .always(function () { + start(); + }); + }); + test("local and remote document deletions", function () { stop(); expect(8); -- 2.30.9