Commit ae26852d authored by Sven Franck's avatar Sven Franck

temporary commit on replicatestorage with master/slave

parent 7bfedd00
......@@ -45,11 +45,12 @@
addStorageFunction = require('jio').addStorage;
/**
* Make a clean clone of an object with clean referring to removal of all
* flags indicating missing or non-coherent elements.
* Make a clone of an object WITHOUT _xxx (except _id). This is what is
* compared when compared when checking answers from multiple storages
* @method cleanClone
* @param {Object} obj to clone
* @return {Object} clones object
*/
**/
function cleanClone (obj) {
var prop, r = {};
......@@ -60,16 +61,16 @@
}
}
}
return r;
};
/**
* Generate a checksum from a passed string to compare the response returned
* by multiple storages for the same requests.
* @method checksum
* @param {Object} obj to generate a checksum for
* @return {Integer} checksum
*/
**/
function checksum (obj) {
var r, i, str = JSON.stringify(obj);
......@@ -129,45 +130,6 @@
});
}
// /**
// * Awaits for an answer from one promise only. Promises are cancelled only
// * by calling `first(promise_list).cancel()`.
// *
// * first(promise_list): Promise
// *
// * @param {Array} promise_list An array of promises
// * @return {Promise} A new promise
// */
// function first(promise_list) {
// var length = promise_list.length;
// promise_list = promise_list.slice();
// return new Promise(function (resolve, reject, notify) {
// var index, count = 0;
// function rejecter(answer) {
// count += 1;
// if (count === length) {
// return reject(answer);
// }
// }
// function notifier(index) {
// return function (notification) {
// notify({
// "index": index,
// "value": notification
// });
// };
// }
// for (index = 0; index < length; index += 1) {
// promise_list[index].then(resolve, rejecter, notifier(index));
// }
// }, function () {
// var index;
// for (index = 0; index < length; index += 1) {
// promise_list[index].cancel();
// }
// });
// }
/**
* Responds with the last resolved promise answer recieved. If all promises
* are rejected, it returns the latest rejected promise answer
......@@ -178,9 +140,11 @@
*
* @param {Array} promise_list An array of promises
* @param {Integer} master The "promise" with id authority
* @param {Object} temp Any temporary data created by master
* @return {Promise} A new promise
*/
function last(promise_list, master) {
// NOTE: added master parameter for master-slave storage
function last(promise_list, master, temp) {
var length = promise_list.length;
promise_list = promise_list.slice();
......@@ -191,6 +155,9 @@
return function (answer) {
count += 1;
if (count === length) {
if (temp) {
answer._temp = temp;
}
return resolve(answer);
}
last_answer = answer;
......@@ -204,6 +171,9 @@
}
count += 1;
if (count === length) {
if (temp) {
answer._temp = temp;
}
return resolve(last_answer);
}
};
......@@ -234,19 +204,12 @@
}
/**
* Test a GET response across multiple storages. Returns first valid document
* together with the following parameters:
*
* _missing = true > when a storage returns a 404 for this document
* _conflict_list = [] > all docs in conflict (including "self")
*
* Promises are cancelled only by calling
*
* `checkAndReturn(promise_list).cancel()`
*
* @param {Array} promise_list An array of promises
* Test responses of a GET request for coherence (will set _conflict)
* and missing (will set _missing) on the returned document
* @method checkAndReturn
* @param {Object} promise_list List of responses received
* @return {Promise} A new promise
*/
**/
function checkAndReturn(promise_list) {
var length = promise_list.length;
......@@ -318,7 +281,8 @@
}
this._storage_list = spec.storage_list;
this._master = spec.master;
}
};
ReplicateStorage.prototype.post = function (command, metadata, option) {
var index, subindex,
......@@ -341,16 +305,15 @@
}
}
// first master, then slave
sequence([
function () {
// master storage
if (master !== undefined) {
return last(priority_list, master);
}
return {};
},
function (response) {
// slave storages
var method, subindex = 0;
if (response.id) {
metadata._id = response.id;
......@@ -375,14 +338,52 @@
};
ReplicateStorage.prototype.put = function (command, metadata, option) {
var promise_list = [], index, length = this._storage_list.length;
for (index = 0; index < length; index += 1) {
promise_list[index] =
command.storage(this._storage_list[index]).put(metadata, option);
var index, subindex,
storages = this._storage_list,
promise_list = [],
priority_list = [],
length = storages.length,
master = this._master;
// setup master storage or all
if (master !== undefined) {
priority_list[0] = success(
command.storage(storages[master]).put(metadata, option)
);
} else {
for (index = 0; index < length; index += 1) {
promise_list[index] = success(
command.storage(storages[index]).put(metadata, option)
);
}
}
sequence([function () {
return last(promise_list);
}, [command.success, command.error]]);
// run master, then slave
sequence([
function () {
return last(priority_list, master);
},
function (response) {
var subindex;
switch (true) {
case response.status >= 500: command.error(response); break;
// HACK: why does 204 return status code 0 on promises?
case response.status === 0:
default:
for (index = 0, subindex = 0; index < length; index += 1) {
if (index !== master) {
promise_list[subindex] = success(
command.storage(storages[index]).put(metadata, option)
);
subindex += 1;
}
}
return last(promise_list, undefined, response._temp);
}
},
[command.success, command.error]
]);
};
ReplicateStorage.prototype.putAttachment = function (command, param, option) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment