Commit 05349435 authored by Yaxel Perez's avatar Yaxel Perez

fixed concurrency issues so that all tests pass

parent 4c66f034
......@@ -330,10 +330,6 @@
});
};
JioProxyStorage.prototype.list = function () {
return this.__storage.list.apply(this.__storage, arguments);
};
declareMethod(JioProxyStorage, 'putAttachment', function (argument_list,
storage,
method_name) {
......@@ -475,11 +471,6 @@
options = {};
}
return ensurePushableQueue(function () {
// this will fail with an unhelpful errror message if context does not
// have the "query" capacity.
// possible fixes:
// - Catch errors thrown by hasCapacity everywhere all the time
// - Refactor hasCapacity to return false instead of raising an error
if (context.hasCapacity("list") &&
((options.query === undefined) || context.hasCapacity("query")) &&
((options.sort_on === undefined) || context.hasCapacity("sort")) &&
......
/*global define, jIO */
/*global define, jIO, RSVP */
/*jslint nomen: true*/
(function (jIO) {
// (function (jIO, RSVP) {
"use strict";
function randomId() {
// https://gist.github.com/gordonbrander/2230317
return '_' + Math.random().toString(36).substr(2, 9);
}
function ListStorage(spec) {
this._sub_storage = jIO.createJIO(spec.sub_storage);
this._signature_storage = jIO.createJIO({
"type": "indexeddb",
"database": randomId()
});
this._index_storage = jIO.createJIO(spec.index_storage);
this._index_initialized = false;
this._index_tmp = []; // temporary array to put ids
this._index_removed_tmp = []; // temp array to put removed ids
}
ListStorage.prototype.list = function () {
// lazily initialize the list in _signature_storage
var ctx = this;
return this._signature_storage.get('_').then(function (list) {
return list;
}).fail(function () {
return ctx._signature_storage.put('_', []).then(function () {
return [];
ListStorage.prototype.buildQuery = function () {
return this.getIndex();
};
ListStorage.prototype.hasCapacity = function (name) {
if (name === 'list') {
return true;
}
return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
};
ListStorage.prototype.getIndex = function () {
// in brief:
// pull all ids from _index_tmp and put them in the _index_storage
// and remove ids from _index_removed_tmp
// and then return the new '_' entry
var ctx = this,
tmp = this._index_tmp,
removed_tmp = this._index_removed_tmp;
ctx._index_tmp = [];
ctx._index_removed_tmp = [];
if (!ctx._index_initialized) {
ctx._index_initialized = true;
tmp = tmp.filter(function (id) {
return removed_tmp.indexOf(id) === -1;
});
return this._index_storage.put('_', tmp)
.then(function () {
return tmp;
});
}
return ctx._index_storage.get('_').then(function (index) {
var newIndex = index.concat(tmp);
newIndex = newIndex.filter(function (id) {
return removed_tmp.indexOf(id) === -1;
});
return ctx._index_storage.put('_', newIndex)
.then(function () {
return newIndex;
});
});
};
......@@ -33,12 +60,8 @@
var ctx = this;
return this._sub_storage.post.apply(this._sub_storage, arguments)
.then(function (id) {
return ctx.list().then(function (list) {
list.push(id);
return ctx._signature_storage.put('_', list).then(function () {
return id;
});
});
ctx._index_tmp.push(id);
return id;
});
};
......@@ -50,12 +73,8 @@
var ctx = this;
return this._sub_storage.put.apply(this._sub_storage, arguments)
.then(function (id) {
return ctx.list().then(function (list) {
list.push(id);
return ctx._signature_storage.put('_', list).then(function () {
return id;
});
});
ctx._index_tmp.push(id);
return id;
});
};
......@@ -63,14 +82,11 @@
var ctx = this;
return this._sub_storage.remove.apply(this._sub_storage, arguments)
.then(function (id) {
return ctx.list().then(function (list) {
list = list.filter(function (x) { return id !== x; });
return ctx._signature_storage.put('_', list).then(function () {
return id;
});
});
ctx._index_removed_tmp.push(id);
return id;
});
};
jIO.addStorage("list", ListStorage);
}(jIO));
// }(jIO, RSVP));
......@@ -29,8 +29,11 @@
this._sub_storage = jIO.createJIO(spec.sub_storage);
}
NoCapacityStorage.prototype.hasCapacity = function () {
return false;
NoCapacityStorage.prototype.hasCapacity = function (name) {
if (name === "query") {
return false;
}
return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
};
NoCapacityStorage.prototype.get = function () {
......
......@@ -9,12 +9,80 @@
type: "list",
sub_storage: {
type: "memory"
},
index_storage: {
type: "memory"
}
});
QUnit.expect(0);
});
// NOTE: list method is implicitly tested in the following two methods
QUnit.test("check concurrent write", function () {
QUnit.stop();
QUnit.expect(12);
var i,
promise_list = [],
storage = jIO.createJIO({
type: "list",
// This storage will store the document IDs
index_storage: {
type: "memory"
},
// This storage will store the documents
sub_storage: {
type: "nocapacity",
sub_storage: {
type: "memory"
}
}
});
// Create many document in parallel
for (i = 0; i < 10; i += 1) {
promise_list.push(storage.put('foo' + i, {bar: i}));
}
return RSVP.all(promise_list)
.then(function () {
// The list of document can be retrieved
return storage.allDocs();
})
.then(function (result) {
QUnit.equal(result.data.total_rows, 10);
// Every document can be retrieved too
promise_list = [];
for (i = 0; i < 10; i += 1) {
promise_list.push(storage.get('foo' + i));
}
return RSVP.all(promise_list);
})
.then(function (result_list) {
for (i = 0; i < 10; i += 1) {
QUnit.deepEqual(result_list[i], {bar: i});
}
// Remove all documents
promise_list = [];
for (i = 0; i < 10; i += 1) {
promise_list.push(storage.remove('foo' + i));
}
return RSVP.all(promise_list);
})
.then(function () {
// The list of document must be empty
return storage.allDocs();
})
.then(function (result) {
QUnit.equal(result.data.total_rows, 0);
})
.fail(function (error) {
console.error(error);
throw error;
})
.always(function () {
QUnit.start();
});
});
QUnit.test('post method correctly records ids', function (assert) {
QUnit.stop();
......@@ -22,21 +90,31 @@
var jio = jIO.createJIO({
type: 'list',
index_storage: {
type: "memory",
},
sub_storage: {
type: 'uuid',
sub_storage: {
type: 'memory'
}
}
});
}),
promise_list = [],
i = 0;
jio.post({}).then(function (id1) {
jio.post({}).then(function (id2) {
jio.list().then(function (l) {
QUnit.start();
assert.deepEqual(l, [id1, id2]);
});
});
for (i = 0; i < 10; i += 1) {
promise_list.push(jio.post(i));
}
RSVP.all(promise_list).then(function (ids) {
var x = jio.allDocs();
x.then(function (res) {
return res.data.rows;
}).then(function (rows) {
QUnit.start();
assert.deepEqual(rows, ids);
}).fail(console.error);
}).fail(console.error);
});
......@@ -46,21 +124,31 @@
var jio = jIO.createJIO({
type: 'list',
index_storage: {
type: "memory",
},
sub_storage: {
type: 'uuid',
sub_storage: {
type: 'memory'
}
}
});
}),
promise_list = [],
i = 0;
jio.put('test', {}).then(function (id1) {
jio.put('test2', {}).then(function (id2) {
jio.list().then(function (l) {
QUnit.start();
assert.deepEqual(l, [id1, id2]);
});
});
for (i = 0; i < 10; i += 1) {
promise_list.push(jio.put(i.toString(), {'test': i}));
}
RSVP.all(promise_list).then(function (ids) {
var x = jio.allDocs();
x.then(function (res) {
return res.data.rows;
}).then(function (rows) {
QUnit.start();
assert.deepEqual(rows, ids);
}).fail(console.error);
}).fail(console.error);
});
......@@ -70,22 +158,38 @@
var jio = jIO.createJIO({
type: 'list',
index_storage: {
type: "memory",
},
sub_storage: {
type: 'uuid',
sub_storage: {
type: 'memory'
}
}
});
}),
promise_list = [],
i = 0;
jio.put('test', {}).then(function () {
jio.put('test2', {}).then(function () {
jio.remove('test').then(function () {
jio.list().then(function (l2) {
QUnit.start();
assert.deepEqual(l2, ['test2']);
});
});
for (i = 0; i < 10; i += 1) {
promise_list.push(jio.put(i.toString(), {'test': i}));
}
RSVP.all(promise_list).then(function (ids) {
var removal_promises = [];
for (i = 0; i < 10; i += 1) {
removal_promises.push(jio.remove(ids[i]));
}
RSVP.all(removal_promises).then(function () {
return jio.allDocs();
}).then(function (res) {
return res.data.rows;
}).then(function (all) {
QUnit.start();
assert.deepEqual(all, []);
}).fail(function (err) {
console.error(err);
QUnit.start();
});
}).fail(console.error);
});
......
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