cnpmcore
Version:
Private NPM Registry for Enterprise
186 lines • 15.1 kB
JavaScript
import os from 'node:os';
import path from 'node:path';
import { InternalServerError } from 'egg/errors';
import { PROXY_CACHE_DIR_NAME } from "../../common/constants.js";
import dayjs from "../../common/dayjs.js";
import { TaskState, TaskType } from "../../common/enum/Task.js";
import { EntityUtil } from "../util/EntityUtil.js";
import { Entity } from "./Entity.js";
import { isPkgManifest } from "./Package.js";
export const HOST_NAME = os.hostname();
export const PID = process.pid;
export class Task extends Entity {
constructor(data) {
super(data);
this.taskId = data.taskId;
this.type = data.type;
this.state = data.state;
this.targetName = data.targetName;
this.authorId = data.authorId;
this.authorIp = data.authorIp;
this.data = data.data;
this.logPath = data.logPath ?? '';
this.logStorePosition = data.logStorePosition ?? '';
this.attempts = data.attempts ?? 0;
this.error = data.error ?? '';
this.bizId = data.bizId;
}
resetLogPath() {
this.logPath = `${path.dirname(this.logPath)}/${dayjs().format('DDHHmm')}-${this.taskId}-${this.attempts}.log`;
this.logStorePosition = '';
}
setExecuteWorker() {
this.data.taskWorker = `${HOST_NAME}:${PID}`;
}
static create(data) {
const newData = EntityUtil.defaultData(data, 'taskId');
return new Task(newData);
}
static createSyncPackage(fullname, options) {
const data = {
type: TaskType.SyncPackage,
state: TaskState.Waiting,
targetName: fullname,
authorId: options?.authorId ?? '',
authorIp: options?.authorIp ?? '',
data: {
// task execute worker
taskWorker: '',
tips: options?.tips,
registryId: options?.registryId ?? '',
skipDependencies: options?.skipDependencies,
syncDownloadData: options?.syncDownloadData,
forceSyncHistory: options?.forceSyncHistory,
force: options?.force,
specificVersions: options?.specificVersions,
},
};
const task = this.create(data);
task.logPath = `/packages/${fullname}/syncs/${dayjs().format('YYYY/MM/DDHHmm')}-${task.taskId}.log`;
return task;
}
static createChangesStream(targetName, registryId = '', since = '') {
const data = {
type: TaskType.ChangesStream,
state: TaskState.Waiting,
targetName,
authorId: `pid_${PID}`,
authorIp: HOST_NAME,
data: {
// task execute worker
taskWorker: '',
registryId,
since,
},
};
return this.create(data);
}
updateSyncData({ lastSince, taskCount, lastPackage }) {
const syncData = this.data;
// 更新任务记录信息
syncData.since = lastSince;
syncData.task_count = (syncData.task_count || 0) + taskCount;
if (taskCount > 0) {
syncData.last_package = lastPackage;
syncData.last_package_created = new Date();
}
}
static createCreateHookTask(hookEvent) {
const data = {
type: TaskType.CreateHook,
state: TaskState.Waiting,
targetName: hookEvent.fullname,
authorId: `pid_${process.pid}`,
authorIp: os.hostname(),
bizId: `CreateHook:${hookEvent.changeId}`,
data: {
// task execute worker
taskWorker: '',
hookEvent,
},
};
const task = this.create(data);
task.logPath = `/packages/${hookEvent.fullname}/hooks/${dayjs().format('YYYY/MM/DDHHmm')}-${task.taskId}.log`;
return task;
}
static createTriggerHookTask(hookEvent, hookId) {
const data = {
type: TaskType.TriggerHook,
state: TaskState.Waiting,
targetName: hookEvent.fullname,
authorId: `pid_${process.pid}`,
bizId: `TriggerHook:${hookEvent.changeId}:${hookId}`,
authorIp: os.hostname(),
data: {
// task execute worker
taskWorker: '',
hookEvent,
hookId,
},
};
const task = this.create(data);
task.logPath = `/packages/${hookEvent.fullname}/hooks/${dayjs().format('YYYY/MM/DDHHmm')}-${task.taskId}.log`;
return task;
}
static createSyncBinary(targetName, lastData) {
const data = {
type: TaskType.SyncBinary,
state: TaskState.Waiting,
targetName,
authorId: `pid_${PID}`,
authorIp: HOST_NAME,
bizId: `SyncBinary:${targetName}`,
data: {
// task execute worker
taskWorker: '',
...lastData,
},
};
const task = this.create(data);
task.logPath = `/binaries/${targetName}/syncs/${dayjs().format('YYYY/MM/DDHHmm')}-${task.taskId}.log`;
return task;
}
needMergeWhenWaiting() {
// 历史任务补偿时,将 shouldNotMerge 设置为 true,避免合并
// 补偿任务单独执行
if (this.data.shouldNotMerge === true) {
return false;
}
// 仅合并二进制镜像与 npm 包
return [TaskType.SyncBinary, TaskType.SyncPackage].includes(this.type);
}
static createUpdateProxyCache(targetName, options) {
if (!isPkgManifest(options.fileType)) {
throw new InternalServerError('should not update package version manifest.');
}
const filePath = `/${PROXY_CACHE_DIR_NAME}/${options.fullname}/${options.fileType}`;
const data = {
type: TaskType.UpdateProxyCache,
state: TaskState.Waiting,
targetName,
authorId: `pid_${PID}`,
authorIp: HOST_NAME,
data: {
taskWorker: '',
fullname: options.fullname,
version: options?.version,
fileType: options.fileType,
filePath,
},
};
const task = this.create(data);
task.logPath = `/${PROXY_CACHE_DIR_NAME}/${options.fullname}/update-manifest-log/${options.fileType.split('.json')[0]}-${dayjs().format('YYYY/MM/DDHHmm')}-${task.taskId}.log`;
return task;
}
start() {
const condition = {
taskId: this.taskId,
attempts: this.attempts,
};
this.setExecuteWorker();
this.state = TaskState.Processing;
this.attempts += 1;
return condition;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGFzay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2FwcC9jb3JlL2VudGl0eS9UYXNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFFN0IsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRWpELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pFLE9BQU8sS0FBSyxNQUFNLHVCQUF1QixDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFVBQVUsRUFBaUIsTUFBTSx1QkFBdUIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsTUFBTSxFQUFtQixNQUFNLGFBQWEsQ0FBQztBQUV0RCxPQUFPLEVBQUUsYUFBYSxFQUFtQixNQUFNLGNBQWMsQ0FBQztBQUU5RCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDO0FBMEYvQixNQUFNLE9BQU8sSUFBNEMsU0FBUSxNQUFNO0lBZXJFLFlBQVksSUFBaUI7UUFDM0IsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ1osSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzFCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDeEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztR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