역할별 PostgreSQL pool 상한과 동일 process 공유 pool을 적용하고 health 지표를 노출한다.\n\n게임 기능 advisory lock을 schema namespace로 통일하고 실제 PostgreSQL 통합 하네스를 보강한다.
87 lines
3.0 KiB
TypeScript
87 lines
3.0 KiB
TypeScript
import { createGatewayPostgresConnector, type GatewayPrismaClient } from '@sammo-ts/infra';
|
|
import {
|
|
createGatewayReleaseRepository,
|
|
GitWorkspaceManager,
|
|
Pm2ProcessManager,
|
|
PnpmBuildRunner,
|
|
} from '@sammo-ts/gateway-api';
|
|
|
|
import { resolveReleaseControllerConfig } from './config.js';
|
|
import { GatewayReleaseController } from './releaseController.js';
|
|
import { upgradeReleaseController } from './selfUpgrade.js';
|
|
|
|
export * from './config.js';
|
|
export * from './releaseController.js';
|
|
export * from './selfUpgrade.js';
|
|
|
|
const main = async (): Promise<void> => {
|
|
const config = resolveReleaseControllerConfig();
|
|
const postgres = createGatewayPostgresConnector({
|
|
url: config.gatewayDatabaseUrl,
|
|
maxConnections: config.postgresPoolMax,
|
|
});
|
|
await postgres.connect();
|
|
const repository = createGatewayReleaseRepository(postgres.prisma as GatewayPrismaClient);
|
|
const workspaceManager = new GitWorkspaceManager({
|
|
repoRoot: config.workspaceRoot,
|
|
worktreeRoot: config.worktreeRoot,
|
|
baseEnv: config.baseEnv,
|
|
});
|
|
const buildRunner = new PnpmBuildRunner();
|
|
const processManager = new Pm2ProcessManager();
|
|
const controller = new GatewayReleaseController(repository, workspaceManager, buildRunner, processManager, config);
|
|
const command = process.argv[2] ?? 'daemon';
|
|
if (command === 'status') {
|
|
console.log(
|
|
JSON.stringify(
|
|
{ state: await repository.getState(), operations: await repository.listOperations(20) },
|
|
null,
|
|
2
|
|
)
|
|
);
|
|
await postgres.disconnect();
|
|
return;
|
|
}
|
|
if (command === 'run-once') {
|
|
console.log(JSON.stringify(await controller.runOnce(), null, 2));
|
|
await postgres.disconnect();
|
|
return;
|
|
}
|
|
if (command === 'self-upgrade') {
|
|
const sourceMode = process.argv[3];
|
|
const sourceRef = process.argv[4];
|
|
if ((sourceMode !== 'BRANCH' && sourceMode !== 'COMMIT') || !sourceRef) {
|
|
throw new Error('usage: release-controller self-upgrade <BRANCH|COMMIT> <ref>');
|
|
}
|
|
const result = await upgradeReleaseController({
|
|
sourceMode,
|
|
sourceRef,
|
|
workspaceManager,
|
|
buildRunner,
|
|
processManager,
|
|
config,
|
|
});
|
|
console.log(JSON.stringify(result, null, 2));
|
|
await postgres.disconnect();
|
|
return;
|
|
}
|
|
if (command !== 'daemon') throw new Error(`Unknown release-controller command: ${command}`);
|
|
let stopping = false;
|
|
const stop = async (): Promise<void> => {
|
|
if (stopping) return;
|
|
stopping = true;
|
|
await postgres.disconnect();
|
|
};
|
|
process.once('SIGINT', () => void stop());
|
|
process.once('SIGTERM', () => void stop());
|
|
while (!stopping) {
|
|
await controller.runOnce();
|
|
await new Promise<void>((resolve) => setTimeout(resolve, config.pollIntervalMs));
|
|
}
|
|
};
|
|
|
|
main().catch((error) => {
|
|
console.error('[release-controller] failed', error);
|
|
process.exitCode = 1;
|
|
});
|