33 lines
1.9 KiB
JavaScript
33 lines
1.9 KiB
JavaScript
export const SERVER_JOB_RESOURCE_BUDGET_SCHEMA = 1;
|
|
export const SERVER_JOB_RESOURCE_LIMITS = Object.freeze({
|
|
cpuMs: 60_000,
|
|
memoryBytes: 512 * 1024 * 1024,
|
|
processCount: 1,
|
|
fileCount: 1_024,
|
|
wallMs: 300_000,
|
|
outputBytes: 512 * 1024 * 1024,
|
|
});
|
|
|
|
const fields = Object.keys(SERVER_JOB_RESOURCE_LIMITS);
|
|
|
|
function integer(value, field, minimum = 0) {
|
|
if (!Number.isSafeInteger(value) || value < minimum || value > SERVER_JOB_RESOURCE_LIMITS[field]) throw new Error(`SERVER_JOB_BUDGET_EXCEEDED: ${field} is outside the enforced budget`);
|
|
return value;
|
|
}
|
|
|
|
export function parseServerJobResourceBudget(value) {
|
|
if (!value || value.schemaVersion !== SERVER_JOB_RESOURCE_BUDGET_SCHEMA || typeof value !== "object") throw new Error("SERVER_JOB_BUDGET_INVALID: schema is unsupported");
|
|
if (Object.keys(value).some((key) => key !== "schemaVersion" && !fields.includes(key))) throw new Error("SERVER_JOB_BUDGET_INVALID: undeclared budget field");
|
|
return Object.freeze({ schemaVersion: SERVER_JOB_RESOURCE_BUDGET_SCHEMA, ...Object.fromEntries(fields.map((field) => [field, integer(value[field], field)])) });
|
|
}
|
|
|
|
export function createServerJobResourceReceipt(budgetValue, usageValue, status = "SUCCEEDED") {
|
|
const budget = parseServerJobResourceBudget(budgetValue);
|
|
if (!usageValue || typeof usageValue !== "object") throw new Error("SERVER_JOB_BUDGET_INVALID: usage is invalid");
|
|
const usage = Object.freeze(Object.fromEntries(fields.map((field) => [field, integer(usageValue[field], field)])));
|
|
const exceeded = fields.filter((field) => usage[field] > budget[field]);
|
|
if (exceeded.length > 0) throw new Error(`SERVER_JOB_BUDGET_EXCEEDED: ${exceeded.join(",")}`);
|
|
if (!["SUCCEEDED", "FAILED", "CANCELLED"].includes(status)) throw new Error("SERVER_JOB_BUDGET_INVALID: status is unsupported");
|
|
return Object.freeze({ schemaVersion: SERVER_JOB_RESOURCE_BUDGET_SCHEMA, status, budget, usage, enforced: true, exceeded: [] });
|
|
}
|