feat: Implement admin router and orchestrator for managing profiles and builds
- Added `adminRouter` for handling profile management, including listing, upserting, and updating statuses. - Introduced `BuildRunner` interface and `PnpmBuildRunner` class for executing build commands. - Created `GatewayOrchestrator` to manage profile states, reconcile processes, and handle build queues. - Implemented `Pm2ProcessManager` for managing processes using PM2. - Developed `GatewayProfileRepository` for interacting with the database to manage profiles. - Added utility functions for resolving workspace roots and managing process definitions. - Included tests for profile reconciliation logic.
This commit is contained in:
@@ -36,6 +36,26 @@ const buildCaller = () => {
|
||||
}),
|
||||
sendTalkMessage: async () => {},
|
||||
};
|
||||
const profiles = {
|
||||
listProfiles: async () => [],
|
||||
getProfile: async () => null,
|
||||
upsertProfile: async () => {
|
||||
throw new Error('not used');
|
||||
},
|
||||
updateStatus: async () => null,
|
||||
updateBuildStatus: async () => null,
|
||||
listReservedToStart: async () => [],
|
||||
findQueuedBuild: async () => null,
|
||||
updateLastError: async () => {},
|
||||
};
|
||||
const orchestrator = {
|
||||
start: () => {},
|
||||
stop: async () => {},
|
||||
reconcileNow: async () => {},
|
||||
runScheduleNow: async () => {},
|
||||
runBuildQueueNow: async () => {},
|
||||
listRuntimeStates: async () => [],
|
||||
};
|
||||
const caller = appRouter.createCaller(
|
||||
createGatewayApiContext({
|
||||
users,
|
||||
@@ -46,6 +66,9 @@ const buildCaller = () => {
|
||||
kakaoClient,
|
||||
oauthSessions,
|
||||
publicBaseUrl: 'http://localhost',
|
||||
profiles,
|
||||
orchestrator,
|
||||
requestHeaders: {},
|
||||
})
|
||||
);
|
||||
return { caller, oauthSessions };
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { planProfileReconcile } from '../src/orchestrator/gatewayOrchestrator.js';
|
||||
|
||||
describe('planProfileReconcile', () => {
|
||||
it('starts missing processes for running profiles', () => {
|
||||
expect(
|
||||
planProfileReconcile('RUNNING', {
|
||||
apiRunning: true,
|
||||
daemonRunning: false,
|
||||
})
|
||||
).toEqual({ shouldStart: true, shouldStop: false });
|
||||
});
|
||||
|
||||
it('does nothing when running profile is healthy', () => {
|
||||
expect(
|
||||
planProfileReconcile('RUNNING', {
|
||||
apiRunning: true,
|
||||
daemonRunning: true,
|
||||
})
|
||||
).toEqual({ shouldStart: false, shouldStop: false });
|
||||
});
|
||||
|
||||
it('stops processes for non-running profiles', () => {
|
||||
expect(
|
||||
planProfileReconcile('STOPPED', {
|
||||
apiRunning: false,
|
||||
daemonRunning: true,
|
||||
})
|
||||
).toEqual({ shouldStart: false, shouldStop: true });
|
||||
});
|
||||
|
||||
it('keeps reserved profiles off', () => {
|
||||
expect(
|
||||
planProfileReconcile('RESERVED', {
|
||||
apiRunning: false,
|
||||
daemonRunning: false,
|
||||
})
|
||||
).toEqual({ shouldStart: false, shouldStop: false });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user