| 29 | 29 | | STANDARD_INSTANCE, |
| 30 | 30 | | instanceNamed, |
| 31 | 31 | | priceScale, |
| 32 | + | runnerMinutes, |
| 32 | 33 | | } from "@g1t/contracts"; |
| 33 | 34 | | |
| 34 | 35 | | import { BUMP_MINUTES, BUMP_TOKEN_TTL_SECONDS, bumpEnv, bumpProblem, bumpSandboxName, systemActor, registryHosts } from "./bump"; |
| ⋯ |
| 897 | 898 | | const route = selfHosted && (kind === "check" || kind === "queue") ? await selfHostedRoute(this.env.ACTIONS, repo) : null; |
| 898 | 899 | | if (route) return { ok: true, held: null, limits: limitsOf(ent), route }; |
| 899 | 900 | | const [standardMicros, isPublic] = await Promise.all([compute.microsPerSecond(), this.isPublic(repo)]); |
| 900 | | − | // A larger machine is reserved for at what it costs with every vCPU busy. |
| 901 | + | // Reserved for its time limit at the larger of what it may cost (the |
| 902 | + | // sandbox price, scaled to its machine) and its minutes at the |
| 903 | + | // machine's rate, which is what it is charged. |
| 904 | + | const limit = estimateMinutes(minutes, ent); |
| 901 | 905 | | const microsPerSecond = standardMicros * priceScale(instance); |
| 902 | | − | const admission = await compute.admit( |
| 903 | | − | { workspace, repo, public: isPublic, kind, estimateMicros: sandboxEstimateMicros(estimateMinutes(minutes, ent), microsPerSecond) }, |
| 904 | | − | ent, |
| 906 | + | const estimateMicros = Math.max( |
| 907 | + | sandboxEstimateMicros(limit, microsPerSecond), |
| 908 | + | runnerMinutes(limit * 60) * instance.microsPerMinute, |
| 905 | 909 | | ); |
| 910 | + | const admission = await compute.admit({ workspace, repo, public: isPublic, kind, estimateMicros }, ent); |
| 906 | 911 | | if (!admission.ok) return { ok: false, code: admission.code, message: admission.message }; |
| 907 | 912 | | return { |
| 908 | 913 | | ok: true, |