UNPKG

@clickup/pg-mig

Version:

PostgreSQL schema migration tool with microsharding and clustering support

111 lines 4.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Worker = void 0; const async_rwlock_1 = require("async-rwlock"); const await_semaphore_1 = require("await-semaphore"); const promiseAllMap_1 = require("./helpers/promiseAllMap"); const rwLock = new async_rwlock_1.RWLock(); class Worker { constructor(chainsQueue, semaphores) { this.chainsQueue = chainsQueue; this.semaphores = semaphores; this.succeededMigrations = 0; this.errorMigrations = []; this.warningMigrations = []; this.curDest = null; this.curMigration = null; this.curLine = null; } getSucceededMigrations() { return this.succeededMigrations; } getErrorMigrations() { return this.errorMigrations; } getWarningMigrations() { return this.warningMigrations; } getCurDest() { return this.curDest; } getCurMigration() { return this.curMigration; } getCurLine() { return this.curLine; } async run(onChange) { while (this.chainsQueue.length > 0) { const chain = this.chainsQueue.shift(); for (const migration of chain.migrations) { this.curDest = chain.dest; this.curMigration = migration; this.curLine = null; onChange(); const interval = setInterval(() => onChange(), 200); // for long-running migrations try { const { warning } = await this.processMigration(chain.dest, migration); this.succeededMigrations++; if (warning) { this.warningMigrations.push({ dest: chain.dest, migration, payload: warning, }); } } catch (error) { this.errorMigrations.push({ dest: chain.dest, migration, payload: error, }); break; } finally { clearInterval(interval); onChange(); } } } this.curDest = null; this.curMigration = null; this.curLine = null; onChange(); } async processMigration(dest, migration) { this.curLine = "waiting to satisfy parallelism limits..."; const releases = await (0, promiseAllMap_1.promiseAllMap)([ migration.file.runAlone ? rwLock.writeLock().then(() => rwLock.unlock.bind(rwLock)) : rwLock.readLock().then(() => rwLock.unlock.bind(rwLock)), this.acquireSemaphore(migration.file.parallelismGlobal, migration.version), this.acquireSemaphore(migration.file.parallelismPerHost, dest.host + ":" + migration.version), ], async (p) => p); try { this.curLine = null; const res = await dest.runFile(migration.file.fileName, migration.newVersions, migration.file.vars, (proc) => { this.curLine = proc.getLastOutLine(); }); if (res.getCode()) { throw res.getOut().trimEnd(); } if (migration.file.delay > 0) { await new Promise((resolve) => setTimeout(resolve, migration.file.delay)); } return { warning: res.getWarning() }; } finally { releases.forEach((release) => release()); } } async acquireSemaphore(maxWorkers, key) { let semaphore = this.semaphores[key]; if (!semaphore) { semaphore = this.semaphores[key] = new await_semaphore_1.Semaphore(maxWorkers); } return semaphore.acquire(); } } exports.Worker = Worker; //# sourceMappingURL=Worker.js.map