@@ -1,51 +0,0 @@
|
|||||||
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/playwright:v1.46.0-noble
|
|
||||||
|
|
||||||
# Set working directory
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# Install node dependencies
|
|
||||||
COPY package*.json ./
|
|
||||||
COPY src ./src
|
|
||||||
COPY public ./public
|
|
||||||
COPY server ./server
|
|
||||||
COPY tsconfig.json ./
|
|
||||||
COPY server/tsconfig.json ./server/
|
|
||||||
# COPY server/start.sh ./
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN npm install --legacy-peer-deps
|
|
||||||
|
|
||||||
# Install Playwright browsers and dependencies
|
|
||||||
RUN npx playwright install --with-deps chromium
|
|
||||||
|
|
||||||
# Create the Chromium data directory with necessary permissions
|
|
||||||
RUN mkdir -p /tmp/chromium-data-dir && \
|
|
||||||
chmod -R 777 /tmp/chromium-data-dir
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN apt-get update && apt-get install -y \
|
|
||||||
libgbm1 \
|
|
||||||
libnss3 \
|
|
||||||
libatk1.0-0 \
|
|
||||||
libatk-bridge2.0-0 \
|
|
||||||
libdrm2 \
|
|
||||||
libxkbcommon0 \
|
|
||||||
libglib2.0-0 \
|
|
||||||
libdbus-1-3 \
|
|
||||||
libx11-xcb1 \
|
|
||||||
libxcb1 \
|
|
||||||
libxcomposite1 \
|
|
||||||
libxcursor1 \
|
|
||||||
libxdamage1 \
|
|
||||||
libxext6 \
|
|
||||||
libxi6 \
|
|
||||||
libxtst6 \
|
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
|
||||||
&& mkdir -p /tmp/.X11-unix && chmod 1777 /tmp/.X11-unix
|
|
||||||
|
|
||||||
# Expose backend port
|
|
||||||
EXPOSE ${BACKEND_PORT:-8080}
|
|
||||||
|
|
||||||
# Run migrations & start backend using start script
|
|
||||||
#CMD ["npm", "run", "server"]
|
|
||||||
CMD ["sh", "-c", "npm run migrate && npm run server"]
|
|
||||||
@@ -630,6 +630,43 @@ router.put('/runs/:id', requireSignIn, async (req: AuthenticatedRequest, res) =>
|
|||||||
robotMetaId: recording.recording_meta.id,
|
robotMetaId: recording.recording_meta.id,
|
||||||
queued: true
|
queued: true
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
const browserId = getActiveBrowserIdByState(req.user.id, "run")
|
||||||
|
|
||||||
|
if (browserId) {
|
||||||
|
// User has reached the browser limit, queue the run
|
||||||
|
try {
|
||||||
|
// Create the run record with 'queued' status
|
||||||
|
await Run.create({
|
||||||
|
status: 'queued',
|
||||||
|
name: recording.recording_meta.name,
|
||||||
|
robotId: recording.id,
|
||||||
|
robotMetaId: recording.recording_meta.id,
|
||||||
|
startedAt: new Date().toLocaleString(),
|
||||||
|
finishedAt: '',
|
||||||
|
browserId: browserId, // Random will be updated later
|
||||||
|
interpreterSettings: req.body,
|
||||||
|
log: 'Run queued - waiting for available browser slot',
|
||||||
|
runId,
|
||||||
|
runByUserId: req.user.id,
|
||||||
|
serializableOutput: {},
|
||||||
|
binaryOutput: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.send({
|
||||||
|
browserId: browserId,
|
||||||
|
runId: runId,
|
||||||
|
robotMetaId: recording.recording_meta.id,
|
||||||
|
queued: true,
|
||||||
|
});
|
||||||
|
} catch (queueError: any) {
|
||||||
|
logger.log('error', `Failed to queue run job: ${queueError.message}`);
|
||||||
|
return res.status(503).send({ error: 'Unable to queue run, please try again later' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.log('info', "Browser id does not exist");
|
||||||
|
return res.send('');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const { message } = e as Error;
|
const { message } = e as Error;
|
||||||
@@ -949,6 +986,26 @@ router.post('/runs/abort/:id', requireSignIn, async (req: AuthenticatedRequest,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!['running', 'queued'].includes(run.status)) {
|
||||||
|
return res.status(400).send({
|
||||||
|
error: `Cannot abort run with status: ${run.status}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await run.update({
|
||||||
|
status: 'aborting'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (run.status === 'queued') {
|
||||||
|
await run.update({
|
||||||
|
status: 'aborted',
|
||||||
|
finishedAt: new Date().toLocaleString(),
|
||||||
|
log: 'Run aborted while queued'
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.send({ success: true, message: 'Queued run aborted' });
|
||||||
|
}
|
||||||
|
|
||||||
const userQueueName = `abort-run-user-${req.user.id}`;
|
const userQueueName = `abort-run-user-${req.user.id}`;
|
||||||
await pgBoss.createQueue(userQueueName);
|
await pgBoss.createQueue(userQueueName);
|
||||||
|
|
||||||
@@ -965,6 +1022,7 @@ router.post('/runs/abort/:id', requireSignIn, async (req: AuthenticatedRequest,
|
|||||||
jobId,
|
jobId,
|
||||||
isQueued: false
|
isQueued: false
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const { message } = e as Error;
|
const { message } = e as Error;
|
||||||
logger.log('error', `Error aborting run ${req.params.id}: ${message}`);
|
logger.log('error', `Error aborting run ${req.params.id}: ${message}`);
|
||||||
|
|||||||
@@ -444,7 +444,7 @@ export const RunContent = ({ row, currentLog, interpretationInProgress, logEndRe
|
|||||||
ref={logEndRef} />
|
ref={logEndRef} />
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
{row.status === 'running' ? <Button
|
{row.status === 'running' || row.status === 'queued' ? <Button
|
||||||
color="error"
|
color="error"
|
||||||
onClick={abortRunHandler}
|
onClick={abortRunHandler}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user