fix(preview): sync fs_dev_servers state with container suspension to properly handle idle wakeup
This commit is contained in:
@@ -186,6 +186,7 @@ function renderDevCompose(projectSlug: string, projectId: string): string {
|
|||||||
image: ${VIBN_DEV_IMAGE}
|
image: ${VIBN_DEV_IMAGE}
|
||||||
pull_policy: never
|
pull_policy: never
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
command: ["bash", "-c", "echo 'Booting Vibn Container...'; if [ -f /workspace/package.json ]; then echo 'Found package.json, checking deps...'; if [ ! -d /workspace/node_modules ]; then npm install; fi; echo 'Starting dev server...'; npx next dev -H 0.0.0.0 --webpack; else echo 'No package.json found. Standing by...'; sleep infinity; fi"]
|
||||||
working_dir: /workspace
|
working_dir: /workspace
|
||||||
volumes:
|
volumes:
|
||||||
- workspace:/workspace
|
- workspace:/workspace
|
||||||
@@ -335,6 +336,29 @@ export async function ensureDevContainer(
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// In Path 2, the dev container natively runs the Next.js server on port 3000.
|
||||||
|
// We automatically inject the static preview tracking row so the UI sees it instantly.
|
||||||
|
const previewUrl = buildPreviewUrl(opts.projectId, opts.projectSlug, 3000);
|
||||||
|
if (previewUrl) {
|
||||||
|
await query(
|
||||||
|
`INSERT INTO fs_dev_servers
|
||||||
|
(id, project_id, workspace, name, command, port, preview_url, state)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||||
|
ON CONFLICT (id) DO UPDATE
|
||||||
|
SET state = EXCLUDED.state`,
|
||||||
|
[
|
||||||
|
`ds_primary_${opts.projectId.replace(/-/g, "").slice(0, 10)}`,
|
||||||
|
opts.projectId,
|
||||||
|
opts.workspace.slug,
|
||||||
|
"Primary App",
|
||||||
|
"npx next dev -H 0.0.0.0 --webpack",
|
||||||
|
3000,
|
||||||
|
previewUrl,
|
||||||
|
"running",
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Bookkeeping link so apps_list / projects_get see the dev container
|
// Bookkeeping link so apps_list / projects_get see the dev container
|
||||||
// under the right Vibn project.
|
// under the right Vibn project.
|
||||||
try {
|
try {
|
||||||
@@ -364,11 +388,17 @@ export async function suspendDevContainer(projectId: string): Promise<void> {
|
|||||||
WHERE project_id = $1`,
|
WHERE project_id = $1`,
|
||||||
[projectId],
|
[projectId],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Also mark the fixed port-3000 app as stopped so the UI knows
|
||||||
|
await query(
|
||||||
|
`UPDATE fs_dev_servers SET state = 'stopped' WHERE project_id = $1 AND port = 3000`,
|
||||||
|
[projectId],
|
||||||
|
).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function resumeDevContainer(projectId: string): Promise<void> {
|
export async function resumeDevContainer(projectId: string): Promise<void> {
|
||||||
const row = await getDevContainerRow(projectId);
|
const row = await getDevContainerRow(projectId);
|
||||||
if (!row) throw new Error(`No dev container provisioned for ${projectId}`);
|
if (!row) return;
|
||||||
if (row.state === "running") return;
|
if (row.state === "running") return;
|
||||||
await startService(row.service_uuid);
|
await startService(row.service_uuid);
|
||||||
await query(
|
await query(
|
||||||
@@ -377,6 +407,12 @@ export async function resumeDevContainer(projectId: string): Promise<void> {
|
|||||||
WHERE project_id = $1`,
|
WHERE project_id = $1`,
|
||||||
[projectId],
|
[projectId],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Mark the fixed port-3000 app as running again since the container boots it
|
||||||
|
await query(
|
||||||
|
`UPDATE fs_dev_servers SET state = 'running' WHERE project_id = $1 AND port = 3000`,
|
||||||
|
[projectId],
|
||||||
|
).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function touchActivity(projectId: string): Promise<void> {
|
async function touchActivity(projectId: string): Promise<void> {
|
||||||
|
|||||||
Reference in New Issue
Block a user