UNPKG

@zkochan/pnpm

Version:

Fast, disk space efficient package manager

134 lines 6.08 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const logger_1 = require("@pnpm/logger"); const server_1 = require("@pnpm/server"); const store_path_1 = require("@pnpm/store-path"); const delay_1 = require("delay"); const fs = require("mz/fs"); const path = require("path"); const createStore_1 = require("./createStore"); const pnpmPkgJson_1 = require("./pnpmPkgJson"); const runServerInBackground_1 = require("./runServerInBackground"); const serverConnectionInfoDir_1 = require("./serverConnectionInfoDir"); function cached(storeControllerCache, opts) { return __awaiter(this, void 0, void 0, function* () { const sp = yield store_path_1.default(opts.prefix, opts.store); if (!storeControllerCache.has(sp)) { storeControllerCache.set(sp, createStoreController(opts)); } return yield storeControllerCache.get(sp); }); } exports.cached = cached; function createStoreController(opts) { return __awaiter(this, void 0, void 0, function* () { const store = yield store_path_1.default(opts.prefix, opts.store); const connectionInfoDir = serverConnectionInfoDir_1.default(store); const serverJsonPath = path.join(connectionInfoDir, 'server.json'); let serverJson = yield tryLoadServerJson({ serverJsonPath, shouldRetryOnNoent: false }); if (serverJson !== null) { if (serverJson.pnpmVersion !== pnpmPkgJson_1.default.version) { logger_1.default.warn({ message: `The store server runs on pnpm v${serverJson.pnpmVersion}. It is recommended to connect with the same version (current is v${pnpmPkgJson_1.default.version})`, prefix: opts.prefix, }); } logger_1.default.info({ message: 'A store server is running. All store manipulations are delegated to it.', prefix: opts.prefix, }); return { ctrl: yield server_1.connectStoreController(serverJson.connectionOptions), path: store, }; } if (opts.useRunningStoreServer) { const err = new Error('No store server is running.'); err['code'] = 'ERR_PNPM_NO_STORE_SERVER'; // tslint:disable-line:no-string-literal throw err; } if (opts.useStoreServer) { runServerInBackground_1.default(store); serverJson = yield tryLoadServerJson({ serverJsonPath, shouldRetryOnNoent: true }); logger_1.default.info({ message: 'A store server has been started. To stop it, use \`pnpm server stop\`', prefix: opts.prefix, }); return { ctrl: yield server_1.connectStoreController(serverJson.connectionOptions), path: store, }; } return yield createStore_1.default(Object.assign(opts, { store, })); }); } exports.default = createStoreController; function tryLoadServerJson(options) { return __awaiter(this, void 0, void 0, function* () { let beforeFirstAttempt = true; const startHRTime = process.hrtime(); while (true) { if (!beforeFirstAttempt) { const elapsedHRTime = process.hrtime(startHRTime); // Time out after 10 seconds of waiting for the server to start, assuming something went wrong. // E.g. server got a SIGTERM or was otherwise abruptly terminated, server has a bug or a third // party is interfering. if (elapsedHRTime[0] >= 10) { // Delete the file in an attempt to recover from this bad state. try { yield fs.unlink(options.serverJsonPath); } catch (error) { if (error.code !== 'ENOENT') { throw error; } // Either the server.json was manually removed or another process already removed it. } return null; } // Poll for server startup every 200 milliseconds. yield delay_1.default(200); } beforeFirstAttempt = false; let serverJsonStr; try { serverJsonStr = yield fs.readFile(options.serverJsonPath, 'utf8'); } catch (error) { if (error.code !== 'ENOENT') { throw error; } if (!options.shouldRetryOnNoent) { return null; } continue; } let serverJson; try { serverJson = JSON.parse(serverJsonStr); } catch (error) { // Server is starting or server.json was modified by a third party. // We assume the best case and retry. continue; } if (serverJson === null) { // Our server should never write null to server.json, even though it is valid json. throw new Error('server.json was modified by a third party'); } return serverJson; } }); } exports.tryLoadServerJson = tryLoadServerJson; //# sourceMappingURL=createStoreController.js.map