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

Commit 5b09d97

Browse files
committed
Merge pull request #452 from cnpm/sync-upstream-package
support sync upstream first. fixed #451
2 parents 7b6c757 + 763224b commit 5b09d97

File tree

5 files changed

+118
-17
lines changed

5 files changed

+118
-17
lines changed

config/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ var config = {
133133
// registry url name
134134
registryHost: 'r.cnpmjs.org',
135135

136-
137136
/**
138137
* registry mode config
139138
*/
@@ -170,8 +169,10 @@ var config = {
170169
disturl: 'http://nodejs.org/dist',
171170
syncDist: false,
172171

173-
// sync source
172+
// sync source, upstream registry
174173
sourceNpmRegistry: 'http://registry.npm.taobao.org',
174+
// upstream registry is base on cnpm/cnpmjs.org or not
175+
sourceNpmRegistryIsCNpm: false,
175176

176177
// if install return 404, try to sync from source registry
177178
syncByInstall: true,

package.json

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313
"agentkeepalive": "~1.2.0",
1414
"bluebird": "~2.3.2",
1515
"bytes": "~1.0.0",
16-
"cfork": "~1.1.0",
16+
"cfork": "~1.1.1",
1717
"cheerio": "~0.17.0",
1818
"co": "~3.1.0",
19-
"co-defer": "~0.1.0",
19+
"co-defer": "~0.1.1",
2020
"co-gather": "~0.0.1",
2121
"co-read": "~0.1.0",
2222
"co-redis": "~1.1.0",
23+
"co-sleep": "~0.0.1",
2324
"co-write": "~0.3.0",
2425
"copy-to": "~1.0.1",
2526
"debug": "~2.0.0",
@@ -30,25 +31,25 @@
3031
"graceful": "~0.1.0",
3132
"gravatar": "~1.0.6",
3233
"humanize-number": "~0.0.2",
33-
"koa": "~0.10.0",
34+
"koa": "~0.12.1",
3435
"koa-limit": "~1.0.2",
3536
"koa-markdown": "~0.0.3",
36-
"koa-middlewares": "~1.2.0",
37+
"koa-middlewares": "~1.4.0",
3738
"marked": "~0.3.2",
3839
"mime": "~1.2.11",
3940
"mini-logger": "~0.3.0",
4041
"mkdirp": "~0.5.0",
41-
"moment": "~2.8.2",
42+
"moment": "~2.8.3",
4243
"ms": "~0.6.2",
4344
"multiline": "~1.0.0",
44-
"mysql": "~2.4.3",
45+
"mysql": "~2.5.1",
4546
"nodemailer": "0.7.1",
4647
"ready": "~0.1.1",
4748
"redis": "~0.12.1",
48-
"semver": "~3.0.1",
49+
"semver": "~4.0.0",
4950
"thunkify-wrap": "~1.0.2",
50-
"urllib": "~1.4.1",
51-
"utility": "~1.1.0"
51+
"urllib": "~1.5.2",
52+
"utility": "~1.2.0"
5253
},
5354
"devDependencies": {
5455
"autod": "~0.2.0",

proxy/sync_module_worker.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ var util = require('util');
2525
var fs = require('fs');
2626
var path = require('path');
2727
var crypto = require('crypto');
28+
var sleep = require('co-sleep');
2829
var urllib = require('../common/urllib');
2930
var utility = require('utility');
3031
var ms = require('ms');
@@ -140,6 +141,64 @@ SyncModuleWorker.prototype._doneOne = function* (concurrencyId, name, success) {
140141
});
141142
};
142143

144+
SyncModuleWorker.prototype.syncUpstream = function* (name) {
145+
var url = config.sourceNpmRegistry + '/' + name + '/sync';
146+
var r = yield urllib.request(url, {
147+
method: 'put',
148+
timeout: 20000,
149+
headers: {
150+
'content-length': 0
151+
},
152+
dataType: 'json'
153+
});
154+
155+
if (r.status !== 201 || !r.data.ok) {
156+
return this.log('sync upstream %s error, status: %s, response: %j',
157+
url, r.status, r.data);
158+
}
159+
160+
var logURL = url + '/log/' + r.data.logId;
161+
var offset = 0;
162+
this.log('Syncing upstream %s', logURL);
163+
164+
var count = 0;
165+
while (true) {
166+
count++;
167+
var synclogURL = logURL + '?offset=' + offset;
168+
var rs = yield urllib.request(synclogURL, {
169+
timeout: 20000,
170+
dataType: 'json'
171+
});
172+
173+
if (rs.status !== 200 || !rs.data.ok) {
174+
this.log('sync upstream %s error, status: %s, response: %j',
175+
synclogURL, rs.status, rs.data);
176+
break;
177+
}
178+
179+
var data = rs.data;
180+
var syncDone = false;
181+
if (data.log.indexOf('[done] Sync') >= 0) {
182+
syncDone = true;
183+
data.log = data.log.replace('[done] Sync', '[upstream sync done]') +
184+
'\n-------------------------------------------------------------\n';
185+
}
186+
this.log(data.log);
187+
188+
if (syncDone) {
189+
break;
190+
}
191+
if (count >= 30) {
192+
this.log('sync upstream %s fail, give up %s',
193+
logURL, '\n-------------------------------------------------------------\n');
194+
break;
195+
}
196+
197+
offset += data.log.split('\n').length;
198+
yield sleep(2000);
199+
}
200+
};
201+
143202
SyncModuleWorker.prototype.next = function *(concurrencyId) {
144203
var name = this.names.shift();
145204
if (!name) {
@@ -150,6 +209,12 @@ SyncModuleWorker.prototype.next = function *(concurrencyId) {
150209
that.syncingNames[name] = true;
151210
var pkg = null;
152211
var status = 0;
212+
213+
// sync upstream
214+
if (config.sourceNpmRegistryIsCNpm) {
215+
yield* this.syncUpstream(name);
216+
}
217+
153218
// get from npm
154219
try {
155220
var result = yield npm.request('/' + name);

test/proxy/sync_module_worker.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@
1515
*/
1616

1717
var should = require('should');
18+
var mm = require('mm');
1819
var SyncModuleWorker = require('../../proxy/sync_module_worker');
1920
var mysql = require('../../common/mysql');
2021
var Log = require('../../proxy/module_log');
22+
var config = require('../../config');
2123

2224
describe('proxy/sync_module_worker.test.js', function () {
25+
afterEach(mm.restore);
26+
2327
it('should start a sync worker', function (done) {
2428
Log.create({
2529
name: 'mk2testmodule',
@@ -38,6 +42,25 @@ describe('proxy/sync_module_worker.test.js', function () {
3842
});
3943
});
4044

45+
it('should sync upstream first', function (done) {
46+
mm(config, 'sourceNpmRegistryIsCNpm', true);
47+
Log.create({
48+
name: 'mk2testmodule',
49+
username: 'fengmk2',
50+
}, function (err, result) {
51+
should.not.exist(err);
52+
result.id.should.above(0);
53+
var worker = new SyncModuleWorker({
54+
logId: result.id,
55+
name: 'mk2testmodule',
56+
username: 'fengmk2'
57+
});
58+
59+
worker.start();
60+
worker.on('end', done);
61+
});
62+
});
63+
4164
it('should start a sync worker with names and noDep', function (done) {
4265
var worker = new SyncModuleWorker({
4366
name: ['mk2testmodule'],
@@ -90,4 +113,17 @@ describe('proxy/sync_module_worker.test.js', function () {
90113
done();
91114
});
92115
});
116+
117+
describe('syncUpstream()', function () {
118+
it('should sync upstream work', function* () {
119+
var worker = new SyncModuleWorker({
120+
name: ['tnpm'],
121+
username: 'fengmk2'
122+
});
123+
yield [
124+
worker.syncUpstream('tnpm'),
125+
worker.syncUpstream('pedding'),
126+
];
127+
});
128+
});
93129
});

view/web/sync.html

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ <h2>Log</h2>
5050

5151
var offset = 0;
5252
var logs = '';
53-
var successFlag = false;
54-
var failFlag = false;
53+
var syncDone = false;
5554
var hasFail = false;
5655
function getSyncLog(id) {
5756
$.ajax({
@@ -65,17 +64,16 @@ <h2>Log</h2>
6564
offset += data.log.split('\n').length;
6665
logs = logs + '\n' + data.log;
6766

68-
if (data.log.indexOf('Success: [') >= 0) {
69-
successFlag = true;
67+
if (data.log.indexOf('[done] Sync') >= 0) {
68+
syncDone = true;
7069
}
7170
if (data.log.indexOf('Fail: [') >= 0) {
72-
failFlag = true;
7371
var failInfo = data.log.match(/Fail: \[ (.*?) \]/);
7472
if (failInfo && failInfo[1]) {
7573
hasFail = true;
7674
}
7775
}
78-
if (successFlag && failFlag) {
76+
if (syncDone) {
7977
logs += '\nSync package ' + name + ' complete!';
8078
if (hasFail) {
8179
logs += ' But some packages sync failed, you can refresh to sync again.';

0 commit comments

Comments
 (0)