Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergiy Kyrylkov committed Aug 7, 2017
0 parents commit ea5c347
Show file tree
Hide file tree
Showing 22 changed files with 914 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
node_modules
1 change: 1 addition & 0 deletions README.md
@@ -0,0 +1 @@
https://kyrylkov.com/2017/04/25/native-promises-async-functions-nodejs-8-performance/
24 changes: 24 additions & 0 deletions bench
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
benchmark=$1
nodepath=${2:-node}
shift 2;
cwd=${PWD}

trap 'cd "$cwd"' EXIT

if [ "$benchmark" = "doxbee" ]; then
cd "$cwd"
npm install
echo "Doxbee sequential"
$nodepath performance.js --n 10000 --t 1 ./doxbee-sequential/*.js --harmony "$@"
exit 0
elif [ "$benchmark" = "parallel" ]; then
cd "$cwd"
npm install
echo "Madeup parallel"
$nodepath performance.js --n 10000 --t 1 --p 25 ./madeup-parallel/*.js --harmony "$@"
exit 0
else
echo "Invalid benchmark name $benchmark"
exit -1
fi
43 changes: 43 additions & 0 deletions doxbee-sequential/async-bluebird.js
@@ -0,0 +1,43 @@
global.useBluebird = true;
require('../lib/fakesP');

module.exports = async function upload(stream, idOrPath, tag, done) {
try {
var blob = blobManager.create(account);
var tx = db.begin();
var blobId = await blob.put(stream);
var file = await self.byUuidOrPath(idOrPath).get();

var previousId = file ? file.version : null;
version = {
userAccountId: userAccount.id,
date: new Date(),
blobId: blobId,
creatorId: userAccount.id,
previousId: previousId,
};
version.id = Version.createHash(version);
await Version.insert(version).execWithin(tx);
if (!file) {
var splitPath = idOrPath.split('/');
var fileName = splitPath[splitPath.length - 1];
file = {
id: uuid.v1(),
userAccountId: userAccount.id,
name: fileName,
version: version.id
}
var query = await self.createQuery(idOrPath, file);
await query.execWithin(tx);
}
await FileVersion.insert({fileId: file.id, versionId: version.id})
.execWithin(tx);
await File.whereUpdate({id: file.id}, {version: version.id})
.execWithin(tx);
tx.commit();
done();
} catch (err) {
tx.rollback();
done(err);
}
}
43 changes: 43 additions & 0 deletions doxbee-sequential/async-es2017-native.js
@@ -0,0 +1,43 @@
global.useNative = true;
require('../lib/fakesP');

module.exports = async function upload(stream, idOrPath, tag, done) {
try {
var blob = blobManager.create(account);
var tx = db.begin();
var blobId = await blob.put(stream);
var file = await self.byUuidOrPath(idOrPath).get();

var previousId = file ? file.version : null;
version = {
userAccountId: userAccount.id,
date: new Date(),
blobId: blobId,
creatorId: userAccount.id,
previousId: previousId,
};
version.id = Version.createHash(version);
await Version.insert(version).execWithin(tx);
if (!file) {
var splitPath = idOrPath.split('/');
var fileName = splitPath[splitPath.length - 1];
file = {
id: uuid.v1(),
userAccountId: userAccount.id,
name: fileName,
version: version.id
}
var query = await self.createQuery(idOrPath, file);
await query.execWithin(tx);
}
await FileVersion.insert({fileId: file.id, versionId: version.id})
.execWithin(tx);
await File.whereUpdate({id: file.id}, {version: version.id})
.execWithin(tx);
tx.commit();
done();
} catch (err) {
tx.rollback();
done(err);
}
}
59 changes: 59 additions & 0 deletions doxbee-sequential/callbacks-baseline.js
@@ -0,0 +1,59 @@
require('../lib/fakes');

module.exports = function upload(stream, idOrPath, tag, done) {
var blob = blobManager.create(account);
var tx = db.begin();
function backoff(err) {
tx.rollback();
return done(err);
}
blob.put(stream, function (err, blobId) {
if (err) return done(err);
self.byUuidOrPath(idOrPath).get(function (err, file) {
if (err) return done(err);
var previousId = file ? file.version : null;
var version = {
userAccountId: userAccount.id,
date: new Date(),
blobId: blobId,
creatorId: userAccount.id,
previousId: previousId,
};
version.id = Version.createHash(version);
Version.insert(version).execWithin(tx, function (err) {
if (err) return backoff(err);
if (!file) {
var splitPath = idOrPath.split('/');
var fileName = splitPath[splitPath.length - 1];
var newId = uuid.v1();
self.createQuery(idOrPath, {
id: newId,
userAccountId: userAccount.id,
name: fileName,
version: version.id
}, function (err, q) {
if (err) return backoff(err);
q.execWithin(tx, function (err) {
afterFileExists(err, newId);
});

})
}
else return afterFileExists(null, file.id);
});
function afterFileExists(err, fileId) {
if (err) return backoff(err);
FileVersion.insert({fileId: fileId,versionId: version.id})
.execWithin(tx, function (err) {
if (err) return backoff(err);
File.whereUpdate({id: fileId}, {
version: version.id
}).execWithin(tx, function (err) {
if (err) return backoff(err);
tx.commit(done);
});
})
}
});
});
}
45 changes: 45 additions & 0 deletions doxbee-sequential/promises-bluebird-generator.js
@@ -0,0 +1,45 @@
global.useBluebird = true;
global.useQ = false;
var bluebird = require('bluebird');
require('../lib/fakesP');

module.exports = bluebird.coroutine(function* upload(stream, idOrPath, tag, done) {
try {
var blob = blobManager.create(account);
var tx = db.begin();
var blobId = yield blob.put(stream);
var file = yield self.byUuidOrPath(idOrPath).get();

var previousId = file ? file.version : null;
version = {
userAccountId: userAccount.id,
date: new Date(),
blobId: blobId,
creatorId: userAccount.id,
previousId: previousId,
};
version.id = Version.createHash(version);
yield Version.insert(version).execWithin(tx);
if (!file) {
var splitPath = idOrPath.split('/');
var fileName = splitPath[splitPath.length - 1];
file = {
id: uuid.v1(),
userAccountId: userAccount.id,
name: fileName,
version: version.id
}
var query = yield self.createQuery(idOrPath, file);
yield query.execWithin(tx);
}
yield FileVersion.insert({fileId: file.id, versionId: version.id})
.execWithin(tx);
yield File.whereUpdate({id: file.id}, {version: version.id})
.execWithin(tx);
tx.commit();
done();
} catch (err) {
tx.rollback();
done(err);
}
});
59 changes: 59 additions & 0 deletions doxbee-sequential/promises-bluebird.js
@@ -0,0 +1,59 @@
global.useBluebird = true;
global.useQ = false;
var bluebird = require('bluebird');
require('../lib/fakesP');

module.exports = function upload(stream, idOrPath, tag, done) {
var blob = blobManager.create(account);
var tx = db.begin();
var blobIdP = blob.put(stream);
var fileP = self.byUuidOrPath(idOrPath).get();
var version, fileId, file;

bluebird.join(blobIdP, fileP, function(blobId, fileV) {
file = fileV;
var previousId = file ? file.version : null;
version = {
userAccountId: userAccount.id,
date: new Date(),
blobId: blobId,
creatorId: userAccount.id,
previousId: previousId,
};
version.id = Version.createHash(version);
return Version.insert(version).execWithin(tx);
}).then(function() {
if (!file) {
var splitPath = idOrPath.split('/');
var fileName = splitPath[splitPath.length - 1];
var newId = uuid.v1();
return self.createQuery(idOrPath, {
id: newId,
userAccountId: userAccount.id,
name: fileName,
version: version.id
}).then(function(q) {
return q.execWithin(tx);
}).then(function() {
return newId;
});
} else {
return file.id;
}
}).then(function(fileIdV) {
fileId = fileIdV;
return FileVersion.insert({
fileId: fileId,
versionId: version.id
}).execWithin(tx);
}).then(function() {
return File.whereUpdate({id: fileId}, {version: version.id})
.execWithin(tx);
}).then(function() {
tx.commit();
return done();
}, function(err) {
tx.rollback();
return done(err);
});
}
67 changes: 67 additions & 0 deletions doxbee-sequential/promises-es2015-native.js
@@ -0,0 +1,67 @@
global.useNative = true;

try {
if (Promise.race.toString() !== 'function race() { [native code] }')
throw 0;
} catch (e) {
throw new Error("No ES6 promises available");
}

require('../lib/fakesP');

module.exports = function upload(stream, idOrPath, tag, done) {
var blob = blobManager.create(account);
var tx = db.begin();
var blobIdP = blob.put(stream);
var fileP = self.byUuidOrPath(idOrPath).get();
var version, fileId, file;

Promise.all([blobIdP, fileP]).then(function(result) {
var blobId = result[0];
var fileV = result[1];
file = fileV;
var previousId = file ? file.version : null;
version = {
userAccountId: userAccount.id,
date: new Date(),
blobId: blobId,
creatorId: userAccount.id,
previousId: previousId,
};
version.id = Version.createHash(version);
return Version.insert(version).execWithin(tx);
}).then(function() {
if (!file) {
var splitPath = idOrPath.split('/');
var fileName = splitPath[splitPath.length - 1];
var newId = uuid.v1();
return self.createQuery(idOrPath, {
id: newId,
userAccountId: userAccount.id,
name: fileName,
version: version.id
}).then(function(q) {
return q.execWithin(tx);
}).then(function() {
return newId;
});
} else {
return file.id;
}
}).then(function(fileIdV) {
fileId = fileIdV;
return FileVersion.insert({
fileId: fileId,
versionId: version.id
}).execWithin(tx);
}).then(function() {
return File.whereUpdate({id: fileId}, {version: version.id})
.execWithin(tx);
}).then(function() {
tx.commit();
return done();
}, function(err) {
tx.rollback();
return done(err);
});
}
30 changes: 30 additions & 0 deletions lib/dummy.js
@@ -0,0 +1,30 @@
// A typical node callback function
// with the callback at the Nth position
exports.dummy = function dummy(n) {
return function dummy_n() {
var cb = arguments[n - 1] || function(){};
if (global.asyncTime)
setTimeout(cb, global.asyncTime || 100);
else
process.nextTick(cb);
}
}

// A throwing callback function
exports.dummyt = function dummyt(n) {
return function dummy_throwing_n() {
var cb = arguments[n - 1];
if (global.testThrow)
throw(new Error("Exception happened"));
setTimeout(function throwTimeout() {
if (global.testThrowAsync) {
throw(new Error("Exception happened"));
} else if (global.testError) {
return cb(new Error("Error happened"));
}
else cb();
}, global.asyncTime || 100);
}
}


0 comments on commit ea5c347

Please sign in to comment.