0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-30 22:34:10 -05:00

refactor: remove locking files from local-storage, update to minor versions local-storage and types

This commit is contained in:
Juan Picado @jotadeveloper 2017-12-21 09:44:57 +01:00 committed by juanpicado
parent 2ae80dd15e
commit 4f5443d857
4 changed files with 43 additions and 84 deletions

View file

@ -19,7 +19,7 @@ ADD . $APPDIR
ENV NODE_ENV=production
RUN npm config set registry http://registry.npmjs.org/ && \
yarn global add -s flow-bin@0.60.0 && \
yarn global add -s flow-bin@0.52.0 && \
yarn install --production=false && \
yarn run lint && \
yarn run code:build && \

View file

@ -16,9 +16,9 @@
},
"dependencies": {
"@verdaccio/file-locking": "^0.0.5",
"@verdaccio/local-storage": "^0.0.14",
"@verdaccio/local-storage": "^0.1.0",
"@verdaccio/streams": "^0.0.2",
"@verdaccio/types": "^0.0.10",
"@verdaccio/types": "^0.1.0",
"JSONStream": "^1.1.1",
"apache-md5": "^1.1.2",
"async": "^2.6.0",

View file

@ -14,7 +14,7 @@ import async from 'async';
import * as Utils from './utils';
import {
generatePackageTemplate, normalizePackage, generateRevision, cleanUpReadme,
fileExist, noSuchFile, resourceNotAvailable, DEFAULT_REVISION, pkgFileName,
fileExist, noSuchFile, DEFAULT_REVISION, pkgFileName,
} from './storage-utils';
import LocalDatabase from '@verdaccio/local-storage';
@ -30,8 +30,8 @@ import type {
Logger,
} from '@verdaccio/types';
import type {
ILocalFS,
ILocalData,
IPackageStorage,
} from '@verdaccio/local-storage';
/**
@ -50,13 +50,13 @@ class LocalStorage implements IStorage {
}
addPackage(name: string, pkg: Package, callback: Callback) {
const storage: ILocalFS = this._getLocalStorage(name);
const storage: IPackageStorage = this._getLocalStorage(name);
if (_.isNil(storage)) {
return callback( Utils.ErrorCode.get404('this package cannot be added'));
}
storage.createJSON(pkgFileName, generatePackageTemplate(name), (err) => {
storage.createPackage(pkgFileName, generatePackageTemplate(name), (err) => {
if (_.isNull(err) === false && err.code === fileExist) {
return callback( Utils.ErrorCode.get409());
}
@ -77,13 +77,13 @@ class LocalStorage implements IStorage {
* @return {Function}
*/
removePackage(name: string, callback: Callback) {
let storage: ILocalFS = this._getLocalStorage(name);
let storage: IPackageStorage = this._getLocalStorage(name);
if (_.isNil(storage)) {
return callback( Utils.ErrorCode.get404());
}
storage.readJSON(pkgFileName, (err, data) => {
storage.readPackage(pkgFileName, (err, data) => {
if (_.isNil(err) === false) {
if (err.code === noSuchFile) {
return callback( Utils.ErrorCode.get404());
@ -101,7 +101,7 @@ class LocalStorage implements IStorage {
return callback(Utils.ErrorCode.get422(removeFailed.message));
}
storage.deleteJSON(pkgFileName, (err) => {
storage.deletePackage(pkgFileName, (err) => {
if (err) {
return callback(err);
}
@ -367,7 +367,7 @@ class LocalStorage implements IStorage {
const storage = this._getLocalStorage(name);
if (storage) {
storage.deleteJSON(filename, callback);
storage.deletePackage(filename, callback);
}
});
}
@ -410,7 +410,7 @@ class LocalStorage implements IStorage {
return uploadStream;
}
const writeStream = storage.createWriteStream(filename);
const writeStream = storage.writeTarball(filename);
writeStream.on('error', (err) => {
if (err.code === fileExist) {
@ -476,7 +476,7 @@ class LocalStorage implements IStorage {
getTarball(name: string, filename: string) {
assert(Utils.validate_name(filename));
const storage: ILocalFS = this._getLocalStorage(name);
const storage: IPackageStorage = this._getLocalStorage(name);
if (_.isNil(storage)) {
return this._createFailureStreamResponse();
@ -506,9 +506,9 @@ class LocalStorage implements IStorage {
* @private
* @return {ReadTarball}
*/
_streamSuccessReadTarBall(storage: ILocalFS, filename: string) {
_streamSuccessReadTarBall(storage: IPackageStorage, filename: string) {
const stream = new ReadTarball();
const readTarballStream = storage.createReadStream(filename);
const readTarballStream = storage.readTarball(filename);
const e404 = Utils.ErrorCode.get404;
stream.abort = function() {
@ -546,7 +546,7 @@ class LocalStorage implements IStorage {
*/
getPackageMetadata(name: string, callback?: Callback = () => {}): void {
const storage = this._getLocalStorage(name);
const storage: IPackageStorage = this._getLocalStorage(name);
if (_.isNil(storage)) {
return callback( Utils.ErrorCode.get404() );
}
@ -622,12 +622,12 @@ class LocalStorage implements IStorage {
* @param {Object} packageInfo package name.
* @return {Object}
*/
_getLocalStorage(packageInfo: string): any {
const path = this.__getLocalStoragePath(this.config.getMatchedPackagesSpec(packageInfo).storage);
_getLocalStorage(packageInfo: string): IPackageStorage {
const path: string = this.__getLocalStoragePath(this.config.getMatchedPackagesSpec(packageInfo).storage);
if (_.isNil(path) || path === false) {
if (_.isString(path) === false) {
this.logger.debug( {name: packageInfo}, 'this package has no storage defined: @{name}' );
return null;
return;
}
return this.localData.getPackageStorage(packageInfo, path);
@ -638,8 +638,8 @@ class LocalStorage implements IStorage {
* @param {Object} storage
* @param {Function} callback
*/
_readJSON(storage: ILocalFS, callback: Callback) {
storage.readJSON(pkgFileName, (err, result) => {
_readJSON(storage: IPackageStorage, callback: Callback) {
storage.readPackage(pkgFileName, (err, result) => {
if (err) {
if (err.code === noSuchFile) {
return callback( Utils.ErrorCode.get404() );
@ -669,9 +669,9 @@ class LocalStorage implements IStorage {
/**
* Walks through each package and calls `on_package` on them.
* @param {*} onPackage
* @param {*} on_end
* @param {*} onEnd
*/
_eachPackage(onPackage: Callback, on_end: Callback) {
_eachPackage(onPackage: Callback, onEnd: Callback) {
const storages = {};
storages[this.config.storage] = true;
@ -719,7 +719,7 @@ class LocalStorage implements IStorage {
}
}, cb);
});
}, on_end);
}, onEnd);
}
/**
@ -729,12 +729,12 @@ class LocalStorage implements IStorage {
* @return {Function}
*/
_readCreatePackage(name: string, callback: Callback) {
const storage: ILocalFS = this._getLocalStorage(name);
const storage: IPackageStorage = this._getLocalStorage(name);
if (_.isNil(storage)) {
return this._createNewPackage(name, callback);
}
storage.readJSON(pkgFileName, (err, data) => {
storage.readPackage(pkgFileName, (err, data) => {
// TODO: race condition
if (_.isNil(err) === false) {
if (err.code === noSuchFile) {
@ -766,65 +766,20 @@ class LocalStorage implements IStorage {
}
/**
* This function allows to update the package thread-safely
Algorithm:
1. lock package.json for writing
2. read package.json
3. updateFn(pkg, cb), and wait for cb
4. write package.json.tmp
5. move package.json.tmp package.json
6. callback(err?)
* @param {*} name package name
* @param {*} updateFn function(package, cb) - update function
* @param {*} updateHandler function(package, cb) - update function
* @param {*} callback callback that gets invoked after it's all updated
* @return {Function}
*/
_updatePackage(name: string, updateFn: Callback, callback: Callback) {
const storage: ILocalFS = this._getLocalStorage(name);
_updatePackage(name: string, updateHandler: Callback, callback: Callback) {
const storage: IPackageStorage = this._getLocalStorage(name);
if (!storage) {
return callback( Utils.ErrorCode.get404() );
}
storage.lockAndReadJSON(pkgFileName, (err, json) => {
let locked = false;
// callback that cleans up lock first
const lockCallback = function(err: Error) {
let _args = arguments;
if (locked) {
storage.unlockJSON(pkgFileName, function() {
// ignore any error from the unlock
callback.apply(err, _args);
});
} else {
callback(..._args);
}
};
if (!err) {
locked = true;
}
if (err) {
if (err.code === resourceNotAvailable) {
return lockCallback( Utils.ErrorCode.get503() );
} else if (err.code === noSuchFile) {
return lockCallback( Utils.ErrorCode.get404() );
} else {
return lockCallback(err);
}
}
json = normalizePackage(json);
updateFn(json, (err) => {
if (err) {
return lockCallback(err);
}
this._writePackage(name, json, lockCallback);
});
});
storage.updatePackage(name, updateHandler, this._writePackage.bind(this), normalizePackage,
callback);
}
/**
@ -835,6 +790,14 @@ class LocalStorage implements IStorage {
* @return {Function}
*/
_writePackage(name: string, json: Package, callback: Callback) {
const storage: IPackageStorage = this._getLocalStorage(name);
if (_.isNil(storage)) {
return callback();
}
storage.savePackage(pkgFileName, this._setDefaultRevision(json), callback);
}
_setDefaultRevision(json: Package) {
// calculate revision a la couchdb
if (_.isString(json._rev) === false) {
json._rev = DEFAULT_REVISION;
@ -842,21 +805,17 @@ class LocalStorage implements IStorage {
json._rev = generateRevision(json._rev);
let storage: ILocalFS = this._getLocalStorage(name);
if (_.isNil(storage)) {
return callback();
}
storage.writeJSON(pkgFileName, json, callback);
return json;
}
_deleteAttachments(storage: ILocalFS, attachments: string[], callback: Callback): void {
_deleteAttachments(storage: IPackageStorage, attachments: string[], callback: Callback): void {
const unlinkNext = function(cb) {
if (_.isEmpty(attachments)) {
return cb();
}
const attachment = attachments.shift();
storage.deleteJSON(attachment, function() {
storage.deletePackage(attachment, function() {
unlinkNext(cb);
});
};

BIN
yarn.lock

Binary file not shown.