@shipfox/api-runners 12.2.0 → 12.4.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.
Files changed (149) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +34 -0
  3. package/dist/config.d.ts +1 -0
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +10 -3
  6. package/dist/config.js.map +1 -1
  7. package/dist/core/demand.d.ts +4 -2
  8. package/dist/core/demand.d.ts.map +1 -1
  9. package/dist/core/demand.js +22 -6
  10. package/dist/core/demand.js.map +1 -1
  11. package/dist/core/entities/reservation.d.ts +1 -0
  12. package/dist/core/entities/reservation.d.ts.map +1 -1
  13. package/dist/core/entities/reservation.js.map +1 -1
  14. package/dist/core/entities/runner-instance.d.ts +3 -0
  15. package/dist/core/entities/runner-instance.d.ts.map +1 -1
  16. package/dist/core/entities/runner-instance.js.map +1 -1
  17. package/dist/core/runner-activation.d.ts +4 -1
  18. package/dist/core/runner-activation.d.ts.map +1 -1
  19. package/dist/core/runner-activation.js +32 -3
  20. package/dist/core/runner-activation.js.map +1 -1
  21. package/dist/core/runner-control-sessions.d.ts +8 -4
  22. package/dist/core/runner-control-sessions.d.ts.map +1 -1
  23. package/dist/core/runner-control-sessions.js +69 -11
  24. package/dist/core/runner-control-sessions.js.map +1 -1
  25. package/dist/core/runner-instances.d.ts +1 -0
  26. package/dist/core/runner-instances.d.ts.map +1 -1
  27. package/dist/core/runner-instances.js +1 -0
  28. package/dist/core/runner-instances.js.map +1 -1
  29. package/dist/db/db.d.ts +68 -0
  30. package/dist/db/db.d.ts.map +1 -1
  31. package/dist/db/ephemeral-registration-tokens.d.ts.map +1 -1
  32. package/dist/db/ephemeral-registration-tokens.js +1 -1
  33. package/dist/db/ephemeral-registration-tokens.js.map +1 -1
  34. package/dist/db/index.d.ts +1 -1
  35. package/dist/db/index.d.ts.map +1 -1
  36. package/dist/db/index.js +1 -1
  37. package/dist/db/index.js.map +1 -1
  38. package/dist/db/reservation-locks.d.ts +6 -0
  39. package/dist/db/reservation-locks.d.ts.map +1 -0
  40. package/dist/db/reservation-locks.js +15 -0
  41. package/dist/db/reservation-locks.js.map +1 -0
  42. package/dist/db/reservations.d.ts +17 -3
  43. package/dist/db/reservations.d.ts.map +1 -1
  44. package/dist/db/reservations.js +256 -45
  45. package/dist/db/reservations.js.map +1 -1
  46. package/dist/db/runner-assignments.d.ts +17 -0
  47. package/dist/db/runner-assignments.d.ts.map +1 -1
  48. package/dist/db/runner-assignments.js +103 -8
  49. package/dist/db/runner-assignments.js.map +1 -1
  50. package/dist/db/runner-instances.d.ts +5 -2
  51. package/dist/db/runner-instances.d.ts.map +1 -1
  52. package/dist/db/runner-instances.js +134 -25
  53. package/dist/db/runner-instances.js.map +1 -1
  54. package/dist/db/runner-sessions.d.ts.map +1 -1
  55. package/dist/db/runner-sessions.js +22 -15
  56. package/dist/db/runner-sessions.js.map +1 -1
  57. package/dist/db/runner-states.d.ts +2 -0
  58. package/dist/db/runner-states.d.ts.map +1 -0
  59. package/dist/db/runner-states.js +7 -0
  60. package/dist/db/runner-states.js.map +1 -0
  61. package/dist/db/schema/reservations.d.ts +18 -0
  62. package/dist/db/schema/reservations.d.ts.map +1 -1
  63. package/dist/db/schema/reservations.js +7 -1
  64. package/dist/db/schema/reservations.js.map +1 -1
  65. package/dist/db/schema/runner-instances.d.ts +18 -0
  66. package/dist/db/schema/runner-instances.d.ts.map +1 -1
  67. package/dist/db/schema/runner-instances.js +8 -0
  68. package/dist/db/schema/runner-instances.js.map +1 -1
  69. package/dist/metrics/index.d.ts +2 -2
  70. package/dist/metrics/index.d.ts.map +1 -1
  71. package/dist/metrics/index.js +1 -1
  72. package/dist/metrics/index.js.map +1 -1
  73. package/dist/metrics/instance.d.ts +24 -2
  74. package/dist/metrics/instance.d.ts.map +1 -1
  75. package/dist/metrics/instance.js +23 -0
  76. package/dist/metrics/instance.js.map +1 -1
  77. package/dist/metrics/service.d.ts.map +1 -1
  78. package/dist/metrics/service.js +20 -4
  79. package/dist/metrics/service.js.map +1 -1
  80. package/dist/presentation/dto/poll-demand.d.ts.map +1 -1
  81. package/dist/presentation/dto/poll-demand.js +3 -0
  82. package/dist/presentation/dto/poll-demand.js.map +1 -1
  83. package/dist/presentation/dto/runner-instances.d.ts +4 -1
  84. package/dist/presentation/dto/runner-instances.d.ts.map +1 -1
  85. package/dist/presentation/dto/runner-instances.js +4 -1
  86. package/dist/presentation/dto/runner-instances.js.map +1 -1
  87. package/dist/presentation/routes/assign-runner-instances.d.ts.map +1 -1
  88. package/dist/presentation/routes/assign-runner-instances.js +3 -3
  89. package/dist/presentation/routes/assign-runner-instances.js.map +1 -1
  90. package/dist/presentation/routes/poll-demand.d.ts.map +1 -1
  91. package/dist/presentation/routes/poll-demand.js +1 -0
  92. package/dist/presentation/routes/poll-demand.js.map +1 -1
  93. package/dist/presentation/routes/reconcile-runner-instances.d.ts.map +1 -1
  94. package/dist/presentation/routes/reconcile-runner-instances.js +4 -2
  95. package/dist/presentation/routes/reconcile-runner-instances.js.map +1 -1
  96. package/dist/presentation/routes/runner-enrollment.d.ts +4 -1
  97. package/dist/presentation/routes/runner-enrollment.d.ts.map +1 -1
  98. package/dist/presentation/routes/runner-enrollment.js +11 -6
  99. package/dist/presentation/routes/runner-enrollment.js.map +1 -1
  100. package/dist/tsconfig.test.tsbuildinfo +1 -1
  101. package/drizzle/0005_previous_lenny_balinger.sql +5 -0
  102. package/drizzle/meta/0005_snapshot.json +2220 -0
  103. package/drizzle/meta/_journal.json +7 -0
  104. package/package.json +4 -4
  105. package/src/config.test.ts +24 -2
  106. package/src/config.ts +16 -3
  107. package/src/core/demand.test.ts +192 -3
  108. package/src/core/demand.ts +44 -4
  109. package/src/core/entities/reservation.ts +1 -0
  110. package/src/core/entities/runner-instance.ts +4 -0
  111. package/src/core/runner-activation.ts +48 -2
  112. package/src/core/runner-control-sessions.test.ts +230 -4
  113. package/src/core/runner-control-sessions.ts +84 -10
  114. package/src/core/runner-instances.test.ts +19 -0
  115. package/src/core/runner-instances.ts +2 -0
  116. package/src/core/runner-sessions.test.ts +121 -1
  117. package/src/db/ephemeral-registration-tokens.test.ts +20 -1
  118. package/src/db/ephemeral-registration-tokens.ts +1 -0
  119. package/src/db/index.ts +1 -0
  120. package/src/db/reservation-locks.ts +22 -0
  121. package/src/db/reservations.test.ts +1110 -31
  122. package/src/db/reservations.ts +434 -105
  123. package/src/db/runner-assignments.test.ts +105 -1
  124. package/src/db/runner-assignments.ts +178 -9
  125. package/src/db/runner-instances.test.ts +496 -2
  126. package/src/db/runner-instances.ts +247 -56
  127. package/src/db/runner-sessions.ts +26 -15
  128. package/src/db/runner-states.ts +7 -0
  129. package/src/db/schema/reservations.ts +5 -1
  130. package/src/db/schema/runner-instances.ts +9 -0
  131. package/src/metrics/index.ts +10 -1
  132. package/src/metrics/instance.ts +59 -2
  133. package/src/metrics/service.test.ts +106 -0
  134. package/src/metrics/service.ts +24 -4
  135. package/src/presentation/dto/poll-demand.ts +3 -0
  136. package/src/presentation/dto/runner-instances.ts +8 -1
  137. package/src/presentation/routes/assign-runner-instances.ts +6 -2
  138. package/src/presentation/routes/late-runner-enrollment.test.ts +447 -0
  139. package/src/presentation/routes/poll-demand.test.ts +79 -6
  140. package/src/presentation/routes/poll-demand.ts +1 -0
  141. package/src/presentation/routes/reconcile-runner-instances.test.ts +34 -2
  142. package/src/presentation/routes/reconcile-runner-instances.ts +7 -1
  143. package/src/presentation/routes/runner-enrollment.test.ts +316 -3
  144. package/src/presentation/routes/runner-enrollment.ts +8 -5
  145. package/test/factories/reservation.ts +2 -0
  146. package/test/factories/runner-instance.ts +6 -0
  147. package/test/fixtures/late-runner-enrollment.ts +103 -0
  148. package/test/index.ts +5 -0
  149. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/ephemeral-registration-tokens.ts"],"sourcesContent":["import type {RunnerToolCapabilitiesDto} from '@shipfox/api-runners-dto';\nimport {and, asc, eq, gt, inArray, isNull, lt, sql} from 'drizzle-orm';\nimport type {EphemeralRegistrationToken} from '#core/entities/ephemeral-registration-token.js';\nimport {\n ActiveEphemeralRegistrationTokenExistsError,\n ActiveEphemeralRegistrationTokensExistError,\n EmptyRunnerLabelsError,\n RegistrationTokenBatchExceedsReservationError,\n RegistrationTokenConsumedError,\n RegistrationTokenExpiredError,\n RegistrationTokenWorkspaceMismatchError,\n ReservationExpiredError,\n ReservationNotFoundError,\n} from '#core/errors.js';\nimport {sanitizeRunnerLabelsOrThrow} from '#core/runner-labels.js';\nimport {db} from './db.js';\nimport {\n ephemeralRegistrationTokens,\n toEphemeralRegistrationToken,\n} from './schema/ephemeral-registration-tokens.js';\nimport {provisionerTokens} from './schema/provisioner-tokens.js';\nimport {reservations} from './schema/reservations.js';\nimport {providerRunners} from './schema/runner-instances.js';\nimport {runnerSessions, toRunnerSession} from './schema/runner-sessions.js';\n\nexport interface CreateEphemeralRegistrationTokenParams {\n workspaceId: string;\n provisionerId: string;\n reservationId?: string | null | undefined;\n providerRunnerId: string;\n hashedToken: string;\n prefix: string;\n expiresAt: Date;\n}\n\nexport interface CreateEphemeralRegistrationTokensBatchRow {\n providerRunnerId: string;\n hashedToken: string;\n prefix: string;\n}\n\nexport interface CreateEphemeralRegistrationTokensBatchParams {\n workspaceId: string;\n provisionerId: string;\n reservationId: string;\n expiresAt: Date;\n rows: CreateEphemeralRegistrationTokensBatchRow[];\n}\n\nexport async function createEphemeralRegistrationToken(\n params: CreateEphemeralRegistrationTokenParams,\n): Promise<EphemeralRegistrationToken> {\n const rows = await db().transaction(async (tx) => {\n const providerRunnerLockKey = [\n 'runners_ephemeral_registration_tokens',\n params.workspaceId,\n params.provisionerId,\n params.providerRunnerId,\n ].join(':');\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${providerRunnerLockKey}))`);\n\n const [active] = await tx\n .select({id: ephemeralRegistrationTokens.id})\n .from(ephemeralRegistrationTokens)\n .where(\n and(\n eq(ephemeralRegistrationTokens.workspaceId, params.workspaceId),\n eq(ephemeralRegistrationTokens.provisionerId, params.provisionerId),\n eq(ephemeralRegistrationTokens.providerRunnerId, params.providerRunnerId),\n isNull(ephemeralRegistrationTokens.consumedAt),\n gt(ephemeralRegistrationTokens.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n\n if (active) {\n throw new ActiveEphemeralRegistrationTokenExistsError(\n params.workspaceId,\n params.provisionerId,\n params.providerRunnerId,\n );\n }\n\n return await tx\n .insert(ephemeralRegistrationTokens)\n .values({\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n reservationId: params.reservationId ?? null,\n providerRunnerId: params.providerRunnerId,\n hashedToken: params.hashedToken,\n prefix: params.prefix,\n expiresAt: params.expiresAt,\n })\n .returning();\n });\n\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toEphemeralRegistrationToken(row);\n}\n\nexport async function createEphemeralRegistrationTokensBatch(\n params: CreateEphemeralRegistrationTokensBatchParams,\n): Promise<EphemeralRegistrationToken[]> {\n const rows = await db().transaction(async (tx) => {\n const provisionerLockKey = [\n 'runners_ephemeral_registration_tokens',\n params.workspaceId,\n params.provisionerId,\n ].join(':');\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${provisionerLockKey}))`);\n for (const providerRunnerId of [\n ...new Set(params.rows.map((row) => row.providerRunnerId)),\n ].sort()) {\n const providerRunnerLockKey = [\n 'runners_ephemeral_registration_tokens',\n params.workspaceId,\n params.provisionerId,\n providerRunnerId,\n ].join(':');\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${providerRunnerLockKey}))`);\n }\n\n const [reservation] = await tx\n .select({\n count: reservations.count,\n isExpired: sql<boolean>`${reservations.expiresAt} <= now()`,\n })\n .from(reservations)\n .where(\n and(\n eq(reservations.id, params.reservationId),\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n ),\n )\n .limit(1);\n\n if (!reservation) throw new ReservationNotFoundError(params.reservationId);\n if (reservation.isExpired) throw new ReservationExpiredError(params.reservationId);\n if (params.rows.length > reservation.count) {\n throw new RegistrationTokenBatchExceedsReservationError(\n params.rows.length,\n reservation.count,\n );\n }\n\n const [existingForReservation] = await tx\n .select({count: sql<number>`count(*)::int`})\n .from(ephemeralRegistrationTokens)\n .where(\n and(\n eq(ephemeralRegistrationTokens.workspaceId, params.workspaceId),\n eq(ephemeralRegistrationTokens.provisionerId, params.provisionerId),\n eq(ephemeralRegistrationTokens.reservationId, params.reservationId),\n ),\n );\n const alreadyMinted = existingForReservation?.count ?? 0;\n if (alreadyMinted + params.rows.length > reservation.count) {\n throw new RegistrationTokenBatchExceedsReservationError(\n params.rows.length,\n reservation.count,\n alreadyMinted,\n );\n }\n\n const providerRunnerIds = params.rows.map((row) => row.providerRunnerId);\n const activeRows = await tx\n .select({providerRunnerId: ephemeralRegistrationTokens.providerRunnerId})\n .from(ephemeralRegistrationTokens)\n .where(\n and(\n eq(ephemeralRegistrationTokens.workspaceId, params.workspaceId),\n eq(ephemeralRegistrationTokens.provisionerId, params.provisionerId),\n inArray(ephemeralRegistrationTokens.providerRunnerId, providerRunnerIds),\n isNull(ephemeralRegistrationTokens.consumedAt),\n gt(ephemeralRegistrationTokens.expiresAt, sql`now()`),\n ),\n );\n\n if (activeRows.length > 0) {\n throw new ActiveEphemeralRegistrationTokensExistError(\n activeRows.map((row) => row.providerRunnerId),\n );\n }\n\n return await tx\n .insert(ephemeralRegistrationTokens)\n .values(\n params.rows.map((row) => ({\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n reservationId: params.reservationId,\n providerRunnerId: row.providerRunnerId,\n hashedToken: row.hashedToken,\n prefix: row.prefix,\n expiresAt: params.expiresAt,\n })),\n )\n .returning();\n });\n\n return rows.map(toEphemeralRegistrationToken);\n}\n\nexport async function resolveEphemeralRegistrationTokenByHash(\n hashedToken: string,\n): Promise<EphemeralRegistrationToken | undefined> {\n const rows = await db()\n .select()\n .from(ephemeralRegistrationTokens)\n .where(eq(ephemeralRegistrationTokens.hashedToken, hashedToken))\n .limit(1);\n\n const row = rows[0];\n if (!row) return undefined;\n return toEphemeralRegistrationToken(row);\n}\n\nexport interface DeleteExpiredEphemeralRegistrationTokensParams {\n retentionDays: number;\n limit?: number;\n}\n\n/**\n * Deletes ephemeral registration tokens that have reached a terminal state and\n * outlived the retention window. A token is terminal once it is consumed\n * (single use spent) or expired without consumption; the retention window is\n * measured from that terminal event so the audit record survives a bounded\n * debugging window. Active tokens that are neither consumed nor expired are\n * never deleted, so a live single-use credential is never removed early.\n */\nexport async function deleteExpiredEphemeralRegistrationTokens(\n params: DeleteExpiredEphemeralRegistrationTokensParams,\n): Promise<number> {\n // coalesce(consumed_at, expires_at) is the terminal timestamp: consumed_at\n // when the token was spent, otherwise its expiry. Comparing it to the cutoff\n // both selects deletable rows and orders the batch, and it matches the\n // terminal index so idle GC ticks never scan live rows.\n const terminalAt = sql`coalesce(${ephemeralRegistrationTokens.consumedAt}, ${ephemeralRegistrationTokens.expiresAt})`;\n const retentionCutoff = sql`now() - (${params.retentionDays} || ' days')::interval`;\n\n const deletableIds = db()\n .select({id: ephemeralRegistrationTokens.id})\n .from(ephemeralRegistrationTokens)\n .where(lt(terminalAt, retentionCutoff))\n .orderBy(asc(terminalAt), asc(ephemeralRegistrationTokens.id))\n .limit(params.limit ?? 1000);\n\n const deleted = await db()\n .delete(ephemeralRegistrationTokens)\n .where(inArray(ephemeralRegistrationTokens.id, deletableIds))\n .returning({id: ephemeralRegistrationTokens.id});\n\n return deleted.length;\n}\n\nexport async function createRunnerSessionConsumingEphemeralToken(params: {\n ephemeralTokenId: string;\n workspaceId: string;\n labels: string[];\n toolCapabilities?: RunnerToolCapabilitiesDto | null;\n maxClaims: number;\n}) {\n return await db().transaction(async (tx) => {\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${params.workspaceId}))`);\n\n const consumed = await tx\n .update(ephemeralRegistrationTokens)\n .set({consumedAt: sql`now()`})\n .where(\n and(\n eq(ephemeralRegistrationTokens.id, params.ephemeralTokenId),\n eq(ephemeralRegistrationTokens.workspaceId, params.workspaceId),\n isNull(ephemeralRegistrationTokens.consumedAt),\n gt(ephemeralRegistrationTokens.expiresAt, sql`now()`),\n ),\n )\n .returning({\n id: ephemeralRegistrationTokens.id,\n provisionerId: ephemeralRegistrationTokens.provisionerId,\n providerRunnerId: ephemeralRegistrationTokens.providerRunnerId,\n });\n\n if (!consumed[0]) {\n const [token] = await tx\n .select({\n workspaceId: ephemeralRegistrationTokens.workspaceId,\n consumedAt: ephemeralRegistrationTokens.consumedAt,\n isExpired: sql<boolean>`${ephemeralRegistrationTokens.expiresAt} <= now()`,\n })\n .from(ephemeralRegistrationTokens)\n .where(eq(ephemeralRegistrationTokens.id, params.ephemeralTokenId))\n .limit(1);\n\n if (!token) {\n throw new Error(`Ephemeral registration token not found: ${params.ephemeralTokenId}`);\n }\n if (token.workspaceId !== params.workspaceId) {\n throw new RegistrationTokenWorkspaceMismatchError(\n params.ephemeralTokenId,\n params.workspaceId,\n );\n }\n if (token.consumedAt) throw new RegistrationTokenConsumedError(params.ephemeralTokenId);\n if (token.isExpired) throw new RegistrationTokenExpiredError(params.ephemeralTokenId);\n throw new Error(\n `Ephemeral registration token could not be consumed: ${params.ephemeralTokenId}`,\n );\n }\n\n const [provisioner] = await tx\n .select({scope: provisionerTokens.scope})\n .from(provisionerTokens)\n .where(eq(provisionerTokens.id, consumed[0].provisionerId))\n .limit(1);\n const labels = sanitizeRunnerLabelsOrThrow(params.labels, {\n scope: provisioner?.scope ?? 'workspace',\n source: 'ephemeral runner registration',\n });\n if (labels.length === 0) throw new EmptyRunnerLabelsError();\n\n const [session] = await tx\n .insert(runnerSessions)\n .values({\n workspaceId: params.workspaceId,\n scope: 'workspace',\n registrationTokenId: params.ephemeralTokenId,\n registrationTokenKind: 'ephemeral',\n provisionerId: consumed[0].provisionerId,\n providerRunnerId: consumed[0].providerRunnerId,\n labels,\n toolCapabilities: params.toolCapabilities ?? null,\n toolCapabilitiesReportedAt: params.toolCapabilities ? sql`now()` : null,\n maxClaims: params.maxClaims,\n claimsUsed: 0,\n })\n .returning();\n\n if (!session) throw new Error('Insert returned no rows');\n\n await tx\n .update(ephemeralRegistrationTokens)\n .set({consumedSessionId: session.id})\n .where(eq(ephemeralRegistrationTokens.id, params.ephemeralTokenId));\n\n await tx\n .update(providerRunners)\n .set({runnerSessionId: session.id, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.workspaceId, params.workspaceId),\n eq(providerRunners.provisionerId, consumed[0].provisionerId),\n eq(providerRunners.providerRunnerId, consumed[0].providerRunnerId),\n isNull(providerRunners.reservationReleasedAt),\n ),\n );\n\n return toRunnerSession(session);\n });\n}\n"],"names":["and","asc","eq","gt","inArray","isNull","lt","sql","ActiveEphemeralRegistrationTokenExistsError","ActiveEphemeralRegistrationTokensExistError","EmptyRunnerLabelsError","RegistrationTokenBatchExceedsReservationError","RegistrationTokenConsumedError","RegistrationTokenExpiredError","RegistrationTokenWorkspaceMismatchError","ReservationExpiredError","ReservationNotFoundError","sanitizeRunnerLabelsOrThrow","db","ephemeralRegistrationTokens","toEphemeralRegistrationToken","provisionerTokens","reservations","providerRunners","runnerSessions","toRunnerSession","createEphemeralRegistrationToken","params","rows","transaction","tx","providerRunnerLockKey","workspaceId","provisionerId","providerRunnerId","join","execute","active","select","id","from","where","consumedAt","expiresAt","limit","insert","values","reservationId","hashedToken","prefix","returning","row","Error","createEphemeralRegistrationTokensBatch","provisionerLockKey","Set","map","sort","reservation","count","isExpired","length","existingForReservation","alreadyMinted","providerRunnerIds","activeRows","resolveEphemeralRegistrationTokenByHash","undefined","deleteExpiredEphemeralRegistrationTokens","terminalAt","retentionCutoff","retentionDays","deletableIds","orderBy","deleted","delete","createRunnerSessionConsumingEphemeralToken","consumed","update","set","ephemeralTokenId","token","provisioner","scope","labels","source","session","registrationTokenId","registrationTokenKind","toolCapabilities","toolCapabilitiesReportedAt","maxClaims","claimsUsed","consumedSessionId","runnerSessionId","updatedAt","reservationReleasedAt"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/db/ephemeral-registration-tokens.ts"],"sourcesContent":["import type {RunnerToolCapabilitiesDto} from '@shipfox/api-runners-dto';\nimport {and, asc, eq, gt, inArray, isNull, lt, sql} from 'drizzle-orm';\nimport type {EphemeralRegistrationToken} from '#core/entities/ephemeral-registration-token.js';\nimport {\n ActiveEphemeralRegistrationTokenExistsError,\n ActiveEphemeralRegistrationTokensExistError,\n EmptyRunnerLabelsError,\n RegistrationTokenBatchExceedsReservationError,\n RegistrationTokenConsumedError,\n RegistrationTokenExpiredError,\n RegistrationTokenWorkspaceMismatchError,\n ReservationExpiredError,\n ReservationNotFoundError,\n} from '#core/errors.js';\nimport {sanitizeRunnerLabelsOrThrow} from '#core/runner-labels.js';\nimport {db} from './db.js';\nimport {\n ephemeralRegistrationTokens,\n toEphemeralRegistrationToken,\n} from './schema/ephemeral-registration-tokens.js';\nimport {provisionerTokens} from './schema/provisioner-tokens.js';\nimport {reservations} from './schema/reservations.js';\nimport {providerRunners} from './schema/runner-instances.js';\nimport {runnerSessions, toRunnerSession} from './schema/runner-sessions.js';\n\nexport interface CreateEphemeralRegistrationTokenParams {\n workspaceId: string;\n provisionerId: string;\n reservationId?: string | null | undefined;\n providerRunnerId: string;\n hashedToken: string;\n prefix: string;\n expiresAt: Date;\n}\n\nexport interface CreateEphemeralRegistrationTokensBatchRow {\n providerRunnerId: string;\n hashedToken: string;\n prefix: string;\n}\n\nexport interface CreateEphemeralRegistrationTokensBatchParams {\n workspaceId: string;\n provisionerId: string;\n reservationId: string;\n expiresAt: Date;\n rows: CreateEphemeralRegistrationTokensBatchRow[];\n}\n\nexport async function createEphemeralRegistrationToken(\n params: CreateEphemeralRegistrationTokenParams,\n): Promise<EphemeralRegistrationToken> {\n const rows = await db().transaction(async (tx) => {\n const providerRunnerLockKey = [\n 'runners_ephemeral_registration_tokens',\n params.workspaceId,\n params.provisionerId,\n params.providerRunnerId,\n ].join(':');\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${providerRunnerLockKey}))`);\n\n const [active] = await tx\n .select({id: ephemeralRegistrationTokens.id})\n .from(ephemeralRegistrationTokens)\n .where(\n and(\n eq(ephemeralRegistrationTokens.workspaceId, params.workspaceId),\n eq(ephemeralRegistrationTokens.provisionerId, params.provisionerId),\n eq(ephemeralRegistrationTokens.providerRunnerId, params.providerRunnerId),\n isNull(ephemeralRegistrationTokens.consumedAt),\n gt(ephemeralRegistrationTokens.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n\n if (active) {\n throw new ActiveEphemeralRegistrationTokenExistsError(\n params.workspaceId,\n params.provisionerId,\n params.providerRunnerId,\n );\n }\n\n return await tx\n .insert(ephemeralRegistrationTokens)\n .values({\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n reservationId: params.reservationId ?? null,\n providerRunnerId: params.providerRunnerId,\n hashedToken: params.hashedToken,\n prefix: params.prefix,\n expiresAt: params.expiresAt,\n })\n .returning();\n });\n\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toEphemeralRegistrationToken(row);\n}\n\nexport async function createEphemeralRegistrationTokensBatch(\n params: CreateEphemeralRegistrationTokensBatchParams,\n): Promise<EphemeralRegistrationToken[]> {\n const rows = await db().transaction(async (tx) => {\n const provisionerLockKey = [\n 'runners_ephemeral_registration_tokens',\n params.workspaceId,\n params.provisionerId,\n ].join(':');\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${provisionerLockKey}))`);\n for (const providerRunnerId of [\n ...new Set(params.rows.map((row) => row.providerRunnerId)),\n ].sort()) {\n const providerRunnerLockKey = [\n 'runners_ephemeral_registration_tokens',\n params.workspaceId,\n params.provisionerId,\n providerRunnerId,\n ].join(':');\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${providerRunnerLockKey}))`);\n }\n\n const [reservation] = await tx\n .select({\n count: reservations.count,\n isExpired: sql<boolean>`${reservations.expiresAt} <= now()`,\n })\n .from(reservations)\n .where(\n and(\n eq(reservations.id, params.reservationId),\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n eq(reservations.kind, 'launch'),\n ),\n )\n .limit(1);\n\n if (!reservation) throw new ReservationNotFoundError(params.reservationId);\n if (reservation.isExpired) throw new ReservationExpiredError(params.reservationId);\n if (params.rows.length > reservation.count) {\n throw new RegistrationTokenBatchExceedsReservationError(\n params.rows.length,\n reservation.count,\n );\n }\n\n const [existingForReservation] = await tx\n .select({count: sql<number>`count(*)::int`})\n .from(ephemeralRegistrationTokens)\n .where(\n and(\n eq(ephemeralRegistrationTokens.workspaceId, params.workspaceId),\n eq(ephemeralRegistrationTokens.provisionerId, params.provisionerId),\n eq(ephemeralRegistrationTokens.reservationId, params.reservationId),\n ),\n );\n const alreadyMinted = existingForReservation?.count ?? 0;\n if (alreadyMinted + params.rows.length > reservation.count) {\n throw new RegistrationTokenBatchExceedsReservationError(\n params.rows.length,\n reservation.count,\n alreadyMinted,\n );\n }\n\n const providerRunnerIds = params.rows.map((row) => row.providerRunnerId);\n const activeRows = await tx\n .select({providerRunnerId: ephemeralRegistrationTokens.providerRunnerId})\n .from(ephemeralRegistrationTokens)\n .where(\n and(\n eq(ephemeralRegistrationTokens.workspaceId, params.workspaceId),\n eq(ephemeralRegistrationTokens.provisionerId, params.provisionerId),\n inArray(ephemeralRegistrationTokens.providerRunnerId, providerRunnerIds),\n isNull(ephemeralRegistrationTokens.consumedAt),\n gt(ephemeralRegistrationTokens.expiresAt, sql`now()`),\n ),\n );\n\n if (activeRows.length > 0) {\n throw new ActiveEphemeralRegistrationTokensExistError(\n activeRows.map((row) => row.providerRunnerId),\n );\n }\n\n return await tx\n .insert(ephemeralRegistrationTokens)\n .values(\n params.rows.map((row) => ({\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n reservationId: params.reservationId,\n providerRunnerId: row.providerRunnerId,\n hashedToken: row.hashedToken,\n prefix: row.prefix,\n expiresAt: params.expiresAt,\n })),\n )\n .returning();\n });\n\n return rows.map(toEphemeralRegistrationToken);\n}\n\nexport async function resolveEphemeralRegistrationTokenByHash(\n hashedToken: string,\n): Promise<EphemeralRegistrationToken | undefined> {\n const rows = await db()\n .select()\n .from(ephemeralRegistrationTokens)\n .where(eq(ephemeralRegistrationTokens.hashedToken, hashedToken))\n .limit(1);\n\n const row = rows[0];\n if (!row) return undefined;\n return toEphemeralRegistrationToken(row);\n}\n\nexport interface DeleteExpiredEphemeralRegistrationTokensParams {\n retentionDays: number;\n limit?: number;\n}\n\n/**\n * Deletes ephemeral registration tokens that have reached a terminal state and\n * outlived the retention window. A token is terminal once it is consumed\n * (single use spent) or expired without consumption; the retention window is\n * measured from that terminal event so the audit record survives a bounded\n * debugging window. Active tokens that are neither consumed nor expired are\n * never deleted, so a live single-use credential is never removed early.\n */\nexport async function deleteExpiredEphemeralRegistrationTokens(\n params: DeleteExpiredEphemeralRegistrationTokensParams,\n): Promise<number> {\n // coalesce(consumed_at, expires_at) is the terminal timestamp: consumed_at\n // when the token was spent, otherwise its expiry. Comparing it to the cutoff\n // both selects deletable rows and orders the batch, and it matches the\n // terminal index so idle GC ticks never scan live rows.\n const terminalAt = sql`coalesce(${ephemeralRegistrationTokens.consumedAt}, ${ephemeralRegistrationTokens.expiresAt})`;\n const retentionCutoff = sql`now() - (${params.retentionDays} || ' days')::interval`;\n\n const deletableIds = db()\n .select({id: ephemeralRegistrationTokens.id})\n .from(ephemeralRegistrationTokens)\n .where(lt(terminalAt, retentionCutoff))\n .orderBy(asc(terminalAt), asc(ephemeralRegistrationTokens.id))\n .limit(params.limit ?? 1000);\n\n const deleted = await db()\n .delete(ephemeralRegistrationTokens)\n .where(inArray(ephemeralRegistrationTokens.id, deletableIds))\n .returning({id: ephemeralRegistrationTokens.id});\n\n return deleted.length;\n}\n\nexport async function createRunnerSessionConsumingEphemeralToken(params: {\n ephemeralTokenId: string;\n workspaceId: string;\n labels: string[];\n toolCapabilities?: RunnerToolCapabilitiesDto | null;\n maxClaims: number;\n}) {\n return await db().transaction(async (tx) => {\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${params.workspaceId}))`);\n\n const consumed = await tx\n .update(ephemeralRegistrationTokens)\n .set({consumedAt: sql`now()`})\n .where(\n and(\n eq(ephemeralRegistrationTokens.id, params.ephemeralTokenId),\n eq(ephemeralRegistrationTokens.workspaceId, params.workspaceId),\n isNull(ephemeralRegistrationTokens.consumedAt),\n gt(ephemeralRegistrationTokens.expiresAt, sql`now()`),\n ),\n )\n .returning({\n id: ephemeralRegistrationTokens.id,\n provisionerId: ephemeralRegistrationTokens.provisionerId,\n providerRunnerId: ephemeralRegistrationTokens.providerRunnerId,\n });\n\n if (!consumed[0]) {\n const [token] = await tx\n .select({\n workspaceId: ephemeralRegistrationTokens.workspaceId,\n consumedAt: ephemeralRegistrationTokens.consumedAt,\n isExpired: sql<boolean>`${ephemeralRegistrationTokens.expiresAt} <= now()`,\n })\n .from(ephemeralRegistrationTokens)\n .where(eq(ephemeralRegistrationTokens.id, params.ephemeralTokenId))\n .limit(1);\n\n if (!token) {\n throw new Error(`Ephemeral registration token not found: ${params.ephemeralTokenId}`);\n }\n if (token.workspaceId !== params.workspaceId) {\n throw new RegistrationTokenWorkspaceMismatchError(\n params.ephemeralTokenId,\n params.workspaceId,\n );\n }\n if (token.consumedAt) throw new RegistrationTokenConsumedError(params.ephemeralTokenId);\n if (token.isExpired) throw new RegistrationTokenExpiredError(params.ephemeralTokenId);\n throw new Error(\n `Ephemeral registration token could not be consumed: ${params.ephemeralTokenId}`,\n );\n }\n\n const [provisioner] = await tx\n .select({scope: provisionerTokens.scope})\n .from(provisionerTokens)\n .where(eq(provisionerTokens.id, consumed[0].provisionerId))\n .limit(1);\n const labels = sanitizeRunnerLabelsOrThrow(params.labels, {\n scope: provisioner?.scope ?? 'workspace',\n source: 'ephemeral runner registration',\n });\n if (labels.length === 0) throw new EmptyRunnerLabelsError();\n\n const [session] = await tx\n .insert(runnerSessions)\n .values({\n workspaceId: params.workspaceId,\n scope: 'workspace',\n registrationTokenId: params.ephemeralTokenId,\n registrationTokenKind: 'ephemeral',\n provisionerId: consumed[0].provisionerId,\n providerRunnerId: consumed[0].providerRunnerId,\n labels,\n toolCapabilities: params.toolCapabilities ?? null,\n toolCapabilitiesReportedAt: params.toolCapabilities ? sql`now()` : null,\n maxClaims: params.maxClaims,\n claimsUsed: 0,\n })\n .returning();\n\n if (!session) throw new Error('Insert returned no rows');\n\n await tx\n .update(ephemeralRegistrationTokens)\n .set({consumedSessionId: session.id})\n .where(eq(ephemeralRegistrationTokens.id, params.ephemeralTokenId));\n\n await tx\n .update(providerRunners)\n .set({runnerSessionId: session.id, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.workspaceId, params.workspaceId),\n eq(providerRunners.provisionerId, consumed[0].provisionerId),\n eq(providerRunners.providerRunnerId, consumed[0].providerRunnerId),\n isNull(providerRunners.reservationReleasedAt),\n ),\n );\n\n return toRunnerSession(session);\n });\n}\n"],"names":["and","asc","eq","gt","inArray","isNull","lt","sql","ActiveEphemeralRegistrationTokenExistsError","ActiveEphemeralRegistrationTokensExistError","EmptyRunnerLabelsError","RegistrationTokenBatchExceedsReservationError","RegistrationTokenConsumedError","RegistrationTokenExpiredError","RegistrationTokenWorkspaceMismatchError","ReservationExpiredError","ReservationNotFoundError","sanitizeRunnerLabelsOrThrow","db","ephemeralRegistrationTokens","toEphemeralRegistrationToken","provisionerTokens","reservations","providerRunners","runnerSessions","toRunnerSession","createEphemeralRegistrationToken","params","rows","transaction","tx","providerRunnerLockKey","workspaceId","provisionerId","providerRunnerId","join","execute","active","select","id","from","where","consumedAt","expiresAt","limit","insert","values","reservationId","hashedToken","prefix","returning","row","Error","createEphemeralRegistrationTokensBatch","provisionerLockKey","Set","map","sort","reservation","count","isExpired","kind","length","existingForReservation","alreadyMinted","providerRunnerIds","activeRows","resolveEphemeralRegistrationTokenByHash","undefined","deleteExpiredEphemeralRegistrationTokens","terminalAt","retentionCutoff","retentionDays","deletableIds","orderBy","deleted","delete","createRunnerSessionConsumingEphemeralToken","consumed","update","set","ephemeralTokenId","token","provisioner","scope","labels","source","session","registrationTokenId","registrationTokenKind","toolCapabilities","toolCapabilitiesReportedAt","maxClaims","claimsUsed","consumedSessionId","runnerSessionId","updatedAt","reservationReleasedAt"],"mappings":"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"}
@@ -15,7 +15,7 @@ export type { DemandStat, PollDemandAndReserveParams, ReservationGrant, Reservat
15
15
  export { deleteExpiredReservations, deleteReservationsByIds, pollDemandAndReserve, releaseReservationUnits, } from './reservations.js';
16
16
  export { assignRunnerInstances } from './runner-assignments.js';
17
17
  export type { ActiveRunnerInstanceTemplateCount, ReapStaleRunnerInstancesResult, ReconcileRunnerInstancesDbResult, ReconcileRunnerInstancesParams, ReportRunnerInstancesParams, RunnerInstanceReportEvent, RunnerInstanceTerminateIntent, RunnerInstanceTerminateIntentReason, } from './runner-instances.js';
18
- export { attachRunnerInstanceProviderId, isTerminalState, listActiveRunnerInstanceCountsByTemplateTx, listActiveRunnerInstances, listProvisionerTerminateIntentRowsTx, listProvisionerTerminateIntents, reapStaleRunnerInstances, reconcileRunnerInstances, reportRunnerInstances, } from './runner-instances.js';
18
+ export { attachRunnerInstanceProviderId, countStaleEnrolledRunnerInstances, isTerminalState, listActiveRunnerInstanceCountsByTemplateTx, listActiveRunnerInstances, listProvisionerTerminateIntentRowsTx, listProvisionerTerminateIntents, reapStaleRunnerInstances, reconcileRunnerInstances, reportRunnerInstances, } from './runner-instances.js';
19
19
  export type { CreateRunnerSessionParams, DeleteExpiredRunnerSessionsParams, } from './runner-sessions.js';
20
20
  export { createRunnerSession, deleteExpiredRunnerSessions } from './runner-sessions.js';
21
21
  export { runnersOutbox } from './schema/outbox.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,mCAAmC,EACnC,8BAA8B,EAC9B,sCAAsC,EACtC,sCAAsC,GACvC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAC,gCAAgC,EAAC,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAC5C,YAAY,EACV,sCAAsC,EACtC,8CAA8C,GAC/C,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,gCAAgC,EAChC,0CAA0C,EAC1C,wCAAwC,EACxC,uCAAuC,GACxC,MAAM,oCAAoC,CAAC;AAC5C,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,gBAAgB,EAChB,8BAA8B,EAC9B,0CAA0C,EAC1C,eAAe,EACf,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAC,mCAAmC,EAAC,MAAM,iCAAiC,CAAC;AACzF,OAAO,EACL,6BAA6B,EAC7B,+CAA+C,EAC/C,oCAAoC,EACpC,6BAA6B,GAC9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,uCAAuC,EACvC,iDAAiD,EACjD,gDAAgD,EAChD,6CAA6C,GAC9C,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EAAC,4BAA4B,EAAC,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EACL,2CAA2C,EAC3C,sBAAsB,EACtB,2BAA2B,EAC3B,iCAAiC,EACjC,wCAAwC,EACxC,6BAA6B,EAC7B,2CAA2C,EAC3C,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,UAAU,EACV,0BAA0B,EAC1B,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EACV,iCAAiC,EACjC,8BAA8B,EAC9B,gCAAgC,EAChC,8BAA8B,EAC9B,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,mCAAmC,GACpC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,8BAA8B,EAC9B,eAAe,EACf,0CAA0C,EAC1C,yBAAyB,EACzB,oCAAoC,EACpC,+BAA+B,EAC/B,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,yBAAyB,EACzB,iCAAiC,GAClC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAC,mBAAmB,EAAE,2BAA2B,EAAC,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAC,qBAAqB,EAAE,qBAAqB,EAAC,MAAM,qCAAqC,CAAC;AAEjG,eAAO,MAAM,cAAc,QAAoE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,mCAAmC,EACnC,8BAA8B,EAC9B,sCAAsC,EACtC,sCAAsC,GACvC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAC,gCAAgC,EAAC,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAC5C,YAAY,EACV,sCAAsC,EACtC,8CAA8C,GAC/C,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,gCAAgC,EAChC,0CAA0C,EAC1C,wCAAwC,EACxC,uCAAuC,GACxC,MAAM,oCAAoC,CAAC;AAC5C,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,gBAAgB,EAChB,8BAA8B,EAC9B,0CAA0C,EAC1C,eAAe,EACf,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAC,mCAAmC,EAAC,MAAM,iCAAiC,CAAC;AACzF,OAAO,EACL,6BAA6B,EAC7B,+CAA+C,EAC/C,oCAAoC,EACpC,6BAA6B,GAC9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,uCAAuC,EACvC,iDAAiD,EACjD,gDAAgD,EAChD,6CAA6C,GAC9C,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EAAC,4BAA4B,EAAC,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EACL,2CAA2C,EAC3C,sBAAsB,EACtB,2BAA2B,EAC3B,iCAAiC,EACjC,wCAAwC,EACxC,6BAA6B,EAC7B,2CAA2C,EAC3C,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,UAAU,EACV,0BAA0B,EAC1B,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EACV,iCAAiC,EACjC,8BAA8B,EAC9B,gCAAgC,EAChC,8BAA8B,EAC9B,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,mCAAmC,GACpC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,8BAA8B,EAC9B,iCAAiC,EACjC,eAAe,EACf,0CAA0C,EAC1C,yBAAyB,EACzB,oCAAoC,EACpC,+BAA+B,EAC/B,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,yBAAyB,EACzB,iCAAiC,GAClC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAC,mBAAmB,EAAE,2BAA2B,EAAC,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAC,qBAAqB,EAAE,qBAAqB,EAAC,MAAM,qCAAqC,CAAC;AAEjG,eAAO,MAAM,cAAc,QAAoE,CAAC"}
package/dist/db/index.js CHANGED
@@ -10,7 +10,7 @@ export { createInstallationProvisionerTokenWithAudit, createProvisionerToken, li
10
10
  export { consumeRunnersRateLimit, pruneExpiredRunnersRateLimits } from './rate-limits.js';
11
11
  export { deleteExpiredReservations, deleteReservationsByIds, pollDemandAndReserve, releaseReservationUnits } from './reservations.js';
12
12
  export { assignRunnerInstances } from './runner-assignments.js';
13
- export { attachRunnerInstanceProviderId, isTerminalState, listActiveRunnerInstanceCountsByTemplateTx, listActiveRunnerInstances, listProvisionerTerminateIntentRowsTx, listProvisionerTerminateIntents, reapStaleRunnerInstances, reconcileRunnerInstances, reportRunnerInstances } from './runner-instances.js';
13
+ export { attachRunnerInstanceProviderId, countStaleEnrolledRunnerInstances, isTerminalState, listActiveRunnerInstanceCountsByTemplateTx, listActiveRunnerInstances, listProvisionerTerminateIntentRowsTx, listProvisionerTerminateIntents, reapStaleRunnerInstances, reconcileRunnerInstances, reportRunnerInstances } from './runner-instances.js';
14
14
  export { createRunnerSession, deleteExpiredRunnerSessions } from './runner-sessions.js';
15
15
  export { runnersOutbox } from './schema/outbox.js';
16
16
  export { runnerBootstrapTokens, runnerControlSessions } from './schema/runner-control-sessions.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport type {\n AdministratorRunnerAssignmentFilter,\n AdministratorRunnerInstanceRow,\n ListAdministratorRunnerInstancesParams,\n ListAdministratorRunnerInstancesResult,\n} from './admin-runner-instances.js';\nexport {listAdministratorRunnerInstances} from './admin-runner-instances.js';\nexport {closeDb, db, schema} from './db.js';\nexport type {\n CreateEphemeralRegistrationTokenParams,\n DeleteExpiredEphemeralRegistrationTokensParams,\n} from './ephemeral-registration-tokens.js';\nexport {\n createEphemeralRegistrationToken,\n createRunnerSessionConsumingEphemeralToken,\n deleteExpiredEphemeralRegistrationTokens,\n resolveEphemeralRegistrationTokenByHash,\n} from './ephemeral-registration-tokens.js';\nexport type {\n ClaimedJobExecution,\n EnqueueJobExecutionParams,\n RunnerInstanceBoundJobExecution,\n} from './job-executions.js';\nexport {\n cancelRunnerJobs,\n claimPendingJobExecution,\n enqueueJobExecution,\n expireStuckJobExecutions,\n getWorkspaceJobCounts,\n isJobLeaseActive,\n listActiveRunningJobExecutions,\n listRunningJobExecutionsByRunnerInstanceTx,\n recordHeartbeat,\n releaseJobExecution,\n} from './job-executions.js';\nexport type {CreateManualRegistrationTokenParams} from './manual-registration-tokens.js';\nexport {\n createManualRegistrationToken,\n listUsableManualRegistrationTokensByWorkspaceId,\n resolveManualRegistrationTokenByHash,\n revokeManualRegistrationToken,\n} from './manual-registration-tokens.js';\nexport {\n hasActiveWorkspaceProvisionerCapability,\n listActiveWorkspaceProvisionerCapabilitySnapshots,\n listStaleWorkspaceProvisionerCapabilitySnapshots,\n publishWorkspaceProvisionerCapabilitySnapshot,\n} from './provisioner-capability-snapshots.js';\nexport type {CreateProvisionerTokenParams} from './provisioner-tokens.js';\nexport {\n createInstallationProvisionerTokenWithAudit,\n createProvisionerToken,\n listActiveProvisionerTokens,\n listInstallationProvisionerTokens,\n listUsableProvisionerTokensByWorkspaceId,\n resolveProvisionerTokenByHash,\n revokeInstallationProvisionerTokenWithAudit,\n revokeProvisionerToken,\n touchProvisionerLastSeen,\n} from './provisioner-tokens.js';\nexport {\n consumeRunnersRateLimit,\n pruneExpiredRunnersRateLimits,\n} from './rate-limits.js';\nexport type {\n DemandStat,\n PollDemandAndReserveParams,\n ReservationGrant,\n ReservationTemplate,\n} from './reservations.js';\nexport {\n deleteExpiredReservations,\n deleteReservationsByIds,\n pollDemandAndReserve,\n releaseReservationUnits,\n} from './reservations.js';\nexport {assignRunnerInstances} from './runner-assignments.js';\nexport type {\n ActiveRunnerInstanceTemplateCount,\n ReapStaleRunnerInstancesResult,\n ReconcileRunnerInstancesDbResult,\n ReconcileRunnerInstancesParams,\n ReportRunnerInstancesParams,\n RunnerInstanceReportEvent,\n RunnerInstanceTerminateIntent,\n RunnerInstanceTerminateIntentReason,\n} from './runner-instances.js';\nexport {\n attachRunnerInstanceProviderId,\n isTerminalState,\n listActiveRunnerInstanceCountsByTemplateTx,\n listActiveRunnerInstances,\n listProvisionerTerminateIntentRowsTx,\n listProvisionerTerminateIntents,\n reapStaleRunnerInstances,\n reconcileRunnerInstances,\n reportRunnerInstances,\n} from './runner-instances.js';\nexport type {\n CreateRunnerSessionParams,\n DeleteExpiredRunnerSessionsParams,\n} from './runner-sessions.js';\nexport {createRunnerSession, deleteExpiredRunnerSessions} from './runner-sessions.js';\nexport {runnersOutbox} from './schema/outbox.js';\nexport {runnerBootstrapTokens, runnerControlSessions} from './schema/runner-control-sessions.js';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n"],"names":["dirname","resolve","fileURLToPath","listAdministratorRunnerInstances","closeDb","db","schema","createEphemeralRegistrationToken","createRunnerSessionConsumingEphemeralToken","deleteExpiredEphemeralRegistrationTokens","resolveEphemeralRegistrationTokenByHash","cancelRunnerJobs","claimPendingJobExecution","enqueueJobExecution","expireStuckJobExecutions","getWorkspaceJobCounts","isJobLeaseActive","listActiveRunningJobExecutions","listRunningJobExecutionsByRunnerInstanceTx","recordHeartbeat","releaseJobExecution","createManualRegistrationToken","listUsableManualRegistrationTokensByWorkspaceId","resolveManualRegistrationTokenByHash","revokeManualRegistrationToken","hasActiveWorkspaceProvisionerCapability","listActiveWorkspaceProvisionerCapabilitySnapshots","listStaleWorkspaceProvisionerCapabilitySnapshots","publishWorkspaceProvisionerCapabilitySnapshot","createInstallationProvisionerTokenWithAudit","createProvisionerToken","listActiveProvisionerTokens","listInstallationProvisionerTokens","listUsableProvisionerTokensByWorkspaceId","resolveProvisionerTokenByHash","revokeInstallationProvisionerTokenWithAudit","revokeProvisionerToken","touchProvisionerLastSeen","consumeRunnersRateLimit","pruneExpiredRunnersRateLimits","deleteExpiredReservations","deleteReservationsByIds","pollDemandAndReserve","releaseReservationUnits","assignRunnerInstances","attachRunnerInstanceProviderId","isTerminalState","listActiveRunnerInstanceCountsByTemplateTx","listActiveRunnerInstances","listProvisionerTerminateIntentRowsTx","listProvisionerTerminateIntents","reapStaleRunnerInstances","reconcileRunnerInstances","reportRunnerInstances","createRunnerSession","deleteExpiredRunnerSessions","runnersOutbox","runnerBootstrapTokens","runnerControlSessions","migrationsPath","url"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAQvC,SAAQC,gCAAgC,QAAO,8BAA8B;AAC7E,SAAQC,OAAO,EAAEC,EAAE,EAAEC,MAAM,QAAO,UAAU;AAK5C,SACEC,gCAAgC,EAChCC,0CAA0C,EAC1CC,wCAAwC,EACxCC,uCAAuC,QAClC,qCAAqC;AAM5C,SACEC,gBAAgB,EAChBC,wBAAwB,EACxBC,mBAAmB,EACnBC,wBAAwB,EACxBC,qBAAqB,EACrBC,gBAAgB,EAChBC,8BAA8B,EAC9BC,0CAA0C,EAC1CC,eAAe,EACfC,mBAAmB,QACd,sBAAsB;AAE7B,SACEC,6BAA6B,EAC7BC,+CAA+C,EAC/CC,oCAAoC,EACpCC,6BAA6B,QACxB,kCAAkC;AACzC,SACEC,uCAAuC,EACvCC,iDAAiD,EACjDC,gDAAgD,EAChDC,6CAA6C,QACxC,wCAAwC;AAE/C,SACEC,2CAA2C,EAC3CC,sBAAsB,EACtBC,2BAA2B,EAC3BC,iCAAiC,EACjCC,wCAAwC,EACxCC,6BAA6B,EAC7BC,2CAA2C,EAC3CC,sBAAsB,EACtBC,wBAAwB,QACnB,0BAA0B;AACjC,SACEC,uBAAuB,EACvBC,6BAA6B,QACxB,mBAAmB;AAO1B,SACEC,yBAAyB,EACzBC,uBAAuB,EACvBC,oBAAoB,EACpBC,uBAAuB,QAClB,oBAAoB;AAC3B,SAAQC,qBAAqB,QAAO,0BAA0B;AAW9D,SACEC,8BAA8B,EAC9BC,eAAe,EACfC,0CAA0C,EAC1CC,yBAAyB,EACzBC,oCAAoC,EACpCC,+BAA+B,EAC/BC,wBAAwB,EACxBC,wBAAwB,EACxBC,qBAAqB,QAChB,wBAAwB;AAK/B,SAAQC,mBAAmB,EAAEC,2BAA2B,QAAO,uBAAuB;AACtF,SAAQC,aAAa,QAAO,qBAAqB;AACjD,SAAQC,qBAAqB,EAAEC,qBAAqB,QAAO,sCAAsC;AAEjG,OAAO,MAAMC,iBAAiB1D,QAAQD,QAAQE,cAAc,YAAY0D,GAAG,IAAI,iBAAiB"}
1
+ {"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport type {\n AdministratorRunnerAssignmentFilter,\n AdministratorRunnerInstanceRow,\n ListAdministratorRunnerInstancesParams,\n ListAdministratorRunnerInstancesResult,\n} from './admin-runner-instances.js';\nexport {listAdministratorRunnerInstances} from './admin-runner-instances.js';\nexport {closeDb, db, schema} from './db.js';\nexport type {\n CreateEphemeralRegistrationTokenParams,\n DeleteExpiredEphemeralRegistrationTokensParams,\n} from './ephemeral-registration-tokens.js';\nexport {\n createEphemeralRegistrationToken,\n createRunnerSessionConsumingEphemeralToken,\n deleteExpiredEphemeralRegistrationTokens,\n resolveEphemeralRegistrationTokenByHash,\n} from './ephemeral-registration-tokens.js';\nexport type {\n ClaimedJobExecution,\n EnqueueJobExecutionParams,\n RunnerInstanceBoundJobExecution,\n} from './job-executions.js';\nexport {\n cancelRunnerJobs,\n claimPendingJobExecution,\n enqueueJobExecution,\n expireStuckJobExecutions,\n getWorkspaceJobCounts,\n isJobLeaseActive,\n listActiveRunningJobExecutions,\n listRunningJobExecutionsByRunnerInstanceTx,\n recordHeartbeat,\n releaseJobExecution,\n} from './job-executions.js';\nexport type {CreateManualRegistrationTokenParams} from './manual-registration-tokens.js';\nexport {\n createManualRegistrationToken,\n listUsableManualRegistrationTokensByWorkspaceId,\n resolveManualRegistrationTokenByHash,\n revokeManualRegistrationToken,\n} from './manual-registration-tokens.js';\nexport {\n hasActiveWorkspaceProvisionerCapability,\n listActiveWorkspaceProvisionerCapabilitySnapshots,\n listStaleWorkspaceProvisionerCapabilitySnapshots,\n publishWorkspaceProvisionerCapabilitySnapshot,\n} from './provisioner-capability-snapshots.js';\nexport type {CreateProvisionerTokenParams} from './provisioner-tokens.js';\nexport {\n createInstallationProvisionerTokenWithAudit,\n createProvisionerToken,\n listActiveProvisionerTokens,\n listInstallationProvisionerTokens,\n listUsableProvisionerTokensByWorkspaceId,\n resolveProvisionerTokenByHash,\n revokeInstallationProvisionerTokenWithAudit,\n revokeProvisionerToken,\n touchProvisionerLastSeen,\n} from './provisioner-tokens.js';\nexport {\n consumeRunnersRateLimit,\n pruneExpiredRunnersRateLimits,\n} from './rate-limits.js';\nexport type {\n DemandStat,\n PollDemandAndReserveParams,\n ReservationGrant,\n ReservationTemplate,\n} from './reservations.js';\nexport {\n deleteExpiredReservations,\n deleteReservationsByIds,\n pollDemandAndReserve,\n releaseReservationUnits,\n} from './reservations.js';\nexport {assignRunnerInstances} from './runner-assignments.js';\nexport type {\n ActiveRunnerInstanceTemplateCount,\n ReapStaleRunnerInstancesResult,\n ReconcileRunnerInstancesDbResult,\n ReconcileRunnerInstancesParams,\n ReportRunnerInstancesParams,\n RunnerInstanceReportEvent,\n RunnerInstanceTerminateIntent,\n RunnerInstanceTerminateIntentReason,\n} from './runner-instances.js';\nexport {\n attachRunnerInstanceProviderId,\n countStaleEnrolledRunnerInstances,\n isTerminalState,\n listActiveRunnerInstanceCountsByTemplateTx,\n listActiveRunnerInstances,\n listProvisionerTerminateIntentRowsTx,\n listProvisionerTerminateIntents,\n reapStaleRunnerInstances,\n reconcileRunnerInstances,\n reportRunnerInstances,\n} from './runner-instances.js';\nexport type {\n CreateRunnerSessionParams,\n DeleteExpiredRunnerSessionsParams,\n} from './runner-sessions.js';\nexport {createRunnerSession, deleteExpiredRunnerSessions} from './runner-sessions.js';\nexport {runnersOutbox} from './schema/outbox.js';\nexport {runnerBootstrapTokens, runnerControlSessions} from './schema/runner-control-sessions.js';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n"],"names":["dirname","resolve","fileURLToPath","listAdministratorRunnerInstances","closeDb","db","schema","createEphemeralRegistrationToken","createRunnerSessionConsumingEphemeralToken","deleteExpiredEphemeralRegistrationTokens","resolveEphemeralRegistrationTokenByHash","cancelRunnerJobs","claimPendingJobExecution","enqueueJobExecution","expireStuckJobExecutions","getWorkspaceJobCounts","isJobLeaseActive","listActiveRunningJobExecutions","listRunningJobExecutionsByRunnerInstanceTx","recordHeartbeat","releaseJobExecution","createManualRegistrationToken","listUsableManualRegistrationTokensByWorkspaceId","resolveManualRegistrationTokenByHash","revokeManualRegistrationToken","hasActiveWorkspaceProvisionerCapability","listActiveWorkspaceProvisionerCapabilitySnapshots","listStaleWorkspaceProvisionerCapabilitySnapshots","publishWorkspaceProvisionerCapabilitySnapshot","createInstallationProvisionerTokenWithAudit","createProvisionerToken","listActiveProvisionerTokens","listInstallationProvisionerTokens","listUsableProvisionerTokensByWorkspaceId","resolveProvisionerTokenByHash","revokeInstallationProvisionerTokenWithAudit","revokeProvisionerToken","touchProvisionerLastSeen","consumeRunnersRateLimit","pruneExpiredRunnersRateLimits","deleteExpiredReservations","deleteReservationsByIds","pollDemandAndReserve","releaseReservationUnits","assignRunnerInstances","attachRunnerInstanceProviderId","countStaleEnrolledRunnerInstances","isTerminalState","listActiveRunnerInstanceCountsByTemplateTx","listActiveRunnerInstances","listProvisionerTerminateIntentRowsTx","listProvisionerTerminateIntents","reapStaleRunnerInstances","reconcileRunnerInstances","reportRunnerInstances","createRunnerSession","deleteExpiredRunnerSessions","runnersOutbox","runnerBootstrapTokens","runnerControlSessions","migrationsPath","url"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAQvC,SAAQC,gCAAgC,QAAO,8BAA8B;AAC7E,SAAQC,OAAO,EAAEC,EAAE,EAAEC,MAAM,QAAO,UAAU;AAK5C,SACEC,gCAAgC,EAChCC,0CAA0C,EAC1CC,wCAAwC,EACxCC,uCAAuC,QAClC,qCAAqC;AAM5C,SACEC,gBAAgB,EAChBC,wBAAwB,EACxBC,mBAAmB,EACnBC,wBAAwB,EACxBC,qBAAqB,EACrBC,gBAAgB,EAChBC,8BAA8B,EAC9BC,0CAA0C,EAC1CC,eAAe,EACfC,mBAAmB,QACd,sBAAsB;AAE7B,SACEC,6BAA6B,EAC7BC,+CAA+C,EAC/CC,oCAAoC,EACpCC,6BAA6B,QACxB,kCAAkC;AACzC,SACEC,uCAAuC,EACvCC,iDAAiD,EACjDC,gDAAgD,EAChDC,6CAA6C,QACxC,wCAAwC;AAE/C,SACEC,2CAA2C,EAC3CC,sBAAsB,EACtBC,2BAA2B,EAC3BC,iCAAiC,EACjCC,wCAAwC,EACxCC,6BAA6B,EAC7BC,2CAA2C,EAC3CC,sBAAsB,EACtBC,wBAAwB,QACnB,0BAA0B;AACjC,SACEC,uBAAuB,EACvBC,6BAA6B,QACxB,mBAAmB;AAO1B,SACEC,yBAAyB,EACzBC,uBAAuB,EACvBC,oBAAoB,EACpBC,uBAAuB,QAClB,oBAAoB;AAC3B,SAAQC,qBAAqB,QAAO,0BAA0B;AAW9D,SACEC,8BAA8B,EAC9BC,iCAAiC,EACjCC,eAAe,EACfC,0CAA0C,EAC1CC,yBAAyB,EACzBC,oCAAoC,EACpCC,+BAA+B,EAC/BC,wBAAwB,EACxBC,wBAAwB,EACxBC,qBAAqB,QAChB,wBAAwB;AAK/B,SAAQC,mBAAmB,EAAEC,2BAA2B,QAAO,uBAAuB;AACtF,SAAQC,aAAa,QAAO,qBAAqB;AACjD,SAAQC,qBAAqB,EAAEC,qBAAqB,QAAO,sCAAsC;AAEjG,OAAO,MAAMC,iBAAiB3D,QAAQD,QAAQE,cAAc,YAAY2D,GAAG,IAAI,iBAAiB"}
@@ -0,0 +1,6 @@
1
+ import type { Tx } from './db.js';
2
+ export declare function lockRunnerReservationAdvisoryKeysTx(tx: Tx, params: {
3
+ provisionerId: string;
4
+ reservationIds: readonly string[];
5
+ }): Promise<void>;
6
+ //# sourceMappingURL=reservation-locks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reservation-locks.d.ts","sourceRoot":"","sources":["../../src/db/reservation-locks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,SAAS,CAAC;AAEhC,wBAAsB,mCAAmC,CACvD,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;CAAC,GACjE,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -0,0 +1,15 @@
1
+ import { sql } from 'drizzle-orm';
2
+ export async function lockRunnerReservationAdvisoryKeysTx(tx, params) {
3
+ const reservationIds = [
4
+ ...new Set(params.reservationIds)
5
+ ].sort();
6
+ if (reservationIds.length === 0) return;
7
+ const lockKeys = sql.join(reservationIds.map((reservationId)=>sql`(${`runners_assignment:${params.provisionerId}:${reservationId}`})`), sql`, `);
8
+ await tx.execute(sql`
9
+ select pg_advisory_xact_lock(hashtext(lock_key))
10
+ from (values ${lockKeys}) as reservation_locks(lock_key)
11
+ order by lock_key
12
+ `);
13
+ }
14
+
15
+ //# sourceMappingURL=reservation-locks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/db/reservation-locks.ts"],"sourcesContent":["import {sql} from 'drizzle-orm';\nimport type {Tx} from './db.js';\n\nexport async function lockRunnerReservationAdvisoryKeysTx(\n tx: Tx,\n params: {provisionerId: string; reservationIds: readonly string[]},\n): Promise<void> {\n const reservationIds = [...new Set(params.reservationIds)].sort();\n if (reservationIds.length === 0) return;\n\n const lockKeys = sql.join(\n reservationIds.map(\n (reservationId) => sql`(${`runners_assignment:${params.provisionerId}:${reservationId}`})`,\n ),\n sql`, `,\n );\n await tx.execute(sql`\n select pg_advisory_xact_lock(hashtext(lock_key))\n from (values ${lockKeys}) as reservation_locks(lock_key)\n order by lock_key\n `);\n}\n"],"names":["sql","lockRunnerReservationAdvisoryKeysTx","tx","params","reservationIds","Set","sort","length","lockKeys","join","map","reservationId","provisionerId","execute"],"mappings":"AAAA,SAAQA,GAAG,QAAO,cAAc;AAGhC,OAAO,eAAeC,oCACpBC,EAAM,EACNC,MAAkE;IAElE,MAAMC,iBAAiB;WAAI,IAAIC,IAAIF,OAAOC,cAAc;KAAE,CAACE,IAAI;IAC/D,IAAIF,eAAeG,MAAM,KAAK,GAAG;IAEjC,MAAMC,WAAWR,IAAIS,IAAI,CACvBL,eAAeM,GAAG,CAChB,CAACC,gBAAkBX,GAAG,CAAC,CAAC,EAAE,CAAC,mBAAmB,EAAEG,OAAOS,aAAa,CAAC,CAAC,EAAED,eAAe,CAAC,CAAC,CAAC,GAE5FX,GAAG,CAAC,EAAE,CAAC;IAET,MAAME,GAAGW,OAAO,CAACb,GAAG,CAAC;;iBAEN,EAAEQ,SAAS;;EAE1B,CAAC;AACH"}
@@ -25,6 +25,8 @@ export interface PollDemandAndReserveParams {
25
25
  provisionerId: string;
26
26
  maxReservations: number;
27
27
  ttlSeconds: number;
28
+ /** Lifetime of the short reservation that gives rebound runners time to activate. */
29
+ activationGraceSeconds?: number;
28
30
  templates: ReservationTemplate[];
29
31
  capabilityWindowSeconds?: number;
30
32
  }
@@ -32,23 +34,34 @@ export interface InstallationPollDemandAndReserveParams {
32
34
  provisionerId: string;
33
35
  maxReservations: number;
34
36
  ttlSeconds: number;
37
+ /** Lifetime of the short reservation that gives rebound runners time to activate. */
38
+ activationGraceSeconds?: number;
35
39
  templates: ReservationTemplate[];
36
40
  capabilityWindowSeconds: number;
37
41
  eligibleWorkspaceIds: ReadonlySet<string>;
38
42
  signal?: AbortSignal;
39
43
  onReservations?: (reservations: ReservationGrant[]) => void;
40
44
  }
41
- export declare function pollDemandAndReserve(params: PollDemandAndReserveParams): Promise<{
45
+ interface NewReservationUnits {
46
+ labels: string[];
47
+ count: number;
48
+ }
49
+ interface PollDemandAndReserveResult {
42
50
  stats: DemandStat[];
51
+ /** Only launch reservations are exposed to the provisioner. */
43
52
  reservations: ReservationGrant[];
44
- }>;
45
- export declare function pollDemandAndReserveTx(tx: Tx, params: PollDemandAndReserveParams): Promise<{
53
+ /** Internal allocation accounting for bound and launch rows together. */
54
+ newlyReservedUnits: NewReservationUnits[];
55
+ }
56
+ export declare function pollDemandAndReserve(params: PollDemandAndReserveParams): Promise<{
46
57
  stats: DemandStat[];
47
58
  reservations: ReservationGrant[];
48
59
  }>;
60
+ export declare function pollDemandAndReserveTx(tx: Tx, params: PollDemandAndReserveParams): Promise<PollDemandAndReserveResult>;
49
61
  export declare function pollInstallationDemandAndReserve(params: InstallationPollDemandAndReserveParams): Promise<{
50
62
  stats: DemandStat[];
51
63
  reservations: ReservationGrant[];
64
+ newlyReservedCount?: number;
52
65
  }>;
53
66
  export declare function listQueuedDemandWorkspaceIds(): Promise<string[]>;
54
67
  export declare function deleteExpiredReservations(params?: {
@@ -63,4 +76,5 @@ export declare function releaseReservationUnits(tx: Tx, params: {
63
76
  count: number;
64
77
  }>;
65
78
  }): Promise<number>;
79
+ export {};
66
80
  //# sourceMappingURL=reservations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reservations.d.ts","sourceRoot":"","sources":["../../src/db/reservations.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,SAAS,CAAC;AAUhC,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,sCAAsC;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,uBAAuB,EAAE,MAAM,CAAC;IAChC,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;CAC7D;AAcD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,YAAY,EAAE,gBAAgB,EAAE,CAAA;CAAC,CAAC,CAIlE;AAED,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,YAAY,EAAE,gBAAgB,EAAE,CAAA;CAAC,CAAC,CAGlE;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,sCAAsC,GAC7C,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,YAAY,EAAE,gBAAgB,EAAE,CAAA;CAAC,CAAC,CA2ClE;AAsOD,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAMtE;AA0BD,wBAAsB,yBAAyB,CAAC,MAAM,CAAC,EAAE;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAc1F;AAED,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAM5E;AA0GD,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IACN,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,KAAK,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;CACzD,GACA,OAAO,CAAC,MAAM,CAAC,CA0CjB"}
1
+ {"version":3,"file":"reservations.d.ts","sourceRoot":"","sources":["../../src/db/reservations.ts"],"names":[],"mappings":"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"}