@shipfox/api-runners 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +61 -0
- package/dist/config.d.ts +5 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +53 -6
- package/dist/config.js.map +1 -1
- package/dist/core/capacity-assignments.d.ts +7 -0
- package/dist/core/capacity-assignments.d.ts.map +1 -0
- package/dist/core/capacity-assignments.js +6 -0
- package/dist/core/capacity-assignments.js.map +1 -0
- package/dist/core/demand.d.ts +6 -6
- package/dist/core/demand.d.ts.map +1 -1
- package/dist/core/demand.js +10 -10
- package/dist/core/demand.js.map +1 -1
- package/dist/core/entities/capacity-assignment.d.ts +9 -0
- package/dist/core/entities/capacity-assignment.d.ts.map +1 -0
- package/dist/core/entities/capacity-assignment.js +3 -0
- package/dist/core/entities/capacity-assignment.js.map +1 -0
- package/dist/core/entities/ephemeral-registration-token.d.ts +1 -1
- package/dist/core/entities/ephemeral-registration-token.d.ts.map +1 -1
- package/dist/core/entities/ephemeral-registration-token.js.map +1 -1
- package/dist/core/entities/provisioner-capability-snapshot.d.ts +13 -0
- package/dist/core/entities/provisioner-capability-snapshot.d.ts.map +1 -0
- package/dist/core/entities/provisioner-capability-snapshot.js +3 -0
- package/dist/core/entities/provisioner-capability-snapshot.js.map +1 -0
- package/dist/core/entities/provisioner-token.d.ts +10 -2
- package/dist/core/entities/provisioner-token.d.ts.map +1 -1
- package/dist/core/entities/provisioner-token.js.map +1 -1
- package/dist/core/entities/{provisioned-runner.d.ts → runner-instance.d.ts} +6 -6
- package/dist/core/entities/runner-instance.d.ts.map +1 -0
- package/dist/core/entities/runner-instance.js +3 -0
- package/dist/core/entities/runner-instance.js.map +1 -0
- package/dist/core/entities/runner-session.d.ts +4 -2
- package/dist/core/entities/runner-session.d.ts.map +1 -1
- package/dist/core/entities/runner-session.js.map +1 -1
- package/dist/core/ephemeral-registration-tokens.d.ts +5 -5
- package/dist/core/ephemeral-registration-tokens.d.ts.map +1 -1
- package/dist/core/ephemeral-registration-tokens.js +12 -12
- package/dist/core/ephemeral-registration-tokens.js.map +1 -1
- package/dist/core/errors.d.ts +16 -4
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +22 -4
- package/dist/core/errors.js.map +1 -1
- package/dist/core/index.d.ts +10 -4
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +6 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/job-executions.d.ts +2 -0
- package/dist/core/job-executions.d.ts.map +1 -1
- package/dist/core/job-executions.js +1 -2
- package/dist/core/job-executions.js.map +1 -1
- package/dist/core/maintenance.d.ts +1 -1
- package/dist/core/maintenance.d.ts.map +1 -1
- package/dist/core/maintenance.js +5 -5
- package/dist/core/maintenance.js.map +1 -1
- package/dist/core/provisioner-capability-snapshots.d.ts +5 -0
- package/dist/core/provisioner-capability-snapshots.d.ts.map +1 -0
- package/dist/core/provisioner-capability-snapshots.js +10 -0
- package/dist/core/provisioner-capability-snapshots.js.map +1 -0
- package/dist/core/provisioner-tokens.d.ts +10 -0
- package/dist/core/provisioner-tokens.d.ts.map +1 -1
- package/dist/core/provisioner-tokens.js +23 -1
- package/dist/core/provisioner-tokens.js.map +1 -1
- package/dist/core/rate-limit.d.ts.map +1 -1
- package/dist/core/rate-limit.js +2 -7
- package/dist/core/rate-limit.js.map +1 -1
- package/dist/core/runner-activation.d.ts +13 -0
- package/dist/core/runner-activation.d.ts.map +1 -0
- package/dist/core/runner-activation.js +36 -0
- package/dist/core/runner-activation.js.map +1 -0
- package/dist/core/runner-control-sessions.d.ts +46 -0
- package/dist/core/runner-control-sessions.d.ts.map +1 -0
- package/dist/core/runner-control-sessions.js +121 -0
- package/dist/core/runner-control-sessions.js.map +1 -0
- package/dist/core/runner-instances.d.ts +79 -0
- package/dist/core/runner-instances.d.ts.map +1 -0
- package/dist/core/runner-instances.js +168 -0
- package/dist/core/runner-instances.js.map +1 -0
- package/dist/core/runner-sessions.d.ts +8 -2
- package/dist/core/runner-sessions.d.ts.map +1 -1
- package/dist/core/runner-sessions.js +8 -5
- package/dist/core/runner-sessions.js.map +1 -1
- package/dist/db/capacity-assignments.d.ts +7 -0
- package/dist/db/capacity-assignments.d.ts.map +1 -0
- package/dist/db/capacity-assignments.js +72 -0
- package/dist/db/capacity-assignments.js.map +1 -0
- package/dist/db/db.d.ts +2837 -1009
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +11 -2
- package/dist/db/db.js.map +1 -1
- package/dist/db/ephemeral-registration-tokens.d.ts +2 -2
- package/dist/db/ephemeral-registration-tokens.d.ts.map +1 -1
- package/dist/db/ephemeral-registration-tokens.js +21 -21
- package/dist/db/ephemeral-registration-tokens.js.map +1 -1
- package/dist/db/index.d.ts +7 -4
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +5 -2
- package/dist/db/index.js.map +1 -1
- package/dist/db/job-executions.d.ts +6 -6
- package/dist/db/job-executions.d.ts.map +1 -1
- package/dist/db/job-executions.js +20 -19
- package/dist/db/job-executions.js.map +1 -1
- package/dist/db/provisioner-capability-snapshots.d.ts +21 -0
- package/dist/db/provisioner-capability-snapshots.d.ts.map +1 -0
- package/dist/db/provisioner-capability-snapshots.js +57 -0
- package/dist/db/provisioner-capability-snapshots.js.map +1 -0
- package/dist/db/provisioner-tokens.d.ts +7 -2
- package/dist/db/provisioner-tokens.d.ts.map +1 -1
- package/dist/db/provisioner-tokens.js +59 -10
- package/dist/db/provisioner-tokens.js.map +1 -1
- package/dist/db/reservations.d.ts +18 -0
- package/dist/db/reservations.d.ts.map +1 -1
- package/dist/db/reservations.js +88 -1
- package/dist/db/reservations.js.map +1 -1
- package/dist/db/runner-instances.d.ts +91 -0
- package/dist/db/runner-instances.d.ts.map +1 -0
- package/dist/db/runner-instances.js +511 -0
- package/dist/db/runner-instances.js.map +1 -0
- package/dist/db/runner-sessions.d.ts +5 -0
- package/dist/db/runner-sessions.d.ts.map +1 -1
- package/dist/db/runner-sessions.js +48 -2
- package/dist/db/runner-sessions.js.map +1 -1
- package/dist/db/schema/capacity-assignments.d.ts +113 -0
- package/dist/db/schema/capacity-assignments.d.ts.map +1 -0
- package/dist/db/schema/capacity-assignments.js +29 -0
- package/dist/db/schema/capacity-assignments.js.map +1 -0
- package/dist/db/schema/ephemeral-registration-tokens.d.ts +2 -2
- package/dist/db/schema/ephemeral-registration-tokens.js +3 -3
- package/dist/db/schema/ephemeral-registration-tokens.js.map +1 -1
- package/dist/db/schema/provisioner-capability-snapshots.d.ts +207 -0
- package/dist/db/schema/provisioner-capability-snapshots.d.ts.map +1 -0
- package/dist/db/schema/provisioner-capability-snapshots.js +38 -0
- package/dist/db/schema/provisioner-capability-snapshots.js.map +1 -0
- package/dist/db/schema/provisioner-tokens.d.ts +19 -1
- package/dist/db/schema/provisioner-tokens.d.ts.map +1 -1
- package/dist/db/schema/provisioner-tokens.js +29 -3
- package/dist/db/schema/provisioner-tokens.js.map +1 -1
- package/dist/db/schema/runner-activation-tokens.d.ts +161 -0
- package/dist/db/schema/runner-activation-tokens.d.ts.map +1 -0
- package/dist/db/schema/runner-activation-tokens.js +27 -0
- package/dist/db/schema/runner-activation-tokens.js.map +1 -0
- package/dist/db/schema/runner-control-sessions.d.ts +338 -0
- package/dist/db/schema/runner-control-sessions.d.ts.map +1 -0
- package/dist/db/schema/runner-control-sessions.js +52 -0
- package/dist/db/schema/runner-control-sessions.js.map +1 -0
- package/dist/db/schema/{provisioned-runners.d.ts → runner-instances.d.ts} +88 -34
- package/dist/db/schema/runner-instances.d.ts.map +1 -0
- package/dist/db/schema/{provisioned-runners.js → runner-instances.js} +19 -14
- package/dist/db/schema/runner-instances.js.map +1 -0
- package/dist/db/schema/runner-sessions.d.ts +39 -5
- package/dist/db/schema/runner-sessions.d.ts.map +1 -1
- package/dist/db/schema/runner-sessions.js +13 -6
- package/dist/db/schema/runner-sessions.js.map +1 -1
- package/dist/db/schema/running-job-executions.d.ts +2 -2
- package/dist/db/schema/running-job-executions.js +4 -4
- package/dist/db/schema/running-job-executions.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +45 -38
- package/dist/index.js.map +1 -1
- package/dist/installation-provisioning.d.ts +14 -0
- package/dist/installation-provisioning.d.ts.map +1 -0
- package/dist/installation-provisioning.js +7 -0
- package/dist/installation-provisioning.js.map +1 -0
- package/dist/metrics/index.d.ts +1 -1
- package/dist/metrics/index.d.ts.map +1 -1
- package/dist/metrics/index.js +1 -1
- package/dist/metrics/index.js.map +1 -1
- package/dist/metrics/instance.d.ts +11 -7
- package/dist/metrics/instance.d.ts.map +1 -1
- package/dist/metrics/instance.js +13 -7
- package/dist/metrics/instance.js.map +1 -1
- package/dist/presentation/auth/index.d.ts +1 -0
- package/dist/presentation/auth/index.d.ts.map +1 -1
- package/dist/presentation/auth/index.js +1 -0
- package/dist/presentation/auth/index.js.map +1 -1
- package/dist/presentation/auth/provisioner-token-auth.d.ts.map +1 -1
- package/dist/presentation/auth/provisioner-token-auth.js +5 -1
- package/dist/presentation/auth/provisioner-token-auth.js.map +1 -1
- package/dist/presentation/auth/runner-control-session-auth.d.ts +4 -0
- package/dist/presentation/auth/runner-control-session-auth.d.ts.map +1 -0
- package/dist/presentation/auth/runner-control-session-auth.js +29 -0
- package/dist/presentation/auth/runner-control-session-auth.js.map +1 -0
- package/dist/presentation/auth/runner-registration-token-auth.d.ts +5 -1
- package/dist/presentation/auth/runner-registration-token-auth.d.ts.map +1 -1
- package/dist/presentation/auth/runner-registration-token-auth.js +21 -1
- package/dist/presentation/auth/runner-registration-token-auth.js.map +1 -1
- package/dist/presentation/dto/index.d.ts +2 -2
- package/dist/presentation/dto/index.d.ts.map +1 -1
- package/dist/presentation/dto/index.js +2 -2
- package/dist/presentation/dto/index.js.map +1 -1
- package/dist/presentation/dto/mint-registration-tokens.d.ts +5 -3
- package/dist/presentation/dto/mint-registration-tokens.d.ts.map +1 -1
- package/dist/presentation/dto/mint-registration-tokens.js +4 -4
- package/dist/presentation/dto/mint-registration-tokens.js.map +1 -1
- package/dist/presentation/dto/poll-demand.d.ts.map +1 -1
- package/dist/presentation/dto/poll-demand.js +7 -1
- package/dist/presentation/dto/poll-demand.js.map +1 -1
- package/dist/presentation/dto/provisioner-token.d.ts +1 -0
- package/dist/presentation/dto/provisioner-token.d.ts.map +1 -1
- package/dist/presentation/dto/provisioner-token.js +5 -1
- package/dist/presentation/dto/provisioner-token.js.map +1 -1
- package/dist/presentation/dto/{provisioned-runners.d.ts → runner-instances.d.ts} +9 -9
- package/dist/presentation/dto/runner-instances.d.ts.map +1 -0
- package/dist/presentation/dto/{provisioned-runners.js → runner-instances.js} +6 -6
- package/dist/presentation/dto/runner-instances.js.map +1 -0
- package/dist/presentation/index.d.ts +2 -2
- package/dist/presentation/index.d.ts.map +1 -1
- package/dist/presentation/index.js +2 -2
- package/dist/presentation/index.js.map +1 -1
- package/dist/presentation/inter-module.d.ts +5 -0
- package/dist/presentation/inter-module.d.ts.map +1 -0
- package/dist/presentation/inter-module.js +43 -0
- package/dist/presentation/inter-module.js.map +1 -0
- package/dist/presentation/routes/assign-capacity.d.ts +2 -0
- package/dist/presentation/routes/assign-capacity.d.ts.map +1 -0
- package/dist/presentation/routes/assign-capacity.js +44 -0
- package/dist/presentation/routes/assign-capacity.js.map +1 -0
- package/dist/presentation/routes/get-provisioner-me.d.ts.map +1 -1
- package/dist/presentation/routes/get-provisioner-me.js +5 -1
- package/dist/presentation/routes/get-provisioner-me.js.map +1 -1
- package/dist/presentation/routes/heartbeat.d.ts +2 -1
- package/dist/presentation/routes/heartbeat.d.ts.map +1 -1
- package/dist/presentation/routes/heartbeat.js +60 -50
- package/dist/presentation/routes/heartbeat.js.map +1 -1
- package/dist/presentation/routes/index.d.ts +3 -1
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +83 -50
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/routes/mint-registration-tokens.d.ts.map +1 -1
- package/dist/presentation/routes/mint-registration-tokens.js +5 -5
- package/dist/presentation/routes/mint-registration-tokens.js.map +1 -1
- package/dist/presentation/routes/planned-capacity.d.ts +3 -0
- package/dist/presentation/routes/planned-capacity.d.ts.map +1 -0
- package/dist/presentation/routes/planned-capacity.js +54 -0
- package/dist/presentation/routes/planned-capacity.js.map +1 -0
- package/dist/presentation/routes/poll-demand.d.ts +2 -0
- package/dist/presentation/routes/poll-demand.d.ts.map +1 -1
- package/dist/presentation/routes/poll-demand.js +86 -45
- package/dist/presentation/routes/poll-demand.js.map +1 -1
- package/dist/presentation/routes/reconcile-runner-instances.d.ts +2 -0
- package/dist/presentation/routes/reconcile-runner-instances.d.ts.map +1 -0
- package/dist/presentation/routes/reconcile-runner-instances.js +27 -0
- package/dist/presentation/routes/reconcile-runner-instances.js.map +1 -0
- package/dist/presentation/routes/register.d.ts +2 -1
- package/dist/presentation/routes/register.d.ts.map +1 -1
- package/dist/presentation/routes/register.js +55 -52
- package/dist/presentation/routes/register.js.map +1 -1
- package/dist/presentation/routes/report-runner-instances.d.ts +2 -0
- package/dist/presentation/routes/report-runner-instances.d.ts.map +1 -0
- package/dist/presentation/routes/report-runner-instances.js +37 -0
- package/dist/presentation/routes/report-runner-instances.js.map +1 -0
- package/dist/presentation/routes/request-job.d.ts +2 -1
- package/dist/presentation/routes/request-job.d.ts.map +1 -1
- package/dist/presentation/routes/request-job.js +39 -36
- package/dist/presentation/routes/request-job.js.map +1 -1
- package/dist/presentation/routes/runner-enrollment.d.ts +7 -0
- package/dist/presentation/routes/runner-enrollment.d.ts.map +1 -0
- package/dist/presentation/routes/runner-enrollment.js +185 -0
- package/dist/presentation/routes/runner-enrollment.js.map +1 -0
- package/dist/temporal/activities/index.d.ts +2 -2
- package/dist/temporal/activities/index.d.ts.map +1 -1
- package/dist/temporal/activities/index.js +2 -2
- package/dist/temporal/activities/index.js.map +1 -1
- package/dist/temporal/activities/maintenance-activities.d.ts +1 -1
- package/dist/temporal/activities/maintenance-activities.d.ts.map +1 -1
- package/dist/temporal/activities/maintenance-activities.js +3 -3
- package/dist/temporal/activities/maintenance-activities.js.map +1 -1
- package/dist/temporal/workflows/index.bundle.js +3 -3
- package/dist/temporal/workflows/stuck-job-detector.js +2 -2
- package/dist/temporal/workflows/stuck-job-detector.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0000_initial.sql +102 -24
- package/drizzle/meta/0000_snapshot.json +483 -63
- package/package.json +21 -16
- package/src/config.test.ts +0 -26
- package/src/config.ts +47 -6
- package/src/core/capacity-assignments.ts +10 -0
- package/src/core/demand.test.ts +29 -29
- package/src/core/demand.ts +22 -22
- package/src/core/entities/capacity-assignment.ts +8 -0
- package/src/core/entities/ephemeral-registration-token.ts +1 -1
- package/src/core/entities/provisioner-capability-snapshot.ts +12 -0
- package/src/core/entities/provisioner-token.ts +8 -2
- package/src/core/entities/{provisioned-runner.ts → runner-instance.ts} +5 -5
- package/src/core/entities/runner-session.ts +4 -2
- package/src/core/ephemeral-registration-tokens.test.ts +11 -11
- package/src/core/ephemeral-registration-tokens.ts +18 -20
- package/src/core/errors.ts +23 -4
- package/src/core/index.ts +39 -17
- package/src/core/job-executions.ts +3 -2
- package/src/core/maintenance.test.ts +13 -17
- package/src/core/maintenance.ts +5 -5
- package/src/core/provisioner-capability-snapshots.test.ts +35 -0
- package/src/core/provisioner-capability-snapshots.ts +12 -0
- package/src/core/provisioner-tokens.test.ts +20 -0
- package/src/core/provisioner-tokens.ts +33 -0
- package/src/core/rate-limit.test.ts +11 -27
- package/src/core/rate-limit.ts +3 -11
- package/src/core/runner-activation.ts +72 -0
- package/src/core/runner-control-sessions.ts +190 -0
- package/src/core/{provisioned-runners.test.ts → runner-instances.test.ts} +24 -24
- package/src/core/runner-instances.ts +310 -0
- package/src/core/runner-sessions.test.ts +112 -22
- package/src/core/runner-sessions.ts +25 -14
- package/src/db/capacity-assignments.test.ts +159 -0
- package/src/db/capacity-assignments.ts +116 -0
- package/src/db/db.ts +11 -2
- package/src/db/ephemeral-registration-tokens.test.ts +9 -9
- package/src/db/ephemeral-registration-tokens.ts +26 -26
- package/src/db/index.ts +31 -21
- package/src/db/job-executions.test.ts +13 -11
- package/src/db/job-executions.ts +33 -27
- package/src/db/provisioner-capability-snapshots.test.ts +175 -0
- package/src/db/provisioner-capability-snapshots.ts +130 -0
- package/src/db/provisioner-tokens.test.ts +139 -2
- package/src/db/provisioner-tokens.ts +123 -15
- package/src/db/reservations.test.ts +49 -0
- package/src/db/reservations.ts +146 -1
- package/src/db/{provisioned-runners.test.ts → runner-instances.test.ts} +429 -353
- package/src/db/runner-instances.ts +942 -0
- package/src/db/runner-sessions.test.ts +19 -6
- package/src/db/runner-sessions.ts +78 -2
- package/src/db/schema/capacity-assignments.ts +34 -0
- package/src/db/schema/ephemeral-registration-tokens.ts +4 -4
- package/src/db/schema/provisioner-capability-snapshots.ts +46 -0
- package/src/db/schema/provisioner-tokens.ts +33 -2
- package/src/db/schema/runner-activation-tokens.ts +22 -0
- package/src/db/schema/runner-control-sessions.ts +46 -0
- package/src/db/schema/{provisioned-runners.ts → runner-instances.ts} +26 -27
- package/src/db/schema/runner-sessions.ts +11 -7
- package/src/db/schema/running-job-executions.ts +5 -5
- package/src/index.test.ts +26 -0
- package/src/index.ts +39 -19
- package/src/installation-provisioning.ts +14 -0
- package/src/metrics/index.ts +5 -5
- package/src/metrics/instance.ts +25 -14
- package/src/presentation/auth/index.ts +4 -0
- package/src/presentation/auth/provisioner-token-auth.ts +8 -4
- package/src/presentation/auth/runner-control-session-auth.ts +31 -0
- package/src/presentation/auth/runner-registration-token-auth.ts +39 -3
- package/src/presentation/dto/index.ts +5 -5
- package/src/presentation/dto/mint-registration-tokens.ts +8 -15
- package/src/presentation/dto/poll-demand.ts +3 -1
- package/src/presentation/dto/provisioner-token.ts +5 -0
- package/src/presentation/dto/{provisioned-runners.ts → runner-instances.ts} +13 -15
- package/src/presentation/index.ts +2 -1
- package/src/presentation/inter-module.test.ts +15 -0
- package/src/presentation/inter-module.ts +53 -0
- package/src/presentation/routes/assign-capacity.ts +48 -0
- package/src/presentation/routes/get-provisioner-me.ts +3 -4
- package/src/presentation/routes/heartbeat.test.ts +4 -3
- package/src/presentation/routes/heartbeat.ts +67 -64
- package/src/presentation/routes/index.ts +93 -43
- package/src/presentation/routes/list-active-runners.test.ts +23 -23
- package/src/presentation/routes/manual-registration-tokens.test.ts +4 -3
- package/src/presentation/routes/mint-registration-tokens.test.ts +12 -12
- package/src/presentation/routes/mint-registration-tokens.ts +5 -7
- package/src/presentation/routes/planned-capacity.ts +49 -0
- package/src/presentation/routes/poll-demand-release.test.ts +4 -4
- package/src/presentation/routes/poll-demand.test.ts +161 -22
- package/src/presentation/routes/poll-demand.ts +105 -45
- package/src/presentation/routes/provisioner-me.test.ts +37 -3
- package/src/presentation/routes/{reconcile-provisioned-runners.test.ts → reconcile-runner-instances.test.ts} +66 -61
- package/src/presentation/routes/reconcile-runner-instances.ts +30 -0
- package/src/presentation/routes/register.test.ts +9 -5
- package/src/presentation/routes/register.ts +61 -57
- package/src/presentation/routes/{report-provisioned-runners.test.ts → report-runner-instances.test.ts} +28 -28
- package/src/presentation/routes/{report-provisioned-runners.ts → report-runner-instances.ts} +14 -14
- package/src/presentation/routes/request-job.test.ts +5 -3
- package/src/presentation/routes/request-job.ts +41 -37
- package/src/presentation/routes/runner-enrollment.test.ts +259 -0
- package/src/presentation/routes/runner-enrollment.ts +174 -0
- package/src/temporal/activities/index.ts +2 -2
- package/src/temporal/activities/maintenance-activities.test.ts +7 -7
- package/src/temporal/activities/maintenance-activities.ts +3 -3
- package/src/temporal/workflows/stuck-job-detector.test.ts +3 -3
- package/src/temporal/workflows/stuck-job-detector.ts +2 -2
- package/test/env.ts +1 -3
- package/test/factories/ephemeral-registration-token.ts +2 -2
- package/test/factories/provisioner-token.ts +3 -1
- package/test/factories/runner-instance.ts +57 -0
- package/test/factories/runner-session.ts +3 -1
- package/test/fixtures/auth-inter-module.ts +30 -0
- package/test/globalSetup.ts +5 -1
- package/test/index.ts +2 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/core/entities/provisioned-runner.d.ts.map +0 -1
- package/dist/core/entities/provisioned-runner.js +0 -3
- package/dist/core/entities/provisioned-runner.js.map +0 -1
- package/dist/core/provisioned-runners.d.ts +0 -67
- package/dist/core/provisioned-runners.d.ts.map +0 -1
- package/dist/core/provisioned-runners.js +0 -162
- package/dist/core/provisioned-runners.js.map +0 -1
- package/dist/db/provisioned-runners.d.ts +0 -79
- package/dist/db/provisioned-runners.d.ts.map +0 -1
- package/dist/db/provisioned-runners.js +0 -466
- package/dist/db/provisioned-runners.js.map +0 -1
- package/dist/db/schema/provisioned-runners.d.ts.map +0 -1
- package/dist/db/schema/provisioned-runners.js.map +0 -1
- package/dist/presentation/dto/provisioned-runners.d.ts.map +0 -1
- package/dist/presentation/dto/provisioned-runners.js.map +0 -1
- package/dist/presentation/routes/reconcile-provisioned-runners.d.ts +0 -2
- package/dist/presentation/routes/reconcile-provisioned-runners.d.ts.map +0 -1
- package/dist/presentation/routes/reconcile-provisioned-runners.js +0 -27
- package/dist/presentation/routes/reconcile-provisioned-runners.js.map +0 -1
- package/dist/presentation/routes/report-provisioned-runners.d.ts +0 -2
- package/dist/presentation/routes/report-provisioned-runners.d.ts.map +0 -1
- package/dist/presentation/routes/report-provisioned-runners.js +0 -37
- package/dist/presentation/routes/report-provisioned-runners.js.map +0 -1
- package/src/core/provisioned-runners.ts +0 -301
- package/src/db/provisioned-runners.ts +0 -886
- package/src/presentation/routes/reconcile-provisioned-runners.ts +0 -30
- package/test/factories/provisioned-runner.ts +0 -78
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { attachProviderRunnerId as attachProviderRunnerIdDb, createPlannedProvisionedCapacity as createPlannedProvisionedCapacityDb, isTerminalState, listActiveRunnerInstances, listActiveRunningJobExecutions, reconcileRunnerInstances as reconcileRunnerInstancesDb, reportRunnerInstances as reportRunnerInstancesDb } from '#db/index.js';
|
|
2
|
+
import { providerRunnerAbsentTerminatedCount, providerRunnerReconcileCallCount, providerRunnerReportCount, providerRunnerTerminateIntentHonoredCount, providerRunnerTerminateIntentIssuedCount, reservationReleasedCount } from '#metrics/instance.js';
|
|
3
|
+
import { config } from '../config.js';
|
|
4
|
+
export function createPlannedProvisionedCapacity(params) {
|
|
5
|
+
return createPlannedProvisionedCapacityDb(params);
|
|
6
|
+
}
|
|
7
|
+
export function attachProviderRunnerId(params) {
|
|
8
|
+
return attachProviderRunnerIdDb(params);
|
|
9
|
+
}
|
|
10
|
+
export async function reportRunnerInstances(params) {
|
|
11
|
+
const result = await reportRunnerInstancesDb(params);
|
|
12
|
+
for (const event of params.events){
|
|
13
|
+
providerRunnerReportCount.add(1, {
|
|
14
|
+
state: event.state
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
for (const intent of result.terminateIntentsHonored){
|
|
18
|
+
providerRunnerTerminateIntentHonoredCount.add(1, {
|
|
19
|
+
reason: intent.reason
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
if (result.reservationsReleased > 0) reservationReleasedCount.add(result.reservationsReleased);
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
export async function reconcileRunnerInstances(params) {
|
|
26
|
+
const result = await reconcileRunnerInstancesDb({
|
|
27
|
+
...params,
|
|
28
|
+
terminateGraceSeconds: config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS
|
|
29
|
+
});
|
|
30
|
+
if (result.reservationsReleased > 0) reservationReleasedCount.add(result.reservationsReleased);
|
|
31
|
+
providerRunnerReconcileCallCount.add(1);
|
|
32
|
+
if (result.absentIds.length > 0) providerRunnerAbsentTerminatedCount.add(result.absentIds.length);
|
|
33
|
+
const runners = reconcileRunnerInstancesFromDbResult({
|
|
34
|
+
observedRunnerInstanceIds: params.observedRunnerInstanceIds,
|
|
35
|
+
observedRows: result.observedRows,
|
|
36
|
+
boundJobExecutionsByRunnerInstanceId: result.boundJobExecutionsByRunnerInstanceId
|
|
37
|
+
});
|
|
38
|
+
for (const runner of runners){
|
|
39
|
+
if (runner.desiredIntentReason) {
|
|
40
|
+
providerRunnerTerminateIntentIssuedCount.add(1, {
|
|
41
|
+
surface: 'reconcile',
|
|
42
|
+
reason: runner.desiredIntentReason
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
runners,
|
|
48
|
+
terminatedAbsentRunnerInstanceIds: result.absentIds
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function reconcileRunnerInstancesFromDbResult(params) {
|
|
52
|
+
const rowsByRunnerInstanceId = new Map(params.observedRows.map((row)=>[
|
|
53
|
+
row.providerRunnerId,
|
|
54
|
+
row
|
|
55
|
+
]));
|
|
56
|
+
return params.observedRunnerInstanceIds.map((providerRunnerId)=>{
|
|
57
|
+
const row = rowsByRunnerInstanceId.get(providerRunnerId);
|
|
58
|
+
const boundJobExecution = params.boundJobExecutionsByRunnerInstanceId.get(providerRunnerId);
|
|
59
|
+
const desiredIntentReason = getDesiredIntentReason(row, boundJobExecution);
|
|
60
|
+
return {
|
|
61
|
+
providerRunnerId,
|
|
62
|
+
state: row?.state ?? null,
|
|
63
|
+
reservationId: row?.reservationId ?? null,
|
|
64
|
+
runnerSessionId: row?.runnerSessionId ?? null,
|
|
65
|
+
boundJobExecution: boundJobExecution ? toReconciledBoundJobExecution(boundJobExecution) : null,
|
|
66
|
+
desiredIntent: desiredIntentReason ? 'terminate' : 'keep',
|
|
67
|
+
desiredIntentReason
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export async function listActiveRunners(params) {
|
|
72
|
+
const [providerRunnerRows, jobExecutionRows] = await Promise.all([
|
|
73
|
+
listActiveRunnerInstances({
|
|
74
|
+
workspaceId: params.workspaceId,
|
|
75
|
+
windowSeconds: config.RUNNER_ACTIVE_WINDOW_SECONDS
|
|
76
|
+
}),
|
|
77
|
+
listActiveRunningJobExecutions({
|
|
78
|
+
workspaceId: params.workspaceId,
|
|
79
|
+
windowSeconds: config.RUNNER_ACTIVE_WINDOW_SECONDS
|
|
80
|
+
})
|
|
81
|
+
]);
|
|
82
|
+
return mergeActiveRunners(providerRunnerRows, jobExecutionRows);
|
|
83
|
+
}
|
|
84
|
+
function toReconciledBoundJobExecution(jobExecution) {
|
|
85
|
+
return {
|
|
86
|
+
jobId: jobExecution.jobId,
|
|
87
|
+
jobExecutionId: jobExecution.jobExecutionId,
|
|
88
|
+
workflowRunAttemptId: jobExecution.workflowRunAttemptId,
|
|
89
|
+
lastHeartbeatAt: jobExecution.lastHeartbeatAt,
|
|
90
|
+
cancellationRequestedAt: jobExecution.cancellationRequestedAt
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export function desiredIntent(row, boundJobExecution) {
|
|
94
|
+
return getDesiredIntentReason(row, boundJobExecution) ? 'terminate' : 'keep';
|
|
95
|
+
}
|
|
96
|
+
function getDesiredIntentReason(row, boundJobExecution) {
|
|
97
|
+
if (!row) return null;
|
|
98
|
+
if (isTerminalState(row.state)) return 'terminal-state';
|
|
99
|
+
if (boundJobExecution?.cancellationRequestedAt) return 'job-cancelled';
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
function mergeActiveRunners(providerRunners, jobExecutions) {
|
|
103
|
+
const jobExecutionsByRunnerSessionId = new Map();
|
|
104
|
+
const jobExecutionsByRunnerInstanceId = new Map();
|
|
105
|
+
for (const jobExecution of jobExecutions){
|
|
106
|
+
const runnerJobExecutions = jobExecutionsByRunnerSessionId.get(jobExecution.runnerSessionId) ?? [];
|
|
107
|
+
runnerJobExecutions.push(jobExecution);
|
|
108
|
+
jobExecutionsByRunnerSessionId.set(jobExecution.runnerSessionId, runnerJobExecutions);
|
|
109
|
+
if (jobExecution.provisionerId && jobExecution.providerRunnerId) {
|
|
110
|
+
const key = providerRunnerKey(jobExecution.provisionerId, jobExecution.providerRunnerId);
|
|
111
|
+
const providerRunnerJobExecutions = jobExecutionsByRunnerInstanceId.get(key) ?? [];
|
|
112
|
+
providerRunnerJobExecutions.push(jobExecution);
|
|
113
|
+
jobExecutionsByRunnerInstanceId.set(key, providerRunnerJobExecutions);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const merged = [];
|
|
117
|
+
const usedJobExecutionIds = new Set();
|
|
118
|
+
for (const providerRunner of providerRunners){
|
|
119
|
+
const providerRunnerJobExecutions = jobExecutionsByRunnerInstanceId.get(providerRunnerKey(providerRunner.provisionerId, providerRunner.providerRunnerId)) ?? (providerRunner.runnerSessionId ? jobExecutionsByRunnerSessionId.get(providerRunner.runnerSessionId) : undefined);
|
|
120
|
+
if (!providerRunnerJobExecutions || providerRunnerJobExecutions.length === 0) {
|
|
121
|
+
merged.push(toActiveRunner(providerRunner, undefined));
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
let emitted = false;
|
|
125
|
+
for (const jobExecution of providerRunnerJobExecutions){
|
|
126
|
+
if (usedJobExecutionIds.has(jobExecution.jobExecutionId)) continue;
|
|
127
|
+
usedJobExecutionIds.add(jobExecution.jobExecutionId);
|
|
128
|
+
merged.push(toActiveRunner(providerRunner, jobExecution));
|
|
129
|
+
emitted = true;
|
|
130
|
+
}
|
|
131
|
+
if (!emitted) merged.push(toActiveRunner(providerRunner, undefined));
|
|
132
|
+
}
|
|
133
|
+
for (const jobExecution of jobExecutions){
|
|
134
|
+
if (usedJobExecutionIds.has(jobExecution.jobExecutionId)) continue;
|
|
135
|
+
merged.push(toActiveRunner(undefined, jobExecution));
|
|
136
|
+
}
|
|
137
|
+
return merged.sort(compareActiveRunners);
|
|
138
|
+
}
|
|
139
|
+
function providerRunnerKey(provisionerId, providerRunnerId) {
|
|
140
|
+
return `${provisionerId}:${providerRunnerId}`;
|
|
141
|
+
}
|
|
142
|
+
function toActiveRunner(providerRunner, jobExecution) {
|
|
143
|
+
return {
|
|
144
|
+
runnerSessionId: providerRunner?.runnerSessionId ?? jobExecution?.runnerSessionId ?? null,
|
|
145
|
+
providerRunnerId: providerRunner?.providerRunnerId ?? jobExecution?.providerRunnerId ?? null,
|
|
146
|
+
provisionerId: providerRunner?.provisionerId ?? jobExecution?.provisionerId ?? null,
|
|
147
|
+
state: jobExecution ? 'busy' : toActiveRunnerState(providerRunner?.state ?? 'running'),
|
|
148
|
+
labels: providerRunner?.labels ?? jobExecution?.runnerLabels ?? [],
|
|
149
|
+
templateKey: providerRunner?.templateKey ?? null,
|
|
150
|
+
providerKind: providerRunner?.providerKind ?? null,
|
|
151
|
+
jobId: jobExecution?.jobId ?? null,
|
|
152
|
+
workflowRunAttemptId: jobExecution?.workflowRunAttemptId ?? null,
|
|
153
|
+
projectId: jobExecution?.projectId ?? null,
|
|
154
|
+
reportedAt: providerRunner?.reportedAt ?? null,
|
|
155
|
+
lastHeartbeatAt: jobExecution?.lastHeartbeatAt ?? null
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function toActiveRunnerState(state) {
|
|
159
|
+
if (state === 'starting' || state === 'stopping') return state;
|
|
160
|
+
return 'running';
|
|
161
|
+
}
|
|
162
|
+
function compareActiveRunners(a, b) {
|
|
163
|
+
const aTime = Math.max(a.lastHeartbeatAt?.getTime() ?? 0, a.reportedAt?.getTime() ?? 0);
|
|
164
|
+
const bTime = Math.max(b.lastHeartbeatAt?.getTime() ?? 0, b.reportedAt?.getTime() ?? 0);
|
|
165
|
+
return bTime - aTime;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
//# sourceMappingURL=runner-instances.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/runner-instances.ts"],"sourcesContent":["import type {RunnerInstance, RunnerInstanceState} from '#core/entities/runner-instance.js';\nimport {\n attachProviderRunnerId as attachProviderRunnerIdDb,\n createPlannedProvisionedCapacity as createPlannedProvisionedCapacityDb,\n isTerminalState,\n listActiveRunnerInstances,\n listActiveRunningJobExecutions,\n type RunnerInstanceReportEvent,\n reconcileRunnerInstances as reconcileRunnerInstancesDb,\n reportRunnerInstances as reportRunnerInstancesDb,\n} from '#db/index.js';\nimport type {\n ActiveRunningJobExecution,\n RunnerInstanceBoundJobExecution,\n} from '#db/job-executions.js';\nimport {\n providerRunnerAbsentTerminatedCount,\n providerRunnerReconcileCallCount,\n providerRunnerReportCount,\n providerRunnerTerminateIntentHonoredCount,\n providerRunnerTerminateIntentIssuedCount,\n reservationReleasedCount,\n} from '#metrics/instance.js';\nimport {config} from '../config.js';\n\nexport interface ReportRunnerInstancesParams {\n workspaceId: string | null;\n provisionerId: string;\n events: RunnerInstanceReportEvent[];\n}\n\nexport function createPlannedProvisionedCapacity(params: {\n provisionerId: string;\n providerKind: string | null;\n templateKey: string | null;\n}): Promise<{capacityId: string}> {\n return createPlannedProvisionedCapacityDb(params);\n}\n\nexport function attachProviderRunnerId(params: {\n capacityId: string;\n provisionerId: string;\n providerRunnerId: string;\n}): Promise<boolean> {\n return attachProviderRunnerIdDb(params);\n}\n\nexport interface ReportRunnerInstancesResult {\n accepted: number;\n reservationsReleased: number;\n}\n\nexport interface ReconcileRunnerInstancesParams {\n workspaceId: string | null;\n provisionerId: string;\n observedRunnerInstanceIds: string[];\n}\n\nexport type ReconcileDesiredIntent = 'keep' | 'terminate';\ntype ReconcileDesiredIntentReason = 'job-cancelled' | 'terminal-state';\n\nexport interface ReconciledBoundJobExecution {\n jobId: string;\n jobExecutionId: string;\n workflowRunAttemptId: string;\n lastHeartbeatAt: Date;\n cancellationRequestedAt: Date | null;\n}\n\nexport interface ReconciledRunnerInstance {\n providerRunnerId: string;\n state: RunnerInstanceState | null;\n reservationId: string | null;\n runnerSessionId: string | null;\n boundJobExecution: ReconciledBoundJobExecution | null;\n desiredIntent: ReconcileDesiredIntent;\n desiredIntentReason: ReconcileDesiredIntentReason | null;\n}\n\nexport interface ReconcileRunnerInstancesResult {\n runners: ReconciledRunnerInstance[];\n terminatedAbsentRunnerInstanceIds: string[];\n}\n\nexport type ActiveRunnerState = 'starting' | 'running' | 'stopping' | 'busy';\n\nexport interface ActiveRunner {\n runnerSessionId: string | null;\n providerRunnerId: string | null;\n provisionerId: string | null;\n state: ActiveRunnerState;\n labels: string[];\n templateKey: string | null;\n providerKind: string | null;\n jobId: string | null;\n workflowRunAttemptId: string | null;\n projectId: string | null;\n reportedAt: Date | null;\n lastHeartbeatAt: Date | null;\n}\n\nexport async function reportRunnerInstances(\n params: ReportRunnerInstancesParams,\n): Promise<ReportRunnerInstancesResult> {\n const result = await reportRunnerInstancesDb(params);\n\n for (const event of params.events) {\n providerRunnerReportCount.add(1, {state: event.state});\n }\n for (const intent of result.terminateIntentsHonored) {\n providerRunnerTerminateIntentHonoredCount.add(1, {reason: intent.reason});\n }\n if (result.reservationsReleased > 0) reservationReleasedCount.add(result.reservationsReleased);\n\n return result;\n}\n\nexport async function reconcileRunnerInstances(\n params: ReconcileRunnerInstancesParams,\n): Promise<ReconcileRunnerInstancesResult> {\n const result = await reconcileRunnerInstancesDb({\n ...params,\n terminateGraceSeconds: config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS,\n });\n\n if (result.reservationsReleased > 0) reservationReleasedCount.add(result.reservationsReleased);\n providerRunnerReconcileCallCount.add(1);\n if (result.absentIds.length > 0) providerRunnerAbsentTerminatedCount.add(result.absentIds.length);\n\n const runners = reconcileRunnerInstancesFromDbResult({\n observedRunnerInstanceIds: params.observedRunnerInstanceIds,\n observedRows: result.observedRows,\n boundJobExecutionsByRunnerInstanceId: result.boundJobExecutionsByRunnerInstanceId,\n });\n for (const runner of runners) {\n if (runner.desiredIntentReason) {\n providerRunnerTerminateIntentIssuedCount.add(1, {\n surface: 'reconcile',\n reason: runner.desiredIntentReason,\n });\n }\n }\n\n return {\n runners,\n terminatedAbsentRunnerInstanceIds: result.absentIds,\n };\n}\n\nexport function reconcileRunnerInstancesFromDbResult(params: {\n observedRunnerInstanceIds: string[];\n observedRows: RunnerInstance[];\n boundJobExecutionsByRunnerInstanceId: Map<string, RunnerInstanceBoundJobExecution>;\n}): ReconciledRunnerInstance[] {\n const rowsByRunnerInstanceId = new Map(\n params.observedRows.map((row) => [row.providerRunnerId, row]),\n );\n\n return params.observedRunnerInstanceIds.map((providerRunnerId) => {\n const row = rowsByRunnerInstanceId.get(providerRunnerId);\n const boundJobExecution = params.boundJobExecutionsByRunnerInstanceId.get(providerRunnerId);\n\n const desiredIntentReason = getDesiredIntentReason(row, boundJobExecution);\n\n return {\n providerRunnerId,\n state: row?.state ?? null,\n reservationId: row?.reservationId ?? null,\n runnerSessionId: row?.runnerSessionId ?? null,\n boundJobExecution: boundJobExecution\n ? toReconciledBoundJobExecution(boundJobExecution)\n : null,\n desiredIntent: desiredIntentReason ? 'terminate' : 'keep',\n desiredIntentReason,\n };\n });\n}\n\nexport async function listActiveRunners(params: {workspaceId: string}): Promise<ActiveRunner[]> {\n const [providerRunnerRows, jobExecutionRows] = await Promise.all([\n listActiveRunnerInstances({\n workspaceId: params.workspaceId,\n windowSeconds: config.RUNNER_ACTIVE_WINDOW_SECONDS,\n }),\n listActiveRunningJobExecutions({\n workspaceId: params.workspaceId,\n windowSeconds: config.RUNNER_ACTIVE_WINDOW_SECONDS,\n }),\n ]);\n\n return mergeActiveRunners(providerRunnerRows, jobExecutionRows);\n}\n\nfunction toReconciledBoundJobExecution(\n jobExecution: RunnerInstanceBoundJobExecution,\n): ReconciledBoundJobExecution {\n return {\n jobId: jobExecution.jobId,\n jobExecutionId: jobExecution.jobExecutionId,\n workflowRunAttemptId: jobExecution.workflowRunAttemptId,\n lastHeartbeatAt: jobExecution.lastHeartbeatAt,\n cancellationRequestedAt: jobExecution.cancellationRequestedAt,\n };\n}\n\nexport function desiredIntent(\n row: RunnerInstance | undefined,\n boundJobExecution: RunnerInstanceBoundJobExecution | undefined,\n): ReconcileDesiredIntent {\n return getDesiredIntentReason(row, boundJobExecution) ? 'terminate' : 'keep';\n}\n\nfunction getDesiredIntentReason(\n row: RunnerInstance | undefined,\n boundJobExecution: RunnerInstanceBoundJobExecution | undefined,\n): ReconcileDesiredIntentReason | null {\n if (!row) return null;\n if (isTerminalState(row.state)) return 'terminal-state';\n if (boundJobExecution?.cancellationRequestedAt) return 'job-cancelled';\n return null;\n}\n\nfunction mergeActiveRunners(\n providerRunners: RunnerInstance[],\n jobExecutions: ActiveRunningJobExecution[],\n): ActiveRunner[] {\n const jobExecutionsByRunnerSessionId = new Map<string, ActiveRunningJobExecution[]>();\n const jobExecutionsByRunnerInstanceId = new Map<string, ActiveRunningJobExecution[]>();\n for (const jobExecution of jobExecutions) {\n const runnerJobExecutions =\n jobExecutionsByRunnerSessionId.get(jobExecution.runnerSessionId) ?? [];\n runnerJobExecutions.push(jobExecution);\n jobExecutionsByRunnerSessionId.set(jobExecution.runnerSessionId, runnerJobExecutions);\n\n if (jobExecution.provisionerId && jobExecution.providerRunnerId) {\n const key = providerRunnerKey(jobExecution.provisionerId, jobExecution.providerRunnerId);\n const providerRunnerJobExecutions = jobExecutionsByRunnerInstanceId.get(key) ?? [];\n providerRunnerJobExecutions.push(jobExecution);\n jobExecutionsByRunnerInstanceId.set(key, providerRunnerJobExecutions);\n }\n }\n\n const merged: ActiveRunner[] = [];\n const usedJobExecutionIds = new Set<string>();\n\n for (const providerRunner of providerRunners) {\n const providerRunnerJobExecutions =\n jobExecutionsByRunnerInstanceId.get(\n providerRunnerKey(providerRunner.provisionerId, providerRunner.providerRunnerId),\n ) ??\n (providerRunner.runnerSessionId\n ? jobExecutionsByRunnerSessionId.get(providerRunner.runnerSessionId)\n : undefined);\n if (!providerRunnerJobExecutions || providerRunnerJobExecutions.length === 0) {\n merged.push(toActiveRunner(providerRunner, undefined));\n continue;\n }\n\n let emitted = false;\n for (const jobExecution of providerRunnerJobExecutions) {\n if (usedJobExecutionIds.has(jobExecution.jobExecutionId)) continue;\n usedJobExecutionIds.add(jobExecution.jobExecutionId);\n merged.push(toActiveRunner(providerRunner, jobExecution));\n emitted = true;\n }\n if (!emitted) merged.push(toActiveRunner(providerRunner, undefined));\n }\n\n for (const jobExecution of jobExecutions) {\n if (usedJobExecutionIds.has(jobExecution.jobExecutionId)) continue;\n merged.push(toActiveRunner(undefined, jobExecution));\n }\n\n return merged.sort(compareActiveRunners);\n}\n\nfunction providerRunnerKey(provisionerId: string, providerRunnerId: string): string {\n return `${provisionerId}:${providerRunnerId}`;\n}\n\nfunction toActiveRunner(\n providerRunner: RunnerInstance | undefined,\n jobExecution: ActiveRunningJobExecution | undefined,\n): ActiveRunner {\n return {\n runnerSessionId: providerRunner?.runnerSessionId ?? jobExecution?.runnerSessionId ?? null,\n providerRunnerId: providerRunner?.providerRunnerId ?? jobExecution?.providerRunnerId ?? null,\n provisionerId: providerRunner?.provisionerId ?? jobExecution?.provisionerId ?? null,\n state: jobExecution ? 'busy' : toActiveRunnerState(providerRunner?.state ?? 'running'),\n labels: providerRunner?.labels ?? jobExecution?.runnerLabels ?? [],\n templateKey: providerRunner?.templateKey ?? null,\n providerKind: providerRunner?.providerKind ?? null,\n jobId: jobExecution?.jobId ?? null,\n workflowRunAttemptId: jobExecution?.workflowRunAttemptId ?? null,\n projectId: jobExecution?.projectId ?? null,\n reportedAt: providerRunner?.reportedAt ?? null,\n lastHeartbeatAt: jobExecution?.lastHeartbeatAt ?? null,\n };\n}\n\nfunction toActiveRunnerState(state: RunnerInstanceState): ActiveRunnerState {\n if (state === 'starting' || state === 'stopping') return state;\n return 'running';\n}\n\nfunction compareActiveRunners(a: ActiveRunner, b: ActiveRunner): number {\n const aTime = Math.max(a.lastHeartbeatAt?.getTime() ?? 0, a.reportedAt?.getTime() ?? 0);\n const bTime = Math.max(b.lastHeartbeatAt?.getTime() ?? 0, b.reportedAt?.getTime() ?? 0);\n return bTime - aTime;\n}\n"],"names":["attachProviderRunnerId","attachProviderRunnerIdDb","createPlannedProvisionedCapacity","createPlannedProvisionedCapacityDb","isTerminalState","listActiveRunnerInstances","listActiveRunningJobExecutions","reconcileRunnerInstances","reconcileRunnerInstancesDb","reportRunnerInstances","reportRunnerInstancesDb","providerRunnerAbsentTerminatedCount","providerRunnerReconcileCallCount","providerRunnerReportCount","providerRunnerTerminateIntentHonoredCount","providerRunnerTerminateIntentIssuedCount","reservationReleasedCount","config","params","result","event","events","add","state","intent","terminateIntentsHonored","reason","reservationsReleased","terminateGraceSeconds","RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS","absentIds","length","runners","reconcileRunnerInstancesFromDbResult","observedRunnerInstanceIds","observedRows","boundJobExecutionsByRunnerInstanceId","runner","desiredIntentReason","surface","terminatedAbsentRunnerInstanceIds","rowsByRunnerInstanceId","Map","map","row","providerRunnerId","get","boundJobExecution","getDesiredIntentReason","reservationId","runnerSessionId","toReconciledBoundJobExecution","desiredIntent","listActiveRunners","providerRunnerRows","jobExecutionRows","Promise","all","workspaceId","windowSeconds","RUNNER_ACTIVE_WINDOW_SECONDS","mergeActiveRunners","jobExecution","jobId","jobExecutionId","workflowRunAttemptId","lastHeartbeatAt","cancellationRequestedAt","providerRunners","jobExecutions","jobExecutionsByRunnerSessionId","jobExecutionsByRunnerInstanceId","runnerJobExecutions","push","set","provisionerId","key","providerRunnerKey","providerRunnerJobExecutions","merged","usedJobExecutionIds","Set","providerRunner","undefined","toActiveRunner","emitted","has","sort","compareActiveRunners","toActiveRunnerState","labels","runnerLabels","templateKey","providerKind","projectId","reportedAt","a","b","aTime","Math","max","getTime","bTime"],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import type { AuthInterModuleClient } from '@shipfox/api-auth-dto/inter-module';
|
|
1
2
|
import type { RunnerToolCapabilitiesDto } from '@shipfox/api-runners-dto';
|
|
2
3
|
import type { RunnerSession } from './entities/runner-session.js';
|
|
3
4
|
export interface RegisterRunnerSessionResult {
|
|
4
5
|
session: RunnerSession;
|
|
5
6
|
sessionToken: string;
|
|
6
|
-
mode: 'manual' | 'ephemeral';
|
|
7
|
+
mode: 'manual' | 'ephemeral' | 'activation';
|
|
7
8
|
maxClaims: number | null;
|
|
8
9
|
}
|
|
9
10
|
export type RunnerRegistrationCredential = {
|
|
@@ -16,9 +17,14 @@ export type RunnerRegistrationCredential = {
|
|
|
16
17
|
workspaceId: string;
|
|
17
18
|
provisionerId: string;
|
|
18
19
|
reservationId: string | null;
|
|
19
|
-
|
|
20
|
+
providerRunnerId: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'activation';
|
|
23
|
+
activationTokenId: string;
|
|
24
|
+
workspaceId: string;
|
|
20
25
|
};
|
|
21
26
|
export declare function registerRunnerSession(params: {
|
|
27
|
+
auth: AuthInterModuleClient;
|
|
22
28
|
credential: RunnerRegistrationCredential;
|
|
23
29
|
labels: string[];
|
|
24
30
|
toolCapabilities?: RunnerToolCapabilitiesDto | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-sessions.d.ts","sourceRoot":"","sources":["../../src/core/runner-sessions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner-sessions.d.ts","sourceRoot":"","sources":["../../src/core/runner-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC;AAOxE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,8BAA8B,CAAC;AAGhE,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,aAAa,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,QAAQ,GAAG,WAAW,GAAG,YAAY,CAAC;IAC5C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,MAAM,4BAA4B,GACpC;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;CAC1B,GACD;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,CAAC;AAEzE,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,IAAI,EAAE,qBAAqB,CAAC;IAC5B,UAAU,EAAE,4BAA4B,CAAC;IACzC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACrD,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAqCvC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { issueRunnerSessionToken } from '@shipfox/api-auth';
|
|
2
1
|
import { canonicalizeLabels } from '@shipfox/runner-labels';
|
|
3
2
|
import { createRunnerSessionConsumingEphemeralToken } from '#db/ephemeral-registration-tokens.js';
|
|
4
|
-
import { createRunnerSession } from '#db/runner-sessions.js';
|
|
3
|
+
import { createRunnerSession, createRunnerSessionConsumingActivationToken } from '#db/runner-sessions.js';
|
|
5
4
|
import { EmptyRunnerLabelsError } from './errors.js';
|
|
6
5
|
export async function registerRunnerSession(params) {
|
|
7
6
|
const labels = [
|
|
@@ -9,21 +8,25 @@ export async function registerRunnerSession(params) {
|
|
|
9
8
|
];
|
|
10
9
|
if (labels.length === 0) throw new EmptyRunnerLabelsError();
|
|
11
10
|
const mode = params.credential.kind;
|
|
12
|
-
const maxClaims = params.credential.kind === '
|
|
11
|
+
const maxClaims = params.credential.kind === 'manual' ? null : 1;
|
|
13
12
|
const session = params.credential.kind === 'manual' ? await createRunnerSession({
|
|
14
13
|
workspaceId: params.credential.workspaceId,
|
|
15
14
|
scope: 'workspace',
|
|
16
15
|
registrationTokenId: params.credential.registrationTokenId,
|
|
17
16
|
labels,
|
|
18
17
|
toolCapabilities: params.toolCapabilities ?? null
|
|
19
|
-
}) : await createRunnerSessionConsumingEphemeralToken({
|
|
18
|
+
}) : params.credential.kind === 'ephemeral' ? await createRunnerSessionConsumingEphemeralToken({
|
|
20
19
|
ephemeralTokenId: params.credential.ephemeralTokenId,
|
|
21
20
|
workspaceId: params.credential.workspaceId,
|
|
22
21
|
labels,
|
|
23
22
|
toolCapabilities: params.toolCapabilities ?? null,
|
|
24
23
|
maxClaims: 1
|
|
24
|
+
}) : await createRunnerSessionConsumingActivationToken({
|
|
25
|
+
activationTokenId: params.credential.activationTokenId,
|
|
26
|
+
labels,
|
|
27
|
+
toolCapabilities: params.toolCapabilities ?? null
|
|
25
28
|
});
|
|
26
|
-
const sessionToken = await
|
|
29
|
+
const { token: sessionToken } = await params.auth.mintRunnerSessionToken({
|
|
27
30
|
runnerSessionId: session.id,
|
|
28
31
|
workspaceId: session.workspaceId,
|
|
29
32
|
scope: session.scope,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/runner-sessions.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/core/runner-sessions.ts"],"sourcesContent":["import type {AuthInterModuleClient} from '@shipfox/api-auth-dto/inter-module';\nimport type {RunnerToolCapabilitiesDto} from '@shipfox/api-runners-dto';\nimport {canonicalizeLabels} from '@shipfox/runner-labels';\nimport {createRunnerSessionConsumingEphemeralToken} from '#db/ephemeral-registration-tokens.js';\nimport {\n createRunnerSession,\n createRunnerSessionConsumingActivationToken,\n} from '#db/runner-sessions.js';\nimport type {RunnerSession} from './entities/runner-session.js';\nimport {EmptyRunnerLabelsError} from './errors.js';\n\nexport interface RegisterRunnerSessionResult {\n session: RunnerSession;\n sessionToken: string;\n mode: 'manual' | 'ephemeral' | 'activation';\n maxClaims: number | null;\n}\n\nexport type RunnerRegistrationCredential =\n | {\n kind: 'manual';\n registrationTokenId: string;\n workspaceId: string;\n }\n | {\n kind: 'ephemeral';\n ephemeralTokenId: string;\n workspaceId: string;\n provisionerId: string;\n reservationId: string | null;\n providerRunnerId: string;\n }\n | {kind: 'activation'; activationTokenId: string; workspaceId: string};\n\nexport async function registerRunnerSession(params: {\n auth: AuthInterModuleClient;\n credential: RunnerRegistrationCredential;\n labels: string[];\n toolCapabilities?: RunnerToolCapabilitiesDto | null;\n}): Promise<RegisterRunnerSessionResult> {\n const labels = [...canonicalizeLabels(params.labels)];\n if (labels.length === 0) throw new EmptyRunnerLabelsError();\n\n const mode = params.credential.kind;\n const maxClaims = params.credential.kind === 'manual' ? null : 1;\n const session =\n params.credential.kind === 'manual'\n ? await createRunnerSession({\n workspaceId: params.credential.workspaceId,\n scope: 'workspace',\n registrationTokenId: params.credential.registrationTokenId,\n labels,\n toolCapabilities: params.toolCapabilities ?? null,\n })\n : params.credential.kind === 'ephemeral'\n ? await createRunnerSessionConsumingEphemeralToken({\n ephemeralTokenId: params.credential.ephemeralTokenId,\n workspaceId: params.credential.workspaceId,\n labels,\n toolCapabilities: params.toolCapabilities ?? null,\n maxClaims: 1,\n })\n : await createRunnerSessionConsumingActivationToken({\n activationTokenId: params.credential.activationTokenId,\n labels,\n toolCapabilities: params.toolCapabilities ?? null,\n });\n const {token: sessionToken} = await params.auth.mintRunnerSessionToken({\n runnerSessionId: session.id,\n workspaceId: session.workspaceId,\n scope: session.scope,\n labels: session.labels,\n maxClaims,\n });\n\n return {session, sessionToken, mode, maxClaims};\n}\n"],"names":["canonicalizeLabels","createRunnerSessionConsumingEphemeralToken","createRunnerSession","createRunnerSessionConsumingActivationToken","EmptyRunnerLabelsError","registerRunnerSession","params","labels","length","mode","credential","kind","maxClaims","session","workspaceId","scope","registrationTokenId","toolCapabilities","ephemeralTokenId","activationTokenId","token","sessionToken","auth","mintRunnerSessionToken","runnerSessionId","id"],"mappings":"AAEA,SAAQA,kBAAkB,QAAO,yBAAyB;AAC1D,SAAQC,0CAA0C,QAAO,uCAAuC;AAChG,SACEC,mBAAmB,EACnBC,2CAA2C,QACtC,yBAAyB;AAEhC,SAAQC,sBAAsB,QAAO,cAAc;AAyBnD,OAAO,eAAeC,sBAAsBC,MAK3C;IACC,MAAMC,SAAS;WAAIP,mBAAmBM,OAAOC,MAAM;KAAE;IACrD,IAAIA,OAAOC,MAAM,KAAK,GAAG,MAAM,IAAIJ;IAEnC,MAAMK,OAAOH,OAAOI,UAAU,CAACC,IAAI;IACnC,MAAMC,YAAYN,OAAOI,UAAU,CAACC,IAAI,KAAK,WAAW,OAAO;IAC/D,MAAME,UACJP,OAAOI,UAAU,CAACC,IAAI,KAAK,WACvB,MAAMT,oBAAoB;QACxBY,aAAaR,OAAOI,UAAU,CAACI,WAAW;QAC1CC,OAAO;QACPC,qBAAqBV,OAAOI,UAAU,CAACM,mBAAmB;QAC1DT;QACAU,kBAAkBX,OAAOW,gBAAgB,IAAI;IAC/C,KACAX,OAAOI,UAAU,CAACC,IAAI,KAAK,cACzB,MAAMV,2CAA2C;QAC/CiB,kBAAkBZ,OAAOI,UAAU,CAACQ,gBAAgB;QACpDJ,aAAaR,OAAOI,UAAU,CAACI,WAAW;QAC1CP;QACAU,kBAAkBX,OAAOW,gBAAgB,IAAI;QAC7CL,WAAW;IACb,KACA,MAAMT,4CAA4C;QAChDgB,mBAAmBb,OAAOI,UAAU,CAACS,iBAAiB;QACtDZ;QACAU,kBAAkBX,OAAOW,gBAAgB,IAAI;IAC/C;IACR,MAAM,EAACG,OAAOC,YAAY,EAAC,GAAG,MAAMf,OAAOgB,IAAI,CAACC,sBAAsB,CAAC;QACrEC,iBAAiBX,QAAQY,EAAE;QAC3BX,aAAaD,QAAQC,WAAW;QAChCC,OAAOF,QAAQE,KAAK;QACpBR,QAAQM,QAAQN,MAAM;QACtBK;IACF;IAEA,OAAO;QAACC;QAASQ;QAAcZ;QAAMG;IAAS;AAChD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CapacityAssignment } from '#core/entities/capacity-assignment.js';
|
|
2
|
+
export declare function assignCapacityBatch(params: {
|
|
3
|
+
provisionerId: string;
|
|
4
|
+
reservationId: string;
|
|
5
|
+
capacityIds: string[];
|
|
6
|
+
}): Promise<CapacityAssignment[]>;
|
|
7
|
+
//# sourceMappingURL=capacity-assignments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capacity-assignments.d.ts","sourceRoot":"","sources":["../../src/db/capacity-assignments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,uCAAuC,CAAC;AAY9E,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAkGhC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { and, eq, inArray, sql } from 'drizzle-orm';
|
|
2
|
+
import { CapacityAlreadyAssignedError, CapacityNotAssignableError, ReservationExpiredError, ReservationNotFoundError } from '#core/errors.js';
|
|
3
|
+
import { db } from './db.js';
|
|
4
|
+
import { capacityAssignments, toCapacityAssignment } from './schema/capacity-assignments.js';
|
|
5
|
+
import { reservations } from './schema/reservations.js';
|
|
6
|
+
import { providerRunners } from './schema/runner-instances.js';
|
|
7
|
+
export async function assignCapacityBatch(params) {
|
|
8
|
+
return await db().transaction(async (tx)=>{
|
|
9
|
+
const lockKey = [
|
|
10
|
+
'runners_capacity_assignments',
|
|
11
|
+
params.provisionerId,
|
|
12
|
+
params.reservationId
|
|
13
|
+
].join(':');
|
|
14
|
+
await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${lockKey}))`);
|
|
15
|
+
for (const capacityId of [
|
|
16
|
+
...params.capacityIds
|
|
17
|
+
].sort()){
|
|
18
|
+
await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${[
|
|
19
|
+
'runners_capacity_assignments',
|
|
20
|
+
capacityId
|
|
21
|
+
].join(':')}))`);
|
|
22
|
+
}
|
|
23
|
+
const [reservation] = await tx.select().from(reservations).where(and(eq(reservations.id, params.reservationId), eq(reservations.provisionerId, params.provisionerId))).limit(1);
|
|
24
|
+
if (!reservation) throw new ReservationNotFoundError(params.reservationId);
|
|
25
|
+
if (reservation.expiresAt <= new Date()) throw new ReservationExpiredError(params.reservationId);
|
|
26
|
+
const existing = await tx.select().from(capacityAssignments).where(eq(capacityAssignments.reservationId, reservation.id));
|
|
27
|
+
const existingByCapacityId = new Map(existing.map((assignment)=>[
|
|
28
|
+
assignment.capacityId,
|
|
29
|
+
assignment
|
|
30
|
+
]));
|
|
31
|
+
const newCapacityIds = params.capacityIds.filter((capacityId)=>!existingByCapacityId.has(capacityId));
|
|
32
|
+
if (existing.length + newCapacityIds.length > reservation.count) throw new CapacityNotAssignableError(params.capacityIds[0] ?? '');
|
|
33
|
+
if (newCapacityIds.length === 0) {
|
|
34
|
+
return params.capacityIds.flatMap((capacityId)=>{
|
|
35
|
+
const assignment = existingByCapacityId.get(capacityId);
|
|
36
|
+
return assignment ? [
|
|
37
|
+
toCapacityAssignment(assignment)
|
|
38
|
+
] : [];
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const capacities = await tx.select().from(providerRunners).where(and(eq(providerRunners.provisionerId, params.provisionerId), inArray(providerRunners.id, newCapacityIds)));
|
|
42
|
+
if (capacities.length !== newCapacityIds.length) throw new CapacityNotAssignableError(params.capacityIds[0] ?? '');
|
|
43
|
+
for (const capacity of capacities){
|
|
44
|
+
if (capacity.state !== 'starting' && capacity.state !== 'running') throw new CapacityNotAssignableError(capacity.id);
|
|
45
|
+
if (!capacity.providerRunnerId || capacity.labels.length === 0 || !reservation.requiredLabels.every((label)=>capacity.labels.includes(label))) {
|
|
46
|
+
throw new CapacityNotAssignableError(capacity.id);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const assignedCapacity = await tx.select({
|
|
50
|
+
capacityId: capacityAssignments.capacityId
|
|
51
|
+
}).from(capacityAssignments).where(inArray(capacityAssignments.capacityId, newCapacityIds));
|
|
52
|
+
if (assignedCapacity.length > 0) throw new CapacityAlreadyAssignedError(assignedCapacity[0]?.capacityId ?? '');
|
|
53
|
+
const inserted = await tx.insert(capacityAssignments).values(newCapacityIds.map((capacityId)=>({
|
|
54
|
+
capacityId,
|
|
55
|
+
reservationId: reservation.id,
|
|
56
|
+
workspaceId: reservation.workspaceId,
|
|
57
|
+
provisionerId: params.provisionerId
|
|
58
|
+
}))).returning();
|
|
59
|
+
const insertedByCapacityId = new Map(inserted.map((assignment)=>[
|
|
60
|
+
assignment.capacityId,
|
|
61
|
+
assignment
|
|
62
|
+
]));
|
|
63
|
+
return params.capacityIds.flatMap((capacityId)=>{
|
|
64
|
+
const assignment = existingByCapacityId.get(capacityId) ?? insertedByCapacityId.get(capacityId);
|
|
65
|
+
return assignment ? [
|
|
66
|
+
toCapacityAssignment(assignment)
|
|
67
|
+
] : [];
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=capacity-assignments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/db/capacity-assignments.ts"],"sourcesContent":["import {and, eq, inArray, sql} from 'drizzle-orm';\nimport type {CapacityAssignment} from '#core/entities/capacity-assignment.js';\nimport {\n CapacityAlreadyAssignedError,\n CapacityNotAssignableError,\n ReservationExpiredError,\n ReservationNotFoundError,\n} from '#core/errors.js';\nimport {db} from './db.js';\nimport {capacityAssignments, toCapacityAssignment} from './schema/capacity-assignments.js';\nimport {reservations} from './schema/reservations.js';\nimport {providerRunners} from './schema/runner-instances.js';\n\nexport async function assignCapacityBatch(params: {\n provisionerId: string;\n reservationId: string;\n capacityIds: string[];\n}): Promise<CapacityAssignment[]> {\n return await db().transaction(async (tx) => {\n const lockKey = [\n 'runners_capacity_assignments',\n params.provisionerId,\n params.reservationId,\n ].join(':');\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${lockKey}))`);\n for (const capacityId of [...params.capacityIds].sort()) {\n await tx.execute(\n sql`select pg_advisory_xact_lock(hashtext(${['runners_capacity_assignments', capacityId].join(':')}))`,\n );\n }\n\n const [reservation] = await tx\n .select()\n .from(reservations)\n .where(\n and(\n eq(reservations.id, params.reservationId),\n eq(reservations.provisionerId, params.provisionerId),\n ),\n )\n .limit(1);\n if (!reservation) throw new ReservationNotFoundError(params.reservationId);\n if (reservation.expiresAt <= new Date())\n throw new ReservationExpiredError(params.reservationId);\n\n const existing = await tx\n .select()\n .from(capacityAssignments)\n .where(eq(capacityAssignments.reservationId, reservation.id));\n const existingByCapacityId = new Map(\n existing.map((assignment) => [assignment.capacityId, assignment]),\n );\n const newCapacityIds = params.capacityIds.filter(\n (capacityId) => !existingByCapacityId.has(capacityId),\n );\n if (existing.length + newCapacityIds.length > reservation.count)\n throw new CapacityNotAssignableError(params.capacityIds[0] ?? '');\n\n if (newCapacityIds.length === 0) {\n return params.capacityIds.flatMap((capacityId) => {\n const assignment = existingByCapacityId.get(capacityId);\n return assignment ? [toCapacityAssignment(assignment)] : [];\n });\n }\n\n const capacities = await tx\n .select()\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.provisionerId, params.provisionerId),\n inArray(providerRunners.id, newCapacityIds),\n ),\n );\n if (capacities.length !== newCapacityIds.length)\n throw new CapacityNotAssignableError(params.capacityIds[0] ?? '');\n for (const capacity of capacities) {\n if (capacity.state !== 'starting' && capacity.state !== 'running')\n throw new CapacityNotAssignableError(capacity.id);\n if (\n !capacity.providerRunnerId ||\n capacity.labels.length === 0 ||\n !reservation.requiredLabels.every((label) => capacity.labels.includes(label))\n ) {\n throw new CapacityNotAssignableError(capacity.id);\n }\n }\n\n const assignedCapacity = await tx\n .select({capacityId: capacityAssignments.capacityId})\n .from(capacityAssignments)\n .where(inArray(capacityAssignments.capacityId, newCapacityIds));\n if (assignedCapacity.length > 0)\n throw new CapacityAlreadyAssignedError(assignedCapacity[0]?.capacityId ?? '');\n\n const inserted = await tx\n .insert(capacityAssignments)\n .values(\n newCapacityIds.map((capacityId) => ({\n capacityId,\n reservationId: reservation.id,\n workspaceId: reservation.workspaceId,\n provisionerId: params.provisionerId,\n })),\n )\n .returning();\n const insertedByCapacityId = new Map(\n inserted.map((assignment) => [assignment.capacityId, assignment]),\n );\n return params.capacityIds.flatMap((capacityId) => {\n const assignment =\n existingByCapacityId.get(capacityId) ?? insertedByCapacityId.get(capacityId);\n return assignment ? [toCapacityAssignment(assignment)] : [];\n });\n });\n}\n"],"names":["and","eq","inArray","sql","CapacityAlreadyAssignedError","CapacityNotAssignableError","ReservationExpiredError","ReservationNotFoundError","db","capacityAssignments","toCapacityAssignment","reservations","providerRunners","assignCapacityBatch","params","transaction","tx","lockKey","provisionerId","reservationId","join","execute","capacityId","capacityIds","sort","reservation","select","from","where","id","limit","expiresAt","Date","existing","existingByCapacityId","Map","map","assignment","newCapacityIds","filter","has","length","count","flatMap","get","capacities","capacity","state","providerRunnerId","labels","requiredLabels","every","label","includes","assignedCapacity","inserted","insert","values","workspaceId","returning","insertedByCapacityId"],"mappings":"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"}
|