Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

Commit

Permalink
sync missing star users. fixed #235
Browse files Browse the repository at this point in the history
* Sync star users on pkg sync flow
* Show star users on registry.show
* Show star users on web package show
* Need to create new table module_star
  • Loading branch information
fengmk2 committed Mar 4, 2014
1 parent 0b7997e commit 261ffda
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 27 deletions.
7 changes: 7 additions & 0 deletions common/mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Module dependencies.
*/

var thunkify = require('thunkify-wrap');
var ready = require('ready');
var mysql = require('mysql');
var config = require('../config');
Expand All @@ -35,6 +36,10 @@ var pool = mysql.createPool({
exports.pool = pool;

exports.query = function (sql, values, cb) {
if (typeof values === 'function') {
cb = values;
values = null;
}
pool.query(sql, values, function (err, rows) {
cb(err, rows);
});
Expand All @@ -59,6 +64,8 @@ exports.escape = function (val) {

ready(exports);

thunkify(exports);

function init() {
exports.query('show tables', function (err, rows) {
if (err) {
Expand Down
30 changes: 22 additions & 8 deletions controllers/registry/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,27 @@ var DownloadTotal = require('../../proxy/download');
var SyncModuleWorker = require('../../proxy/sync_module_worker');
var logger = require('../../common/logger');
var ModuleDeps = require('../../proxy/module_deps');
var ModuleStar = require('../../proxy/module_star');

/**
* show all version of a module
*/
exports.show = function *(next) {
var name = this.params.name;

var r = yield [Module.listTags(name), Module.listByName(name)];
var r = yield [
Module.listTags(name),
Module.listByName(name),
ModuleStar.listUsers(name)
];
var tags = r[0];
var rows = r[1];
var users = r[2];
var userMap = {};
for (var i = 0; i < users.length; i++) {
userMap[users[i]] = true;
}
users = userMap;

debug('show module, user: %s, allowSync: %s, isAdmin: %s',
this.session.name, this.session.allowSync, this.session.isAdmin);
Expand Down Expand Up @@ -108,14 +119,16 @@ exports.show = function *(next) {
}
}

var ts = {
modified: modifiedTime,
created: createdTime,
};
for (var t in times) {
ts[t] = times[t];
if (modifiedTime && createdTime) {
var ts = {
modified: modifiedTime,
created: createdTime,
};
for (var t in times) {
ts[t] = times[t];
}
times = ts;
}
times = ts;

if (!latestMod) {
latestMod = nextMod || rows[0];
Expand All @@ -140,6 +153,7 @@ exports.show = function *(next) {
"dist-tags": distTags,
maintainers: pkg.maintainers,
time: times,
users: users,
author: pkg.author,
repository: pkg.repository,
versions: versions,
Expand Down
6 changes: 5 additions & 1 deletion controllers/web/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var sync = require('../sync');
var Log = require('../../proxy/module_log');
var ModuleDeps = require('../../proxy/module_deps');
var setDownloadURL = require('../../lib/common').setDownloadURL;
var ModuleStar = require('../../proxy/module_star');

exports.display = function *(next) {
var params = this.params;
Expand All @@ -47,20 +48,23 @@ exports.display = function *(next) {
var r = yield [
Module[getPackageMethod].apply(Module, getPackageArgs),
down.total(name),
ModuleDeps.list(name)
ModuleDeps.list(name),
ModuleStar.listUsers(name),
];
var pkg = r[0];
var download = r[1];
var dependents = (r[2] || []).map(function (item) {
return item.deps;
});
var users = r[3];

if (!pkg || !pkg.package) {
return yield next;
}

pkg.package.fromNow = moment(pkg.publish_time).fromNow();
pkg = pkg.package;
pkg.users = users;
pkg.readme = marked(pkg.readme || '');
if (!pkg.readme) {
pkg.readme = pkg.description || '';
Expand Down
10 changes: 10 additions & 0 deletions docs/db.sql
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ CREATE TABLE `module_keyword` (
KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module keyword';

CREATE TABLE `module_star` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',
`gmt_create` datetime NOT NULL COMMENT 'create time',
`user` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'user name',
`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'module name',
PRIMARY KEY (`id`),
UNIQUE KEY `user_module_name` (`user`,`name`),
KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module star';

CREATE TABLE `module` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',
`gmt_create` datetime NOT NULL COMMENT 'create time',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
},
"devDependencies": {
"autod": ">=0.0.13",
"co": "3.0.4",
"contributors": "*",
"cov": "*",
"istanbul": "git://github.com/gotwarlost/istanbul.git#harmony",
Expand Down
47 changes: 47 additions & 0 deletions proxy/module_star.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**!
* cnpmjs.org - proxy/module_star.js
*
* Copyright(c) cnpmjs.org and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <[email protected]> (http://fengmk2.github.com)
*/

'use strict';

/**
* Module dependencies.
*/

var mysql = require('../common/mysql');

exports.add = function *add(name, user) {
var sql = 'INSERT INTO module_star(name, user) VALUES(?, ?);';
try {
yield mysql.query(sql, [name, user]);
} catch (err) {
if (err.code !== 'ER_DUP_ENTRY') {
throw err;
}
}
};

exports.remove = function *(name, user) {
var sql = 'DELETE FROM module_star WHERE name = ? AND user = ?;';
return yield mysql.query(sql, [name, user]);
};

exports.listUsers = function *(name) {
var sql = 'SELECT user FROM module_star WHERE name = ?;';
return (yield mysql.query(sql, [name])).map(function (r) {
return r.user;
});
};

exports.listUserModules = function *(user) {
var sql = 'SELECT name FROM module_star WHERE user = ?;';
return (yield mysql.query(sql, [user])).map(function (r) {
return r.name;
});
};
78 changes: 73 additions & 5 deletions proxy/sync_module_worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Module dependencies.
*/

var co = require('co');
var thunkify = require('thunkify-wrap');
var debug = require('debug')('cnpmjs.org:proxy:sync_module_worker');
var EventEmitter = require('events').EventEmitter;
Expand All @@ -33,6 +34,7 @@ var Module = require('./module');
var ModuleDeps = require('./module_deps');
var Log = require('./module_log');
var config = require('../config');
var ModuleStar = require('./module_star');

function SyncModuleWorker(options) {
EventEmitter.call(this);
Expand Down Expand Up @@ -145,6 +147,36 @@ SyncModuleWorker.prototype.next = function (concurrencyId) {
});
};

function _listStarUsers(modName, callback) {
co(function *() {
var users;
var err;
try {
users = yield ModuleStar.listUsers(modName);
var userMap = {};
for (var i = 0; i < users.length; i++) {
userMap[users[i]] = true;
}
users = userMap;
} catch (e) {
err = e;
}
callback(err, users);
})();
}

function _addStar(modName, username, callback) {
co(function *() {
var err;
try {
yield ModuleStar.add(modName, username);
} catch (e) {
err = e;
}
callback(err);
})();
};

SyncModuleWorker.prototype._sync = function (name, pkg, callback) {
var username = this.username;
var that = this;
Expand Down Expand Up @@ -194,12 +226,24 @@ SyncModuleWorker.prototype._sync = function (name, pkg, callback) {
ep.emit('existsTags', tags);
}));

_listStarUsers(name, ep.done('existsStarUsers'));

var missingVersions = [];
var missingTags = [];
var missingDescriptions = [];
var missingReadmes = [];
var missingStarUsers = [];

ep.all('existsMap', 'existsTags', 'existsStarUsers', function (map, tags, existsStarUsers) {
var starUsers = pkg.users || {};
for (var k in starUsers) {
if (!existsStarUsers[k]) {
missingStarUsers.push(k);
}
}

that.log(' [%s] found %d missing star users', name, missingStarUsers.length);

ep.all('existsMap', 'existsTags', function (map, tags) {
var times = pkg.time || {};
pkg.versions = pkg.versions || {};
var versionNames = Object.keys(times);
Expand Down Expand Up @@ -300,7 +344,7 @@ SyncModuleWorker.prototype._sync = function (name, pkg, callback) {
return a.publish_time - b.publish_time;
});
missingVersions = versions;
that.log(' [%s] %d versions', name, versions.length);
that.log(' [%s] %d versions need to sync', name, versions.length);
ep.emit('syncModule', missingVersions.shift());
});

Expand All @@ -318,13 +362,16 @@ SyncModuleWorker.prototype._sync = function (name, pkg, callback) {

var nextVersion = missingVersions.shift();
if (!nextVersion) {
ep.unbind('syncModule');
return ep.emit('syncDone', result);
}

// next
ep.emit('syncModule', nextVersion);
});
});

ep.on('syncDone', function () {
ep.once('syncDone', function () {
if (missingDescriptions.length === 0) {
return ep.emit('descriptionDone');
}
Expand All @@ -346,7 +393,7 @@ SyncModuleWorker.prototype._sync = function (name, pkg, callback) {
});
});

ep.on('syncDone', function () {
ep.once('syncDone', function () {
if (missingTags.length === 0) {
return ep.emit('tagDone');
}
Expand Down Expand Up @@ -387,7 +434,28 @@ SyncModuleWorker.prototype._sync = function (name, pkg, callback) {
});
});

ep.all('tagDone', 'descriptionDone', 'readmeDone', function () {
ep.once('syncDone', function () {
if (missingStarUsers.length === 0) {
return ep.emit('starUserDone');
}

that.log(' [%s] saving %d star users', name, missingStarUsers.length);
missingStarUsers.forEach(function (username) {
_addStar(name, username, function (err) {
if (err) {
that.log(' add star user error, %s', err);
}
ep.emitLater('addStarUser');
});
});

ep.after('addStarUser', missingStarUsers.length, function () {
ep.emit('starUserDone');
});
});

ep.all('tagDone', 'descriptionDone', 'readmeDone', 'starUserDone',
function () {
// TODO: set latest version
callback(null, versionNames);
});
Expand Down
7 changes: 4 additions & 3 deletions test/controllers/registry/module.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe('controllers/registry/module.test.js', function () {
res.body.should.have.keys('_id', '_rev', 'name', 'description',
'versions', 'dist-tags', 'readme', 'maintainers',
'time', 'author', 'repository', '_attachments',
'readmeFilename', 'homepage', 'bugs', 'license');
'users', 'readmeFilename', 'homepage', 'bugs', 'license');
res.body.name.should.equal('cnpmjs.org');
res.body.versions[Object.keys(res.body.versions)[0]]
.dist.tarball.should.include('/cnpmjs.org/download');
Expand All @@ -105,7 +105,8 @@ describe('controllers/registry/module.test.js', function () {
etag = res.headers.etag;
res.body.should.have.keys('_id', '_rev', 'name', 'description',
'versions', 'dist-tags', 'readme', 'maintainers',
'time', 'author', 'repository', '_attachments');
'time', 'author', 'repository', '_attachments',
'users', 'readmeFilename', 'homepage', 'bugs', 'license');
res.body.name.should.equal('cnpmjs.org');
res.body.versions[Object.keys(res.body.versions)[0]].dist.tarball.should.include('/cnpmjs.org/download');
done();
Expand Down Expand Up @@ -243,7 +244,7 @@ describe('controllers/registry/module.test.js', function () {
.expect(200, function (err, res) {
should.not.exist(err);
res.body.should.have.keys('_id', '_rev', 'name', 'description', 'versions', 'dist-tags',
'readme', 'maintainers', 'time', '_attachments');
'readme', 'maintainers', 'time', '_attachments', 'users');
res.body.versions.should.eql({});
res.body.time.should.eql({});
res.body['dist-tags'].should.eql({});
Expand Down
Loading

0 comments on commit 261ffda

Please sign in to comment.