@shipfox/api-runners 12.2.0 → 12.3.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 (43) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +12 -0
  3. package/dist/config.js +3 -3
  4. package/dist/config.js.map +1 -1
  5. package/dist/core/runner-control-sessions.d.ts.map +1 -1
  6. package/dist/core/runner-control-sessions.js +14 -2
  7. package/dist/core/runner-control-sessions.js.map +1 -1
  8. package/dist/db/index.d.ts +1 -1
  9. package/dist/db/index.d.ts.map +1 -1
  10. package/dist/db/index.js +1 -1
  11. package/dist/db/index.js.map +1 -1
  12. package/dist/db/reservations.d.ts.map +1 -1
  13. package/dist/db/reservations.js +22 -6
  14. package/dist/db/reservations.js.map +1 -1
  15. package/dist/db/runner-instances.d.ts +3 -0
  16. package/dist/db/runner-instances.d.ts.map +1 -1
  17. package/dist/db/runner-instances.js +10 -1
  18. package/dist/db/runner-instances.js.map +1 -1
  19. package/dist/db/runner-sessions.d.ts.map +1 -1
  20. package/dist/db/runner-sessions.js +22 -15
  21. package/dist/db/runner-sessions.js.map +1 -1
  22. package/dist/metrics/service.d.ts.map +1 -1
  23. package/dist/metrics/service.js +20 -4
  24. package/dist/metrics/service.js.map +1 -1
  25. package/dist/tsconfig.test.tsbuildinfo +1 -1
  26. package/package.json +3 -3
  27. package/src/config.test.ts +2 -2
  28. package/src/config.ts +3 -3
  29. package/src/core/runner-control-sessions.test.ts +169 -4
  30. package/src/core/runner-control-sessions.ts +22 -1
  31. package/src/db/index.ts +1 -0
  32. package/src/db/reservations.test.ts +369 -1
  33. package/src/db/reservations.ts +74 -9
  34. package/src/db/runner-instances.test.ts +231 -0
  35. package/src/db/runner-instances.ts +32 -1
  36. package/src/db/runner-sessions.ts +26 -15
  37. package/src/metrics/service.test.ts +99 -0
  38. package/src/metrics/service.ts +24 -4
  39. package/src/presentation/routes/late-runner-enrollment.test.ts +230 -0
  40. package/src/presentation/routes/poll-demand.test.ts +23 -6
  41. package/test/fixtures/late-runner-enrollment.ts +103 -0
  42. package/test/index.ts +5 -0
  43. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/reservations.ts"],"sourcesContent":["import {canonicalizeLabels} from '@shipfox/runner-labels';\nimport {\n and,\n arrayContains,\n asc,\n eq,\n exists,\n gt,\n inArray,\n isNotNull,\n isNull,\n lt,\n or,\n sql,\n} from 'drizzle-orm';\nimport type {Tx} from './db.js';\nimport {db} from './db.js';\nimport {pendingJobExecutions} from './schema/pending-job-executions.js';\nimport {provisionerCapabilitySnapshots} from './schema/provisioner-capability-snapshots.js';\nimport {provisionerTokens} from './schema/provisioner-tokens.js';\nimport {reservations} from './schema/reservations.js';\nimport {runnerActivationTokens} from './schema/runner-activation-tokens.js';\nimport {runnerControlSessions} from './schema/runner-control-sessions.js';\nimport {providerRunners} from './schema/runner-instances.js';\n\nexport interface ReservationTemplate {\n templateKey: string;\n labels: string[];\n availableSlots: number;\n starting: number;\n running: number;\n}\n\nexport interface DemandStat {\n workspaceId?: string;\n labels: string[];\n queued: number;\n reserved: number;\n oldestQueuedAt: Date;\n}\n\nexport interface ReservationGrant {\n reservationId: string;\n workspaceId?: string;\n labels: string[];\n count: number;\n expiresAt: Date;\n}\n\nexport interface PollDemandAndReserveParams {\n workspaceId: string;\n provisionerId: string;\n maxReservations: number;\n ttlSeconds: number;\n templates: ReservationTemplate[];\n capabilityWindowSeconds?: number;\n}\n\nexport interface InstallationPollDemandAndReserveParams {\n provisionerId: string;\n maxReservations: number;\n ttlSeconds: number;\n templates: ReservationTemplate[];\n capabilityWindowSeconds: number;\n eligibleWorkspaceIds: ReadonlySet<string>;\n signal?: AbortSignal;\n onReservations?: (reservations: ReservationGrant[]) => void;\n}\n\ninterface NormalizedTemplate {\n templateKey: string;\n labels: string[];\n remainingSlots: number;\n}\n\ninterface DemandRow {\n requiredLabels: string[];\n queued: number;\n oldestQueuedAt: Date;\n}\n\nexport async function pollDemandAndReserve(\n params: PollDemandAndReserveParams,\n): Promise<{stats: DemandStat[]; reservations: ReservationGrant[]}> {\n return await db().transaction(async (tx) => {\n return await pollDemandAndReserveTx(tx, params);\n });\n}\n\nexport async function pollDemandAndReserveTx(\n tx: Tx,\n params: PollDemandAndReserveParams,\n): Promise<{stats: DemandStat[]; reservations: ReservationGrant[]}> {\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${params.workspaceId}))`);\n return await pollDemandAndReserveLockedTx(tx, params);\n}\n\nexport async function pollInstallationDemandAndReserve(\n params: InstallationPollDemandAndReserveParams,\n): Promise<{stats: DemandStat[]; reservations: ReservationGrant[]}> {\n const candidateWorkspaceIds = await listInstallationDemandWorkspaceIds(\n params.eligibleWorkspaceIds,\n );\n const results: Array<{stats: DemandStat[]; reservations: ReservationGrant[]}> = [];\n let remainingMaxReservations = params.maxReservations;\n const remainingTemplates = params.templates.map((template) => ({\n ...template,\n labels: [...canonicalizeLabels(template.labels)],\n remainingSlots: template.availableSlots,\n }));\n for (const workspaceId of candidateWorkspaceIds) {\n if (params.signal?.aborted || remainingMaxReservations === 0) break;\n const result = await db().transaction(async (tx) => {\n const lockResult = await tx.execute<{locked: boolean}>(\n sql`select pg_try_advisory_xact_lock(hashtext(${workspaceId})) as locked`,\n );\n const locked = lockResult.rows[0];\n if (!locked?.locked) return {stats: [], reservations: []};\n return await pollDemandAndReserveLockedTx(tx, {\n workspaceId,\n provisionerId: params.provisionerId,\n maxReservations: remainingMaxReservations,\n ttlSeconds: params.ttlSeconds,\n templates: remainingTemplates.map((template) => ({\n ...template,\n availableSlots: template.remainingSlots,\n })),\n capabilityWindowSeconds: params.capabilityWindowSeconds,\n });\n });\n results.push(result);\n consumeInstallationTemplateSlots(remainingTemplates, result.reservations);\n params.onReservations?.(result.reservations);\n remainingMaxReservations -= result.reservations.reduce(\n (total, reservation) => total + reservation.count,\n 0,\n );\n }\n return {\n stats: results.flatMap((result) => result.stats),\n reservations: results.flatMap((result) => result.reservations),\n };\n}\n\nfunction consumeInstallationTemplateSlots(\n templates: NormalizedTemplate[],\n reservations: ReservationGrant[],\n): void {\n for (const reservation of reservations) {\n const satisfyingTemplates = templates\n .filter((template) => isSubset(reservation.labels, template.labels))\n .sort(\n (a, b) => a.labels.length - b.labels.length || a.templateKey.localeCompare(b.templateKey),\n );\n drawSlots(satisfyingTemplates, reservation.count);\n }\n}\n\nasync function pollDemandAndReserveLockedTx(\n tx: Tx,\n params: PollDemandAndReserveParams,\n): Promise<{stats: DemandStat[]; reservations: ReservationGrant[]}> {\n let demandRows = (\n await tx\n .select({\n requiredLabels: pendingJobExecutions.requiredLabels,\n queued: sql<number>`count(*)::int`,\n oldestQueuedAt: sql<Date | string>`min(${pendingJobExecutions.createdAt})`,\n })\n .from(pendingJobExecutions)\n .where(eq(pendingJobExecutions.workspaceId, params.workspaceId))\n .groupBy(pendingJobExecutions.requiredLabels)\n ).map((row) => ({\n ...row,\n oldestQueuedAt: new Date(row.oldestQueuedAt),\n }));\n if (params.capabilityWindowSeconds !== undefined) {\n const capabilityLabels = await listActiveWorkspaceCapabilityLabelsTx(tx, {\n workspaceId: params.workspaceId,\n windowSeconds: params.capabilityWindowSeconds,\n });\n demandRows = demandRows.filter(\n (demand) => !capabilityLabels.some((labels) => isSubset(demand.requiredLabels, labels)),\n );\n }\n\n const activeReservationRows = await tx\n .select({\n requiredLabels: reservations.requiredLabels,\n reserved: sql<number>`coalesce(sum(${reservations.count}), 0)::int`,\n })\n .from(reservations)\n .where(\n and(eq(reservations.workspaceId, params.workspaceId), gt(reservations.expiresAt, sql`now()`)),\n )\n .groupBy(reservations.requiredLabels);\n\n const reservedByLabels = new Map(\n activeReservationRows.map((row) => [labelKey(row.requiredLabels), row.reserved]),\n );\n const activeProvisionerReservationRows = await tx\n .select({\n requiredLabels: reservations.requiredLabels,\n reserved: sql<number>`coalesce(sum(${reservations.count}), 0)::int`,\n })\n .from(reservations)\n .where(\n and(\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n gt(reservations.expiresAt, sql`now()`),\n ),\n )\n .groupBy(reservations.requiredLabels);\n\n const templates = params.templates.map((template) => ({\n templateKey: template.templateKey,\n labels: [...canonicalizeLabels(template.labels)],\n remainingSlots: template.availableSlots,\n }));\n deductProvisionerReservations(templates, activeProvisionerReservationRows);\n const stats: DemandStat[] = [];\n const grants: ReservationGrant[] = [];\n let remainingMaxReservations = params.maxReservations;\n const workspaceIdField =\n params.capabilityWindowSeconds === undefined ? {} : {workspaceId: params.workspaceId};\n\n for (const demand of sortDemandRows(demandRows)) {\n const satisfyingTemplates = templates\n .filter((template) => isSubset(demand.requiredLabels, template.labels))\n .sort(\n (a, b) => a.labels.length - b.labels.length || a.templateKey.localeCompare(b.templateKey),\n );\n\n if (satisfyingTemplates.length === 0) continue;\n\n const reserved = reservedByLabels.get(labelKey(demand.requiredLabels)) ?? 0;\n const unreserved = Math.max(0, demand.queued - reserved);\n const capacity = satisfyingTemplates.reduce(\n (total, template) => total + template.remainingSlots,\n 0,\n );\n const grant = Math.min(unreserved, capacity, remainingMaxReservations);\n let reservedAfterGrant = reserved;\n\n if (grant > 0 && params.maxReservations > 0) {\n const [inserted] = await tx\n .insert(reservations)\n .values({\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n requiredLabels: demand.requiredLabels,\n count: grant,\n expiresAt: sql`now() + (${params.ttlSeconds} || ' seconds')::interval`,\n })\n .returning({id: reservations.id, expiresAt: reservations.expiresAt});\n\n if (!inserted) throw new Error('Insert returned no rows');\n\n remainingMaxReservations -= grant;\n drawSlots(satisfyingTemplates, grant);\n await bindIdleRunnerInstancesTx(tx, {\n provisionerId: params.provisionerId,\n reservationId: inserted.id,\n requiredLabels: demand.requiredLabels,\n count: grant,\n workspaceId: params.workspaceId,\n });\n reservedAfterGrant += grant;\n grants.push({\n reservationId: inserted.id,\n ...workspaceIdField,\n labels: demand.requiredLabels,\n count: grant,\n expiresAt: inserted.expiresAt,\n });\n }\n\n stats.push({\n ...workspaceIdField,\n labels: demand.requiredLabels,\n queued: demand.queued,\n reserved: reservedAfterGrant,\n oldestQueuedAt: demand.oldestQueuedAt,\n });\n }\n\n return {stats, reservations: grants};\n}\n\nasync function bindIdleRunnerInstancesTx(\n tx: Tx,\n params: {\n provisionerId: string;\n reservationId: string;\n workspaceId: string;\n requiredLabels: string[];\n count: number;\n },\n): Promise<void> {\n const idleRunners = await tx\n .select({id: providerRunners.id})\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.provisionerId, params.provisionerId),\n isNull(providerRunners.workspaceId),\n isNull(providerRunners.reservationId),\n isNull(providerRunners.intendedReservationId),\n isNull(providerRunners.runnerSessionId),\n isNotNull(providerRunners.providerRunnerId),\n eq(providerRunners.state, 'running'),\n arrayContains(providerRunners.labels, params.requiredLabels),\n exists(\n tx\n .select({id: runnerControlSessions.id})\n .from(runnerControlSessions)\n .where(\n and(\n eq(runnerControlSessions.runnerInstanceId, providerRunners.id),\n eq(runnerControlSessions.provisionerId, params.provisionerId),\n isNull(runnerControlSessions.closedAt),\n gt(runnerControlSessions.expiresAt, sql`now()`),\n ),\n ),\n ),\n ),\n )\n .orderBy(asc(providerRunners.createdAt), asc(providerRunners.id))\n .limit(params.count)\n .for('update');\n\n if (idleRunners.length === 0) return;\n\n await tx\n .update(providerRunners)\n .set({\n workspaceId: params.workspaceId,\n reservationId: params.reservationId,\n assignedAt: sql`now()`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n inArray(\n providerRunners.id,\n idleRunners.map((runner) => runner.id),\n ),\n isNull(providerRunners.workspaceId),\n isNull(providerRunners.reservationId),\n isNull(providerRunners.runnerSessionId),\n ),\n );\n}\n\nasync function listInstallationDemandWorkspaceIds(eligibleWorkspaceIds: ReadonlySet<string>) {\n if (eligibleWorkspaceIds.size === 0) return [];\n const rows = await db()\n .select({\n workspaceId: pendingJobExecutions.workspaceId,\n oldestQueuedAt: sql<Date>`min(${pendingJobExecutions.createdAt})`,\n })\n .from(pendingJobExecutions)\n .where(inArray(pendingJobExecutions.workspaceId, [...eligibleWorkspaceIds]))\n .groupBy(pendingJobExecutions.workspaceId)\n .orderBy(\n asc(sql`min(${pendingJobExecutions.createdAt})`),\n asc(pendingJobExecutions.workspaceId),\n );\n return rows.map((row) => row.workspaceId);\n}\n\nexport async function listQueuedDemandWorkspaceIds(): Promise<string[]> {\n const rows = await db()\n .select({workspaceId: pendingJobExecutions.workspaceId})\n .from(pendingJobExecutions)\n .groupBy(pendingJobExecutions.workspaceId);\n return rows.map((row) => row.workspaceId);\n}\n\nasync function listActiveWorkspaceCapabilityLabelsTx(\n tx: Tx,\n params: {workspaceId: string; windowSeconds: number},\n): Promise<string[][]> {\n const rows = await tx\n .select({labels: provisionerCapabilitySnapshots.labels})\n .from(provisionerCapabilitySnapshots)\n .innerJoin(\n provisionerTokens,\n eq(provisionerTokens.id, provisionerCapabilitySnapshots.provisionerId),\n )\n .where(\n and(\n eq(provisionerCapabilitySnapshots.workspaceId, params.workspaceId),\n eq(provisionerTokens.workspaceId, params.workspaceId),\n eq(provisionerTokens.scope, 'workspace'),\n sql`${provisionerCapabilitySnapshots.advertisedAt} > now() - (${params.windowSeconds} || ' seconds')::interval`,\n sql`${provisionerTokens.revokedAt} is null`,\n sql`(${provisionerTokens.expiresAt} is null or ${provisionerTokens.expiresAt} > now())`,\n ),\n );\n return rows.map((row) => row.labels);\n}\n\nexport async function deleteExpiredReservations(params?: {limit?: number}): Promise<number> {\n return await db().transaction(async (tx) => {\n const expiredRows = await tx\n .select({id: reservations.id})\n .from(reservations)\n .where(lt(reservations.expiresAt, sql`now()`))\n .orderBy(asc(reservations.expiresAt))\n .limit(params?.limit ?? 1000);\n return await deleteReservationsWithCleanupTx(\n tx,\n expiredRows.map((reservation) => reservation.id),\n {expiredOnly: true},\n );\n });\n}\n\nexport async function deleteReservationsByIds(ids: string[]): Promise<number> {\n if (ids.length === 0) return 0;\n\n return await db().transaction(async (tx) => {\n return await deleteReservationsWithCleanupTx(tx, ids);\n });\n}\n\nasync function deleteReservationsWithCleanupTx(\n tx: Tx,\n ids: string[],\n params: {expiredOnly?: boolean} = {},\n): Promise<number> {\n if (ids.length === 0) return 0;\n\n const affectedRunners = await tx\n .select({\n id: providerRunners.id,\n reservationId: providerRunners.reservationId,\n intendedReservationId: providerRunners.intendedReservationId,\n runnerSessionId: providerRunners.runnerSessionId,\n reservationReleasedAt: providerRunners.reservationReleasedAt,\n })\n .from(providerRunners)\n .where(\n or(\n and(\n inArray(providerRunners.reservationId, ids),\n isNull(providerRunners.runnerSessionId),\n isNull(providerRunners.reservationReleasedAt),\n ),\n inArray(providerRunners.intendedReservationId, ids),\n ),\n )\n .orderBy(asc(providerRunners.id))\n .for('update');\n const reservationRows = await tx\n .select({id: reservations.id})\n .from(reservations)\n .where(\n and(\n inArray(reservations.id, ids),\n params.expiredOnly ? lt(reservations.expiresAt, sql`now()`) : undefined,\n ),\n )\n .for('update');\n const reservationIds = reservationRows.map((reservation) => reservation.id);\n\n if (reservationIds.length === 0) return 0;\n\n const assignedRunnerIds = affectedRunners\n .filter(\n (runner) =>\n runner.reservationId &&\n reservationIds.includes(runner.reservationId) &&\n !runner.runnerSessionId &&\n !runner.reservationReleasedAt,\n )\n .map((runner) => runner.id);\n const intendedRunnerIds = affectedRunners\n .filter(\n (runner) =>\n runner.intendedReservationId && reservationIds.includes(runner.intendedReservationId),\n )\n .map((runner) => runner.id);\n if (assignedRunnerIds.length > 0) {\n await tx\n .update(runnerActivationTokens)\n .set({revokedAt: sql`now()`})\n .where(\n and(\n inArray(runnerActivationTokens.runnerInstanceId, assignedRunnerIds),\n isNull(runnerActivationTokens.consumedAt),\n isNull(runnerActivationTokens.revokedAt),\n ),\n );\n await tx\n .update(providerRunners)\n .set({\n workspaceId: null,\n reservationId: null,\n assignedAt: null,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n inArray(providerRunners.id, assignedRunnerIds),\n isNull(providerRunners.runnerSessionId),\n isNull(providerRunners.reservationReleasedAt),\n ),\n );\n }\n if (intendedRunnerIds.length > 0) {\n await tx\n .update(providerRunners)\n .set({intendedReservationId: null, updatedAt: sql`now()`})\n .where(\n and(\n inArray(providerRunners.id, intendedRunnerIds),\n inArray(providerRunners.intendedReservationId, reservationIds),\n ),\n );\n }\n\n const deleted = await tx\n .delete(reservations)\n .where(inArray(reservations.id, reservationIds))\n .returning({id: reservations.id});\n\n return deleted.length;\n}\n\nexport async function releaseReservationUnits(\n tx: Tx,\n params: {\n workspaceId: string;\n provisionerId: string;\n releases: Array<{reservationId: string; count: number}>;\n },\n): Promise<number> {\n let released = 0;\n\n for (const release of params.releases) {\n if (release.count <= 0) continue;\n\n const decremented = await tx\n .update(reservations)\n .set({count: sql`${reservations.count} - ${release.count}`})\n .where(\n and(\n eq(reservations.id, release.reservationId),\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n gt(reservations.count, release.count),\n gt(reservations.expiresAt, sql`now()`),\n ),\n )\n .returning({id: reservations.id});\n\n if (decremented.length > 0) {\n released += release.count;\n continue;\n }\n\n const deleted = await tx\n .delete(reservations)\n .where(\n and(\n eq(reservations.id, release.reservationId),\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n sql`${reservations.count} <= ${release.count}`,\n gt(reservations.expiresAt, sql`now()`),\n ),\n )\n .returning({count: reservations.count});\n\n released += deleted.reduce((total, row) => total + row.count, 0);\n }\n\n return released;\n}\n\nfunction deductProvisionerReservations(\n templates: NormalizedTemplate[],\n activeReservations: {requiredLabels: string[]; reserved: number}[],\n): void {\n for (const reservation of sortReservationRows(activeReservations)) {\n const satisfyingTemplates = templates\n .filter((template) => isSubset(reservation.requiredLabels, template.labels))\n .sort(\n (a, b) => a.labels.length - b.labels.length || a.templateKey.localeCompare(b.templateKey),\n );\n drawSlots(satisfyingTemplates, reservation.reserved);\n }\n}\n\nfunction sortDemandRows(rows: DemandRow[]): DemandRow[] {\n return [...rows].sort((a, b) => {\n const specificity = b.requiredLabels.length - a.requiredLabels.length;\n if (specificity !== 0) return specificity;\n return a.oldestQueuedAt.getTime() - b.oldestQueuedAt.getTime();\n });\n}\n\nfunction sortReservationRows<T extends {requiredLabels: string[]}>(rows: T[]): T[] {\n return [...rows].sort((a, b) => {\n const specificity = b.requiredLabels.length - a.requiredLabels.length;\n if (specificity !== 0) return specificity;\n return labelKey(a.requiredLabels).localeCompare(labelKey(b.requiredLabels));\n });\n}\n\nfunction isSubset(requiredLabels: string[], availableLabels: string[]): boolean {\n return requiredLabels.every((label) => availableLabels.includes(label));\n}\n\nfunction drawSlots(templates: NormalizedTemplate[], count: number): void {\n let remaining = count;\n for (const template of templates) {\n if (remaining === 0) return;\n const used = Math.min(template.remainingSlots, remaining);\n template.remainingSlots -= used;\n remaining -= used;\n }\n}\n\nfunction labelKey(labels: string[]): string {\n return JSON.stringify(labels);\n}\n"],"names":["canonicalizeLabels","and","arrayContains","asc","eq","exists","gt","inArray","isNotNull","isNull","lt","or","sql","db","pendingJobExecutions","provisionerCapabilitySnapshots","provisionerTokens","reservations","runnerActivationTokens","runnerControlSessions","providerRunners","pollDemandAndReserve","params","transaction","tx","pollDemandAndReserveTx","execute","workspaceId","pollDemandAndReserveLockedTx","pollInstallationDemandAndReserve","candidateWorkspaceIds","listInstallationDemandWorkspaceIds","eligibleWorkspaceIds","results","remainingMaxReservations","maxReservations","remainingTemplates","templates","map","template","labels","remainingSlots","availableSlots","signal","aborted","result","lockResult","locked","rows","stats","provisionerId","ttlSeconds","capabilityWindowSeconds","push","consumeInstallationTemplateSlots","onReservations","reduce","total","reservation","count","flatMap","satisfyingTemplates","filter","isSubset","sort","a","b","length","templateKey","localeCompare","drawSlots","demandRows","select","requiredLabels","queued","oldestQueuedAt","createdAt","from","where","groupBy","row","Date","undefined","capabilityLabels","listActiveWorkspaceCapabilityLabelsTx","windowSeconds","demand","some","activeReservationRows","reserved","expiresAt","reservedByLabels","Map","labelKey","activeProvisionerReservationRows","deductProvisionerReservations","grants","workspaceIdField","sortDemandRows","get","unreserved","Math","max","capacity","grant","min","reservedAfterGrant","inserted","insert","values","returning","id","Error","bindIdleRunnerInstancesTx","reservationId","idleRunners","intendedReservationId","runnerSessionId","providerRunnerId","state","runnerInstanceId","closedAt","orderBy","limit","for","update","set","assignedAt","updatedAt","runner","size","listQueuedDemandWorkspaceIds","innerJoin","scope","advertisedAt","revokedAt","deleteExpiredReservations","expiredRows","deleteReservationsWithCleanupTx","expiredOnly","deleteReservationsByIds","ids","affectedRunners","reservationReleasedAt","reservationRows","reservationIds","assignedRunnerIds","includes","intendedRunnerIds","consumedAt","deleted","delete","releaseReservationUnits","released","release","releases","decremented","activeReservations","sortReservationRows","specificity","getTime","availableLabels","every","label","remaining","used","JSON","stringify"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/db/reservations.ts"],"sourcesContent":["import {canonicalizeLabels} from '@shipfox/runner-labels';\nimport {\n and,\n arrayContains,\n asc,\n eq,\n exists,\n gt,\n inArray,\n isNotNull,\n isNull,\n lt,\n notExists,\n or,\n sql,\n} from 'drizzle-orm';\nimport type {Tx} from './db.js';\nimport {db} from './db.js';\nimport {pendingJobExecutions} from './schema/pending-job-executions.js';\nimport {provisionerCapabilitySnapshots} from './schema/provisioner-capability-snapshots.js';\nimport {provisionerTokens} from './schema/provisioner-tokens.js';\nimport {reservations} from './schema/reservations.js';\nimport {runnerActivationTokens} from './schema/runner-activation-tokens.js';\nimport {runnerControlSessions} from './schema/runner-control-sessions.js';\nimport {providerRunners} from './schema/runner-instances.js';\n\nexport interface ReservationTemplate {\n templateKey: string;\n labels: string[];\n availableSlots: number;\n starting: number;\n running: number;\n}\n\nexport interface DemandStat {\n workspaceId?: string;\n labels: string[];\n queued: number;\n reserved: number;\n oldestQueuedAt: Date;\n}\n\nexport interface ReservationGrant {\n reservationId: string;\n workspaceId?: string;\n labels: string[];\n count: number;\n expiresAt: Date;\n}\n\nexport interface PollDemandAndReserveParams {\n workspaceId: string;\n provisionerId: string;\n maxReservations: number;\n ttlSeconds: number;\n templates: ReservationTemplate[];\n capabilityWindowSeconds?: number;\n}\n\nexport interface InstallationPollDemandAndReserveParams {\n provisionerId: string;\n maxReservations: number;\n ttlSeconds: number;\n templates: ReservationTemplate[];\n capabilityWindowSeconds: number;\n eligibleWorkspaceIds: ReadonlySet<string>;\n signal?: AbortSignal;\n onReservations?: (reservations: ReservationGrant[]) => void;\n}\n\ntype DemandScope = 'installation' | 'workspace';\n\ntype PollDemandAndReserveLockedParams = PollDemandAndReserveParams & {\n scope: DemandScope;\n};\n\ninterface NormalizedTemplate {\n templateKey: string;\n labels: string[];\n remainingSlots: number;\n}\n\ninterface DemandRow {\n requiredLabels: string[];\n queued: number;\n oldestQueuedAt: Date;\n}\n\nexport async function pollDemandAndReserve(\n params: PollDemandAndReserveParams,\n): Promise<{stats: DemandStat[]; reservations: ReservationGrant[]}> {\n return await db().transaction(async (tx) => {\n return await pollDemandAndReserveTx(tx, params);\n });\n}\n\nexport async function pollDemandAndReserveTx(\n tx: Tx,\n params: PollDemandAndReserveParams,\n): Promise<{stats: DemandStat[]; reservations: ReservationGrant[]}> {\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${params.workspaceId}))`);\n return await pollDemandAndReserveLockedTx(tx, {...params, scope: 'workspace'});\n}\n\nexport async function pollInstallationDemandAndReserve(\n params: InstallationPollDemandAndReserveParams,\n): Promise<{stats: DemandStat[]; reservations: ReservationGrant[]}> {\n const candidateWorkspaceIds = await listInstallationDemandWorkspaceIds(\n params.eligibleWorkspaceIds,\n );\n const results: Array<{stats: DemandStat[]; reservations: ReservationGrant[]}> = [];\n let remainingMaxReservations = params.maxReservations;\n const remainingTemplates = params.templates.map((template) => ({\n ...template,\n labels: [...canonicalizeLabels(template.labels)],\n remainingSlots: template.availableSlots,\n }));\n for (const workspaceId of candidateWorkspaceIds) {\n if (params.signal?.aborted || remainingMaxReservations === 0) break;\n const result = await db().transaction(async (tx) => {\n const lockResult = await tx.execute<{locked: boolean}>(\n sql`select pg_try_advisory_xact_lock(hashtext(${workspaceId})) as locked`,\n );\n const locked = lockResult.rows[0];\n if (!locked?.locked) return {stats: [], reservations: []};\n return await pollDemandAndReserveLockedTx(tx, {\n workspaceId,\n provisionerId: params.provisionerId,\n maxReservations: remainingMaxReservations,\n ttlSeconds: params.ttlSeconds,\n templates: remainingTemplates.map((template) => ({\n ...template,\n availableSlots: template.remainingSlots,\n })),\n capabilityWindowSeconds: params.capabilityWindowSeconds,\n scope: 'installation',\n });\n });\n results.push(result);\n consumeInstallationTemplateSlots(remainingTemplates, result.reservations);\n params.onReservations?.(result.reservations);\n remainingMaxReservations -= result.reservations.reduce(\n (total, reservation) => total + reservation.count,\n 0,\n );\n }\n return {\n stats: results.flatMap((result) => result.stats),\n reservations: results.flatMap((result) => result.reservations),\n };\n}\n\nfunction consumeInstallationTemplateSlots(\n templates: NormalizedTemplate[],\n reservations: ReservationGrant[],\n): void {\n for (const reservation of reservations) {\n const satisfyingTemplates = templates\n .filter((template) => isSubset(reservation.labels, template.labels))\n .sort(\n (a, b) => a.labels.length - b.labels.length || a.templateKey.localeCompare(b.templateKey),\n );\n drawSlots(satisfyingTemplates, reservation.count);\n }\n}\n\nasync function pollDemandAndReserveLockedTx(\n tx: Tx,\n params: PollDemandAndReserveLockedParams,\n): Promise<{stats: DemandStat[]; reservations: ReservationGrant[]}> {\n let demandRows = (\n await tx\n .select({\n requiredLabels: pendingJobExecutions.requiredLabels,\n queued: sql<number>`count(*)::int`,\n oldestQueuedAt: sql<Date | string>`min(${pendingJobExecutions.createdAt})`,\n })\n .from(pendingJobExecutions)\n .where(eq(pendingJobExecutions.workspaceId, params.workspaceId))\n .groupBy(pendingJobExecutions.requiredLabels)\n ).map((row) => ({\n ...row,\n oldestQueuedAt: new Date(row.oldestQueuedAt),\n }));\n if (params.capabilityWindowSeconds !== undefined) {\n const capabilityLabels = await listActiveWorkspaceCapabilityLabelsTx(tx, {\n workspaceId: params.workspaceId,\n windowSeconds: params.capabilityWindowSeconds,\n });\n demandRows = demandRows.filter(\n (demand) => !capabilityLabels.some((labels) => isSubset(demand.requiredLabels, labels)),\n );\n }\n\n const activeReservationRows = await tx\n .select({\n requiredLabels: reservations.requiredLabels,\n reserved: sql<number>`coalesce(sum(${reservations.count}), 0)::int`,\n })\n .from(reservations)\n .where(\n and(eq(reservations.workspaceId, params.workspaceId), gt(reservations.expiresAt, sql`now()`)),\n )\n .groupBy(reservations.requiredLabels);\n\n const reservedByLabels = new Map(\n activeReservationRows.map((row) => [labelKey(row.requiredLabels), row.reserved]),\n );\n const activeProvisionerReservationRows = await tx\n .select({\n requiredLabels: reservations.requiredLabels,\n reserved: sql<number>`coalesce(sum(${reservations.count}), 0)::int`,\n })\n .from(reservations)\n .where(\n and(\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n gt(reservations.expiresAt, sql`now()`),\n ),\n )\n .groupBy(reservations.requiredLabels);\n\n const templates = params.templates.map((template) => ({\n templateKey: template.templateKey,\n labels: [...canonicalizeLabels(template.labels)],\n remainingSlots: template.availableSlots,\n }));\n deductProvisionerReservations(templates, activeProvisionerReservationRows);\n const stats: DemandStat[] = [];\n const grants: ReservationGrant[] = [];\n let remainingMaxReservations = params.maxReservations;\n const workspaceIdField =\n params.capabilityWindowSeconds === undefined ? {} : {workspaceId: params.workspaceId};\n\n for (const demand of sortDemandRows(demandRows)) {\n const satisfyingTemplates = templates\n .filter((template) => isSubset(demand.requiredLabels, template.labels))\n .sort(\n (a, b) => a.labels.length - b.labels.length || a.templateKey.localeCompare(b.templateKey),\n );\n\n if (satisfyingTemplates.length === 0) continue;\n\n const reserved = reservedByLabels.get(labelKey(demand.requiredLabels)) ?? 0;\n const unreserved = Math.max(0, demand.queued - reserved);\n const capacity = satisfyingTemplates.reduce(\n (total, template) => total + template.remainingSlots,\n 0,\n );\n const grant = Math.min(unreserved, capacity, remainingMaxReservations);\n let reservedAfterGrant = reserved;\n\n if (grant > 0 && params.maxReservations > 0) {\n const [inserted] = await tx\n .insert(reservations)\n .values({\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n requiredLabels: demand.requiredLabels,\n count: grant,\n expiresAt: sql`now() + (${params.ttlSeconds} || ' seconds')::interval`,\n })\n .returning({id: reservations.id, expiresAt: reservations.expiresAt});\n\n if (!inserted) throw new Error('Insert returned no rows');\n\n remainingMaxReservations -= grant;\n drawSlots(satisfyingTemplates, grant);\n await bindIdleRunnerInstancesTx(tx, {\n provisionerId: params.provisionerId,\n reservationId: inserted.id,\n requiredLabels: demand.requiredLabels,\n count: grant,\n workspaceId: params.workspaceId,\n scope: params.scope,\n });\n reservedAfterGrant += grant;\n grants.push({\n reservationId: inserted.id,\n ...workspaceIdField,\n labels: demand.requiredLabels,\n count: grant,\n expiresAt: inserted.expiresAt,\n });\n }\n\n stats.push({\n ...workspaceIdField,\n labels: demand.requiredLabels,\n queued: demand.queued,\n reserved: reservedAfterGrant,\n oldestQueuedAt: demand.oldestQueuedAt,\n });\n }\n\n return {stats, reservations: grants};\n}\n\nasync function bindIdleRunnerInstancesTx(\n tx: Tx,\n params: {\n provisionerId: string;\n reservationId: string;\n workspaceId: string;\n requiredLabels: string[];\n count: number;\n scope: DemandScope;\n },\n): Promise<void> {\n // Reservation expiry is the activation grace deadline. A live reservation\n // protects a runner that is still booting; an expired or missing row is stale.\n const canBindRunner = () =>\n and(\n or(\n and(isNull(providerRunners.workspaceId), isNull(providerRunners.reservationId)),\n and(\n isNotNull(providerRunners.reservationId),\n params.scope === 'installation'\n ? undefined\n : or(\n isNull(providerRunners.workspaceId),\n eq(providerRunners.workspaceId, params.workspaceId),\n ),\n notExists(\n tx\n .select({id: reservations.id})\n .from(reservations)\n .where(\n and(\n eq(reservations.id, providerRunners.reservationId),\n gt(reservations.expiresAt, sql`now()`),\n ),\n ),\n ),\n ),\n ),\n or(\n isNull(providerRunners.intendedReservationId),\n notExists(\n tx\n .select({id: reservations.id})\n .from(reservations)\n .where(\n and(\n eq(reservations.id, providerRunners.intendedReservationId),\n gt(reservations.expiresAt, sql`now()`),\n ),\n ),\n ),\n ),\n isNull(providerRunners.reservationReleasedAt),\n isNull(providerRunners.runnerSessionId),\n );\n\n const idleRunners = await tx\n .select({id: providerRunners.id})\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.provisionerId, params.provisionerId),\n canBindRunner(),\n isNotNull(providerRunners.providerRunnerId),\n eq(providerRunners.state, 'running'),\n arrayContains(providerRunners.labels, params.requiredLabels),\n exists(\n tx\n .select({id: runnerControlSessions.id})\n .from(runnerControlSessions)\n .where(\n and(\n eq(runnerControlSessions.runnerInstanceId, providerRunners.id),\n eq(runnerControlSessions.provisionerId, params.provisionerId),\n isNull(runnerControlSessions.closedAt),\n gt(runnerControlSessions.expiresAt, sql`now()`),\n ),\n ),\n ),\n ),\n )\n .orderBy(asc(providerRunners.createdAt), asc(providerRunners.id))\n .limit(params.count)\n .for('update');\n\n if (idleRunners.length === 0) return;\n\n await tx\n .update(runnerActivationTokens)\n .set({revokedAt: sql`now()`})\n .where(\n and(\n inArray(\n runnerActivationTokens.runnerInstanceId,\n idleRunners.map((runner) => runner.id),\n ),\n isNull(runnerActivationTokens.consumedAt),\n isNull(runnerActivationTokens.revokedAt),\n ),\n );\n\n await tx\n .update(providerRunners)\n .set({\n workspaceId: params.workspaceId,\n reservationId: params.reservationId,\n intendedReservationId: null,\n assignedAt: sql`now()`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n inArray(\n providerRunners.id,\n idleRunners.map((runner) => runner.id),\n ),\n canBindRunner(),\n ),\n );\n}\n\nasync function listInstallationDemandWorkspaceIds(eligibleWorkspaceIds: ReadonlySet<string>) {\n if (eligibleWorkspaceIds.size === 0) return [];\n const rows = await db()\n .select({\n workspaceId: pendingJobExecutions.workspaceId,\n oldestQueuedAt: sql<Date>`min(${pendingJobExecutions.createdAt})`,\n })\n .from(pendingJobExecutions)\n .where(inArray(pendingJobExecutions.workspaceId, [...eligibleWorkspaceIds]))\n .groupBy(pendingJobExecutions.workspaceId)\n .orderBy(\n asc(sql`min(${pendingJobExecutions.createdAt})`),\n asc(pendingJobExecutions.workspaceId),\n );\n return rows.map((row) => row.workspaceId);\n}\n\nexport async function listQueuedDemandWorkspaceIds(): Promise<string[]> {\n const rows = await db()\n .select({workspaceId: pendingJobExecutions.workspaceId})\n .from(pendingJobExecutions)\n .groupBy(pendingJobExecutions.workspaceId);\n return rows.map((row) => row.workspaceId);\n}\n\nasync function listActiveWorkspaceCapabilityLabelsTx(\n tx: Tx,\n params: {workspaceId: string; windowSeconds: number},\n): Promise<string[][]> {\n const rows = await tx\n .select({labels: provisionerCapabilitySnapshots.labels})\n .from(provisionerCapabilitySnapshots)\n .innerJoin(\n provisionerTokens,\n eq(provisionerTokens.id, provisionerCapabilitySnapshots.provisionerId),\n )\n .where(\n and(\n eq(provisionerCapabilitySnapshots.workspaceId, params.workspaceId),\n eq(provisionerTokens.workspaceId, params.workspaceId),\n eq(provisionerTokens.scope, 'workspace'),\n sql`${provisionerCapabilitySnapshots.advertisedAt} > now() - (${params.windowSeconds} || ' seconds')::interval`,\n sql`${provisionerTokens.revokedAt} is null`,\n sql`(${provisionerTokens.expiresAt} is null or ${provisionerTokens.expiresAt} > now())`,\n ),\n );\n return rows.map((row) => row.labels);\n}\n\nexport async function deleteExpiredReservations(params?: {limit?: number}): Promise<number> {\n return await db().transaction(async (tx) => {\n const expiredRows = await tx\n .select({id: reservations.id})\n .from(reservations)\n .where(lt(reservations.expiresAt, sql`now()`))\n .orderBy(asc(reservations.expiresAt))\n .limit(params?.limit ?? 1000);\n return await deleteReservationsWithCleanupTx(\n tx,\n expiredRows.map((reservation) => reservation.id),\n {expiredOnly: true},\n );\n });\n}\n\nexport async function deleteReservationsByIds(ids: string[]): Promise<number> {\n if (ids.length === 0) return 0;\n\n return await db().transaction(async (tx) => {\n return await deleteReservationsWithCleanupTx(tx, ids);\n });\n}\n\nasync function deleteReservationsWithCleanupTx(\n tx: Tx,\n ids: string[],\n params: {expiredOnly?: boolean} = {},\n): Promise<number> {\n if (ids.length === 0) return 0;\n\n const affectedRunners = await tx\n .select({\n id: providerRunners.id,\n reservationId: providerRunners.reservationId,\n intendedReservationId: providerRunners.intendedReservationId,\n runnerSessionId: providerRunners.runnerSessionId,\n reservationReleasedAt: providerRunners.reservationReleasedAt,\n })\n .from(providerRunners)\n .where(\n or(\n and(\n inArray(providerRunners.reservationId, ids),\n isNull(providerRunners.runnerSessionId),\n isNull(providerRunners.reservationReleasedAt),\n ),\n inArray(providerRunners.intendedReservationId, ids),\n ),\n )\n .orderBy(asc(providerRunners.id))\n .for('update');\n const reservationRows = await tx\n .select({id: reservations.id})\n .from(reservations)\n .where(\n and(\n inArray(reservations.id, ids),\n params.expiredOnly ? lt(reservations.expiresAt, sql`now()`) : undefined,\n ),\n )\n .for('update');\n const reservationIds = reservationRows.map((reservation) => reservation.id);\n\n if (reservationIds.length === 0) return 0;\n\n const assignedRunnerIds = affectedRunners\n .filter(\n (runner) =>\n runner.reservationId &&\n reservationIds.includes(runner.reservationId) &&\n !runner.runnerSessionId &&\n !runner.reservationReleasedAt,\n )\n .map((runner) => runner.id);\n const intendedRunnerIds = affectedRunners\n .filter(\n (runner) =>\n runner.intendedReservationId && reservationIds.includes(runner.intendedReservationId),\n )\n .map((runner) => runner.id);\n if (assignedRunnerIds.length > 0) {\n await tx\n .update(runnerActivationTokens)\n .set({revokedAt: sql`now()`})\n .where(\n and(\n inArray(runnerActivationTokens.runnerInstanceId, assignedRunnerIds),\n isNull(runnerActivationTokens.consumedAt),\n isNull(runnerActivationTokens.revokedAt),\n ),\n );\n await tx\n .update(providerRunners)\n .set({\n workspaceId: null,\n reservationId: null,\n assignedAt: null,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n inArray(providerRunners.id, assignedRunnerIds),\n isNull(providerRunners.runnerSessionId),\n isNull(providerRunners.reservationReleasedAt),\n ),\n );\n }\n if (intendedRunnerIds.length > 0) {\n await tx\n .update(providerRunners)\n .set({intendedReservationId: null, updatedAt: sql`now()`})\n .where(\n and(\n inArray(providerRunners.id, intendedRunnerIds),\n inArray(providerRunners.intendedReservationId, reservationIds),\n ),\n );\n }\n\n const deleted = await tx\n .delete(reservations)\n .where(inArray(reservations.id, reservationIds))\n .returning({id: reservations.id});\n\n return deleted.length;\n}\n\nexport async function releaseReservationUnits(\n tx: Tx,\n params: {\n workspaceId: string;\n provisionerId: string;\n releases: Array<{reservationId: string; count: number}>;\n },\n): Promise<number> {\n let released = 0;\n\n for (const release of params.releases) {\n if (release.count <= 0) continue;\n\n const decremented = await tx\n .update(reservations)\n .set({count: sql`${reservations.count} - ${release.count}`})\n .where(\n and(\n eq(reservations.id, release.reservationId),\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n gt(reservations.count, release.count),\n gt(reservations.expiresAt, sql`now()`),\n ),\n )\n .returning({id: reservations.id});\n\n if (decremented.length > 0) {\n released += release.count;\n continue;\n }\n\n const deleted = await tx\n .delete(reservations)\n .where(\n and(\n eq(reservations.id, release.reservationId),\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n sql`${reservations.count} <= ${release.count}`,\n gt(reservations.expiresAt, sql`now()`),\n ),\n )\n .returning({count: reservations.count});\n\n released += deleted.reduce((total, row) => total + row.count, 0);\n }\n\n return released;\n}\n\nfunction deductProvisionerReservations(\n templates: NormalizedTemplate[],\n activeReservations: {requiredLabels: string[]; reserved: number}[],\n): void {\n for (const reservation of sortReservationRows(activeReservations)) {\n const satisfyingTemplates = templates\n .filter((template) => isSubset(reservation.requiredLabels, template.labels))\n .sort(\n (a, b) => a.labels.length - b.labels.length || a.templateKey.localeCompare(b.templateKey),\n );\n drawSlots(satisfyingTemplates, reservation.reserved);\n }\n}\n\nfunction sortDemandRows(rows: DemandRow[]): DemandRow[] {\n return [...rows].sort((a, b) => {\n const specificity = b.requiredLabels.length - a.requiredLabels.length;\n if (specificity !== 0) return specificity;\n return a.oldestQueuedAt.getTime() - b.oldestQueuedAt.getTime();\n });\n}\n\nfunction sortReservationRows<T extends {requiredLabels: string[]}>(rows: T[]): T[] {\n return [...rows].sort((a, b) => {\n const specificity = b.requiredLabels.length - a.requiredLabels.length;\n if (specificity !== 0) return specificity;\n return labelKey(a.requiredLabels).localeCompare(labelKey(b.requiredLabels));\n });\n}\n\nfunction isSubset(requiredLabels: string[], availableLabels: string[]): boolean {\n return requiredLabels.every((label) => availableLabels.includes(label));\n}\n\nfunction drawSlots(templates: NormalizedTemplate[], count: number): void {\n let remaining = count;\n for (const template of templates) {\n if (remaining === 0) return;\n const used = Math.min(template.remainingSlots, remaining);\n template.remainingSlots -= used;\n remaining -= used;\n }\n}\n\nfunction labelKey(labels: string[]): string {\n return JSON.stringify(labels);\n}\n"],"names":["canonicalizeLabels","and","arrayContains","asc","eq","exists","gt","inArray","isNotNull","isNull","lt","notExists","or","sql","db","pendingJobExecutions","provisionerCapabilitySnapshots","provisionerTokens","reservations","runnerActivationTokens","runnerControlSessions","providerRunners","pollDemandAndReserve","params","transaction","tx","pollDemandAndReserveTx","execute","workspaceId","pollDemandAndReserveLockedTx","scope","pollInstallationDemandAndReserve","candidateWorkspaceIds","listInstallationDemandWorkspaceIds","eligibleWorkspaceIds","results","remainingMaxReservations","maxReservations","remainingTemplates","templates","map","template","labels","remainingSlots","availableSlots","signal","aborted","result","lockResult","locked","rows","stats","provisionerId","ttlSeconds","capabilityWindowSeconds","push","consumeInstallationTemplateSlots","onReservations","reduce","total","reservation","count","flatMap","satisfyingTemplates","filter","isSubset","sort","a","b","length","templateKey","localeCompare","drawSlots","demandRows","select","requiredLabels","queued","oldestQueuedAt","createdAt","from","where","groupBy","row","Date","undefined","capabilityLabels","listActiveWorkspaceCapabilityLabelsTx","windowSeconds","demand","some","activeReservationRows","reserved","expiresAt","reservedByLabels","Map","labelKey","activeProvisionerReservationRows","deductProvisionerReservations","grants","workspaceIdField","sortDemandRows","get","unreserved","Math","max","capacity","grant","min","reservedAfterGrant","inserted","insert","values","returning","id","Error","bindIdleRunnerInstancesTx","reservationId","canBindRunner","intendedReservationId","reservationReleasedAt","runnerSessionId","idleRunners","providerRunnerId","state","runnerInstanceId","closedAt","orderBy","limit","for","update","set","revokedAt","runner","consumedAt","assignedAt","updatedAt","size","listQueuedDemandWorkspaceIds","innerJoin","advertisedAt","deleteExpiredReservations","expiredRows","deleteReservationsWithCleanupTx","expiredOnly","deleteReservationsByIds","ids","affectedRunners","reservationRows","reservationIds","assignedRunnerIds","includes","intendedRunnerIds","deleted","delete","releaseReservationUnits","released","release","releases","decremented","activeReservations","sortReservationRows","specificity","getTime","availableLabels","every","label","remaining","used","JSON","stringify"],"mappings":"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"}
@@ -61,6 +61,9 @@ export declare function listActiveRunnerInstanceCountsByTemplateTx(tx: Tx, param
61
61
  workspaceId: string;
62
62
  provisionerId: string;
63
63
  }): Promise<ActiveRunnerInstanceTemplateCount[]>;
64
+ export declare function countStaleEnrolledRunnerInstances(params: {
65
+ graceSeconds: number;
66
+ }): Promise<number>;
64
67
  export declare function listActiveRunnerInstances(params: {
65
68
  workspaceId: string;
66
69
  windowSeconds: number;
@@ -1 +1 @@
1
- {"version":3,"file":"runner-instances.d.ts","sourceRoot":"","sources":["../../src/db/runner-instances.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner-instances.d.ts","sourceRoot":"","sources":["../../src/db/runner-instances.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ import { releaseReservationUnits } from './reservations.js';
8
8
  import { ephemeralRegistrationTokens } from './schema/ephemeral-registration-tokens.js';
9
9
  import { provisionerTokens } from './schema/provisioner-tokens.js';
10
10
  import { reservations } from './schema/reservations.js';
11
+ import { runnerControlSessions } from './schema/runner-control-sessions.js';
11
12
  import { providerRunners, toRunnerInstance } from './schema/runner-instances.js';
12
13
  import { runnerSessions } from './schema/runner-sessions.js';
13
14
  import { runningJobExecutions } from './schema/running-job-executions.js';
@@ -80,7 +81,7 @@ export async function reportRunnerInstances(params) {
80
81
  ],
81
82
  targetWhere: isNotNull(providerRunners.providerRunnerId),
82
83
  set: {
83
- reservationId: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(excluded.reservation_id, ${providerRunners.reservationId}) ELSE ${providerRunners.reservationId} END`,
84
+ reservationId: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(${providerRunners.reservationId}, excluded.reservation_id) ELSE ${providerRunners.reservationId} END`,
84
85
  templateKey: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(excluded.template_key, ${providerRunners.templateKey}) ELSE ${providerRunners.templateKey} END`,
85
86
  labels: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN excluded.labels ELSE ${providerRunners.labels} END`,
86
87
  state: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN excluded.state ELSE ${providerRunners.state} END`,
@@ -122,6 +123,14 @@ export async function listActiveRunnerInstanceCountsByTemplateTx(tx, params) {
122
123
  }
123
124
  ] : []);
124
125
  }
126
+ export async function countStaleEnrolledRunnerInstances(params) {
127
+ const [row] = await db().select({
128
+ count: sql`count(*)::int`
129
+ }).from(providerRunners).where(and(eq(providerRunners.state, 'running'), isNull(providerRunners.workspaceId), isNull(providerRunners.runnerSessionId), lt(providerRunners.reportedAt, staleRunnerInstanceCutoff(params.graceSeconds)), exists(db().select({
130
+ id: runnerControlSessions.id
131
+ }).from(runnerControlSessions).where(and(eq(runnerControlSessions.runnerInstanceId, providerRunners.id), isNull(runnerControlSessions.closedAt), gt(runnerControlSessions.expiresAt, sql`now()`))))));
132
+ return row?.count ?? 0;
133
+ }
125
134
  export async function listActiveRunnerInstances(params) {
126
135
  const rows = await db().select().from(providerRunners).where(and(eq(providerRunners.workspaceId, params.workspaceId), inArray(providerRunners.state, activeStates), sql`${providerRunners.updatedAt} > now() - (${params.windowSeconds} || ' seconds')::interval`)).orderBy(desc(providerRunners.updatedAt), desc(providerRunners.id)).limit(params.limit ?? 1000);
127
136
  return rows.map(toRunnerInstance);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/runner-instances.ts"],"sourcesContent":["import {logger} from '@shipfox/node-opentelemetry';\nimport {\n and,\n asc,\n desc,\n eq,\n exists,\n gt,\n inArray,\n isNotNull,\n isNull,\n lt,\n notExists,\n notInArray,\n or,\n type SQL,\n sql,\n} from 'drizzle-orm';\nimport {alias} from 'drizzle-orm/pg-core';\nimport type {RunnerInstance, RunnerInstanceState} from '#core/entities/runner-instance.js';\nimport {sanitizeRunnerLabels} from '#core/runner-labels.js';\nimport type {Tx} from './db.js';\nimport {db} from './db.js';\nimport {\n listRunningJobExecutionsByRunnerInstanceTx,\n type RunnerInstanceBoundJobExecution,\n} from './job-executions.js';\nimport {releaseReservationUnits} from './reservations.js';\nimport {ephemeralRegistrationTokens} from './schema/ephemeral-registration-tokens.js';\nimport {provisionerTokens} from './schema/provisioner-tokens.js';\nimport {reservations} from './schema/reservations.js';\nimport {providerRunners, toRunnerInstance} from './schema/runner-instances.js';\nimport {runnerSessions} from './schema/runner-sessions.js';\nimport {runningJobExecutions} from './schema/running-job-executions.js';\n\nexport const terminalStates = [\n 'stopped',\n 'failed',\n 'terminated',\n] as const satisfies readonly RunnerInstanceState[];\nexport const activeStates = [\n 'starting',\n 'running',\n 'stopping',\n] as const satisfies readonly RunnerInstanceState[];\nexport const divergenceCountStates = ['starting', 'running'] as const satisfies readonly Extract<\n RunnerInstanceState,\n 'starting' | 'running'\n>[];\n\nexport type RunnerInstanceTerminateIntentReason = 'job-cancelled';\n\nexport interface RunnerInstanceTerminateIntent {\n providerRunnerId: string;\n reason: RunnerInstanceTerminateIntentReason;\n}\n\nexport interface ActiveRunnerInstanceTemplateCount {\n templateKey: string;\n state: (typeof divergenceCountStates)[number];\n count: number;\n}\n\nexport interface RunnerInstanceReportEvent {\n providerRunnerId: string;\n reservationId: string | null;\n templateKey: string | null;\n labels: string[];\n state: RunnerInstanceState;\n reason: string | null;\n runnerSessionId: string | null;\n providerKind: string | null;\n reportedAt: Date;\n}\n\nexport interface ReportRunnerInstancesParams {\n scope: 'installation' | 'workspace';\n workspaceId: string | null;\n provisionerId: string;\n events: RunnerInstanceReportEvent[];\n}\n\nexport interface ReconcileRunnerInstancesParams {\n workspaceId: string | null;\n provisionerId: string;\n observedRunnerInstanceIds: string[];\n terminateGraceSeconds: number;\n}\n\nexport interface ReconcileRunnerInstancesDbResult {\n observedRows: RunnerInstance[];\n boundJobExecutionsByRunnerInstanceId: Map<string, RunnerInstanceBoundJobExecution>;\n absentIds: string[];\n reservationsReleased: number;\n}\n\nexport interface ReapStaleRunnerInstancesResult {\n reaped: number;\n reservationsReleased: number;\n}\n\nexport async function attachRunnerInstanceProviderId(params: {\n runnerInstanceId: string;\n provisionerId: string;\n providerRunnerId: string;\n}): Promise<boolean> {\n const updated = await db()\n .update(providerRunners)\n .set({providerRunnerId: params.providerRunnerId, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n isNull(providerRunners.providerRunnerId),\n notInArray(providerRunners.state, [...terminalStates]),\n ),\n )\n .returning({id: providerRunners.id});\n return updated.length === 1;\n}\n\ninterface RunnerInstanceReportRow extends RunnerInstanceReportEvent {\n startedAt: Date | null;\n stoppingAt: Date | null;\n stoppedAt: Date | null;\n failedAt: Date | null;\n terminatedAt: Date | null;\n}\n\ntype RunnerInstanceMilestoneColumn =\n | typeof providerRunners.startedAt\n | typeof providerRunners.stoppingAt\n | typeof providerRunners.stoppedAt\n | typeof providerRunners.failedAt\n | typeof providerRunners.terminatedAt;\n\nexport async function reportRunnerInstances(params: ReportRunnerInstancesParams): Promise<{\n accepted: number;\n reservationsReleased: number;\n terminateIntentsHonored: RunnerInstanceTerminateIntent[];\n}> {\n if (params.events.length === 0)\n return {accepted: 0, reservationsReleased: 0, terminateIntentsHonored: []};\n\n return await db().transaction(async (tx) => {\n const receivedAt = new Date();\n const aggregatedEvents = aggregateEvents(params.events, receivedAt);\n const hasTerminalEvent = aggregatedEvents.some((event) => isTerminalState(event.state));\n\n if (hasTerminalEvent) {\n await tx.execute(\n sql`select pg_advisory_xact_lock(hashtext(${params.workspaceId ?? params.provisionerId}))`,\n );\n }\n\n const events = await hydrateRunnerSessionIdsFromConsumedTokens(tx, params, aggregatedEvents);\n const terminateIntentsHonored = await listTerminateIntentsHonoredByTerminatedReportsTx(\n tx,\n params,\n events,\n );\n\n const values = events.map((event) => ({\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n providerRunnerId: event.providerRunnerId,\n reservationId: event.reservationId,\n templateKey: event.templateKey,\n labels: sanitizeRunnerLabels(event.labels, {\n scope: params.scope,\n logLevel: 'debug',\n source: 'runner instance report',\n }),\n state: event.state,\n reason: event.reason,\n runnerSessionId: event.runnerSessionId,\n providerKind: event.providerKind,\n reportedAt: event.reportedAt > receivedAt ? receivedAt : event.reportedAt,\n startedAt: event.startedAt,\n stoppingAt: event.stoppingAt,\n stoppedAt: event.stoppedAt,\n failedAt: event.failedAt,\n terminatedAt: event.terminatedAt,\n }));\n\n await tx\n .insert(providerRunners)\n .values(values)\n .onConflictDoUpdate({\n target: [providerRunners.provisionerId, providerRunners.providerRunnerId],\n targetWhere: isNotNull(providerRunners.providerRunnerId),\n set: {\n reservationId: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(excluded.reservation_id, ${providerRunners.reservationId}) ELSE ${providerRunners.reservationId} END`,\n templateKey: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(excluded.template_key, ${providerRunners.templateKey}) ELSE ${providerRunners.templateKey} END`,\n labels: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN excluded.labels ELSE ${providerRunners.labels} END`,\n state: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN excluded.state ELSE ${providerRunners.state} END`,\n reason: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN excluded.reason ELSE ${providerRunners.reason} END`,\n runnerSessionId: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(${providerRunners.runnerSessionId}, excluded.runner_session_id) ELSE ${providerRunners.runnerSessionId} END`,\n providerKind: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(excluded.provider_kind, ${providerRunners.providerKind}) ELSE ${providerRunners.providerKind} END`,\n reportedAt: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN excluded.reported_at ELSE ${providerRunners.reportedAt} END`,\n startedAt: firstObservedAt(providerRunners.startedAt, sql`excluded.started_at`),\n stoppingAt: firstObservedAt(providerRunners.stoppingAt, sql`excluded.stopping_at`),\n stoppedAt: firstObservedAt(providerRunners.stoppedAt, sql`excluded.stopped_at`),\n failedAt: firstObservedAt(providerRunners.failedAt, sql`excluded.failed_at`),\n terminatedAt: firstObservedAt(providerRunners.terminatedAt, sql`excluded.terminated_at`),\n updatedAt: sql`now()`,\n },\n setWhere: sql`\n ${providerRunnerProjectionUpdateCondition()}\n OR ${providerRunnerMilestoneUpdateCondition()}\n `,\n });\n\n const reservationsReleased = hasTerminalEvent\n ? await releaseTerminalRunnerInstanceReservations(tx, params, events)\n : 0;\n\n return {accepted: events.length, reservationsReleased, terminateIntentsHonored};\n });\n}\n\nexport async function listActiveRunnerInstanceCountsByTemplateTx(\n tx: Tx,\n params: {workspaceId: string; provisionerId: string},\n): Promise<ActiveRunnerInstanceTemplateCount[]> {\n const rows = await tx\n .select({\n templateKey: providerRunners.templateKey,\n state: providerRunners.state,\n count: sql<number>`count(*)::int`,\n })\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.workspaceId, params.workspaceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n inArray(providerRunners.state, divergenceCountStates),\n isNotNull(providerRunners.templateKey),\n ),\n )\n .groupBy(providerRunners.templateKey, providerRunners.state);\n\n return rows.flatMap((row) =>\n row.templateKey && isDivergenceCountState(row.state)\n ? [{templateKey: row.templateKey, state: row.state, count: row.count}]\n : [],\n );\n}\n\nexport async function listActiveRunnerInstances(params: {\n workspaceId: string;\n windowSeconds: number;\n limit?: number;\n}): Promise<RunnerInstance[]> {\n const rows = await db()\n .select()\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.workspaceId, params.workspaceId),\n inArray(providerRunners.state, activeStates),\n sql`${providerRunners.updatedAt} > now() - (${params.windowSeconds} || ' seconds')::interval`,\n ),\n )\n .orderBy(desc(providerRunners.updatedAt), desc(providerRunners.id))\n .limit(params.limit ?? 1000);\n\n return rows.map(toRunnerInstance);\n}\n\nexport async function listProvisionerTerminateIntents(params: {\n workspaceId: string;\n provisionerId: string;\n limit: number;\n}): Promise<string[]> {\n return await db().transaction(async (tx) => {\n const rows = await listProvisionerTerminateIntentRowsTx(tx, params);\n return rows.map((row) => row.providerRunnerId);\n });\n}\n\nexport async function listProvisionerTerminateIntentRowsTx(\n tx: Tx,\n params: {\n workspaceId: string;\n provisionerId: string;\n limit: number;\n },\n): Promise<RunnerInstanceTerminateIntent[]> {\n const rows = await provisionerTerminateIntentsQuery(tx, params)\n .orderBy(asc(providerRunners.providerRunnerId))\n .limit(params.limit + 1);\n\n const truncated = rows.length > params.limit;\n const returnedRows = truncated ? rows.slice(0, params.limit) : rows;\n if (truncated) {\n logger().warn(\n {\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n limit: params.limit,\n returnedCount: returnedRows.length,\n },\n 'provisioner terminate intents truncated by poll-demand limit',\n );\n }\n\n return returnedRows.flatMap((row) =>\n row.providerRunnerId ? [{...row, providerRunnerId: row.providerRunnerId}] : [],\n );\n}\n\nfunction provisionerTerminateIntentsQuery(\n tx: Tx,\n params: {workspaceId: string; provisionerId: string; providerRunnerIds?: string[]},\n) {\n const newerRunningJobExecutions = alias(runningJobExecutions, 'newer_running_jobs');\n\n return tx\n .select({\n providerRunnerId: providerRunners.providerRunnerId,\n reason: sql<RunnerInstanceTerminateIntentReason>`'job-cancelled'`,\n })\n .from(runningJobExecutions)\n .innerJoin(\n providerRunners,\n and(\n eq(providerRunners.workspaceId, runningJobExecutions.workspaceId),\n eq(providerRunners.provisionerId, runningJobExecutions.provisionerId),\n eq(providerRunners.providerRunnerId, runningJobExecutions.providerRunnerId),\n ),\n )\n .where(\n and(\n eq(runningJobExecutions.workspaceId, params.workspaceId),\n eq(runningJobExecutions.provisionerId, params.provisionerId),\n isNotNull(providerRunners.providerRunnerId),\n isNotNull(runningJobExecutions.cancellationRequestedAt),\n inArray(providerRunners.state, activeStates),\n params.providerRunnerIds && params.providerRunnerIds.length > 0\n ? inArray(providerRunners.providerRunnerId, params.providerRunnerIds)\n : undefined,\n notExists(\n tx\n .select({id: newerRunningJobExecutions.id})\n .from(newerRunningJobExecutions)\n .where(\n and(\n eq(newerRunningJobExecutions.workspaceId, runningJobExecutions.workspaceId),\n eq(newerRunningJobExecutions.provisionerId, runningJobExecutions.provisionerId),\n eq(\n newerRunningJobExecutions.providerRunnerId,\n runningJobExecutions.providerRunnerId,\n ),\n or(\n gt(newerRunningJobExecutions.startedAt, runningJobExecutions.startedAt),\n and(\n eq(newerRunningJobExecutions.startedAt, runningJobExecutions.startedAt),\n gt(\n newerRunningJobExecutions.jobExecutionId,\n runningJobExecutions.jobExecutionId,\n ),\n ),\n ),\n ),\n ),\n ),\n ),\n )\n .groupBy(providerRunners.providerRunnerId);\n}\n\nasync function listTerminateIntentsHonoredByTerminatedReportsTx(\n tx: Tx,\n params: ReportRunnerInstancesParams,\n events: RunnerInstanceReportEvent[],\n): Promise<RunnerInstanceTerminateIntent[]> {\n if (!params.workspaceId) return [];\n const terminatedRunnerInstanceIds = [\n ...new Set(\n events.filter((event) => event.state === 'terminated').map((event) => event.providerRunnerId),\n ),\n ];\n if (terminatedRunnerInstanceIds.length === 0) return [];\n\n const rows = await provisionerTerminateIntentsQuery(tx, {\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n providerRunnerIds: terminatedRunnerInstanceIds,\n }).orderBy(asc(providerRunners.providerRunnerId));\n return rows.flatMap((row) =>\n row.providerRunnerId ? [{...row, providerRunnerId: row.providerRunnerId}] : [],\n );\n}\n\nexport async function reconcileRunnerInstances(\n params: ReconcileRunnerInstancesParams,\n): Promise<ReconcileRunnerInstancesDbResult> {\n const observedRunnerInstanceIds = [...new Set(params.observedRunnerInstanceIds)];\n\n return await db().transaction(async (tx) => {\n await tx.execute(\n sql`select pg_advisory_xact_lock(hashtext(${params.workspaceId ?? params.provisionerId}))`,\n );\n\n let absentIds: string[] = [];\n let reservationsReleased = 0;\n if (observedRunnerInstanceIds.length > 0) {\n const staleAbsentRows = await tx\n .select({\n id: providerRunners.id,\n providerRunnerId: providerRunners.providerRunnerId,\n })\n .from(providerRunners)\n .where(\n and(\n params.workspaceId\n ? eq(providerRunners.workspaceId, params.workspaceId)\n : isNull(providerRunners.workspaceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n inArray(providerRunners.state, activeStates),\n lt(\n providerRunners.reportedAt,\n sql`now() - (${params.terminateGraceSeconds} || ' seconds')::interval`,\n ),\n notInArray(providerRunners.providerRunnerId, observedRunnerInstanceIds),\n ),\n );\n\n if (staleAbsentRows.length > 0) {\n const updated = await tx\n .update(providerRunners)\n .set({\n state: 'terminated',\n terminatedAt: sql`coalesce(${providerRunners.terminatedAt}, now())`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n inArray(\n providerRunners.id,\n staleAbsentRows.map((row) => row.id),\n ),\n inArray(providerRunners.state, activeStates),\n lt(\n providerRunners.reportedAt,\n sql`now() - (${params.terminateGraceSeconds} || ' seconds')::interval`,\n ),\n ),\n )\n .returning({providerRunnerId: providerRunners.providerRunnerId});\n\n absentIds = updated.flatMap((row) => (row.providerRunnerId ? [row.providerRunnerId] : []));\n if (params.workspaceId) {\n reservationsReleased = await releaseTerminalRunnerInstanceReservationsByIds(tx, {\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n providerRunnerIds: absentIds,\n });\n }\n }\n }\n\n const observedRows =\n observedRunnerInstanceIds.length === 0\n ? []\n : (\n await tx\n .select()\n .from(providerRunners)\n .where(\n and(\n params.workspaceId\n ? eq(providerRunners.workspaceId, params.workspaceId)\n : isNull(providerRunners.workspaceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n inArray(providerRunners.providerRunnerId, observedRunnerInstanceIds),\n ),\n )\n ).map(toRunnerInstance);\n\n const boundJobExecutions = params.workspaceId\n ? await listRunningJobExecutionsByRunnerInstanceTx(tx, {\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n providerRunnerIds: observedRunnerInstanceIds,\n })\n : [];\n\n return {\n observedRows,\n boundJobExecutionsByRunnerInstanceId: new Map(\n boundJobExecutions.map((jobExecution) => [jobExecution.providerRunnerId, jobExecution]),\n ),\n absentIds,\n reservationsReleased,\n };\n });\n}\n\nexport async function reapStaleRunnerInstances(params: {\n thresholdSeconds: number;\n limit: number;\n}): Promise<ReapStaleRunnerInstancesResult> {\n const cutoff = staleRunnerInstanceCutoff(params.thresholdSeconds);\n\n return await db().transaction(async (tx) => {\n const candidateRows = await tx\n .select({\n id: providerRunners.id,\n workspaceId: providerRunners.workspaceId,\n provisionerId: providerRunners.provisionerId,\n providerRunnerId: providerRunners.providerRunnerId,\n })\n .from(providerRunners)\n .where(staleRunnerInstanceWhere(tx, cutoff))\n .orderBy(asc(providerRunners.updatedAt), asc(providerRunners.id))\n .limit(params.limit);\n\n if (candidateRows.length === 0) return {reaped: 0, reservationsReleased: 0};\n\n const workspaceIds = [\n ...new Set(candidateRows.flatMap((row) => (row.workspaceId ? [row.workspaceId] : []))),\n ].sort();\n for (const workspaceId of workspaceIds) {\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${workspaceId}))`);\n }\n\n const updatedRows = await tx\n .update(providerRunners)\n .set({\n state: 'failed',\n reason: 'stale-provisioner',\n failedAt: sql`coalesce(${providerRunners.failedAt}, now())`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n inArray(\n providerRunners.id,\n candidateRows.map((row) => row.id),\n ),\n staleRunnerInstanceWhere(tx, cutoff),\n ),\n )\n .returning({\n workspaceId: providerRunners.workspaceId,\n provisionerId: providerRunners.provisionerId,\n providerRunnerId: providerRunners.providerRunnerId,\n });\n\n let reservationsReleased = 0;\n for (const group of groupRunnerInstanceIds(updatedRows)) {\n reservationsReleased += await releaseTerminalRunnerInstanceReservationsByIds(tx, {\n workspaceId: group.workspaceId,\n provisionerId: group.provisionerId,\n providerRunnerIds: group.providerRunnerIds,\n requireUnlinkedSession: false,\n });\n }\n\n return {reaped: updatedRows.length, reservationsReleased};\n });\n}\n\nasync function releaseTerminalRunnerInstanceReservations(\n tx: Tx,\n params: ReportRunnerInstancesParams,\n events: RunnerInstanceReportEvent[],\n): Promise<number> {\n const terminalEvents = events.filter((event) => isTerminalState(event.state));\n if (terminalEvents.length === 0) return 0;\n\n return await releaseTerminalRunnerInstanceReservationsByIds(tx, {\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n providerRunnerIds: terminalEvents.map((event) => event.providerRunnerId),\n });\n}\n\nasync function releaseTerminalRunnerInstanceReservationsByIds(\n tx: Tx,\n params: {\n workspaceId: string | null;\n provisionerId: string;\n providerRunnerIds: string[];\n requireUnlinkedSession?: boolean;\n },\n): Promise<number> {\n if (params.providerRunnerIds.length === 0) return 0;\n\n const reservationWorkspacePredicate =\n params.workspaceId === null\n ? sql``\n : sql`and ${eq(reservations.workspaceId, params.workspaceId)}`;\n\n const rows = await tx\n .select({\n id: providerRunners.id,\n releaseReservationId: sql<string | null>`coalesce(\n (select ${reservations.id}\n from ${reservations}\n where ${reservations.id} = ${providerRunners.intendedReservationId}\n and ${reservations.provisionerId} = ${params.provisionerId}\n ${reservationWorkspacePredicate}),\n (select ${reservations.id}\n from ${reservations}\n where ${reservations.id} = ${providerRunners.reservationId}\n and ${reservations.provisionerId} = ${params.provisionerId}\n ${reservationWorkspacePredicate})\n )`,\n releaseReservationWorkspaceId: sql<string | null>`coalesce(\n (select ${reservations.workspaceId}\n from ${reservations}\n where ${reservations.id} = ${providerRunners.intendedReservationId}\n and ${reservations.provisionerId} = ${params.provisionerId}\n ${reservationWorkspacePredicate}),\n (select ${reservations.workspaceId}\n from ${reservations}\n where ${reservations.id} = ${providerRunners.reservationId}\n and ${reservations.provisionerId} = ${params.provisionerId}\n ${reservationWorkspacePredicate})\n )`,\n })\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.provisionerId, params.provisionerId),\n inArray(providerRunners.providerRunnerId, params.providerRunnerIds),\n inArray(providerRunners.state, terminalStates),\n or(\n isNotNull(providerRunners.reservationId),\n isNotNull(providerRunners.intendedReservationId),\n ),\n params.workspaceId === null\n ? undefined\n : or(\n and(\n eq(providerRunners.workspaceId, params.workspaceId),\n or(\n exists(\n tx\n .select({id: reservations.id})\n .from(reservations)\n .where(\n and(\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n eq(reservations.id, providerRunners.reservationId),\n ),\n ),\n ),\n exists(\n tx\n .select({id: reservations.id})\n .from(reservations)\n .where(\n and(\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n eq(reservations.id, providerRunners.intendedReservationId),\n ),\n ),\n ),\n ),\n ),\n and(\n isNull(providerRunners.workspaceId),\n isNotNull(providerRunners.intendedReservationId),\n exists(\n tx\n .select({id: reservations.id})\n .from(reservations)\n .where(\n and(\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n eq(reservations.id, providerRunners.intendedReservationId),\n ),\n ),\n ),\n ),\n ),\n params.requireUnlinkedSession === false\n ? undefined\n : isNull(providerRunners.runnerSessionId),\n isNull(providerRunners.reservationReleasedAt),\n ),\n )\n .for('update');\n\n if (rows.length === 0) return 0;\n\n const updated = await tx\n .update(providerRunners)\n .set({\n intendedReservationId: null,\n reservationReleasedAt: sql`now()`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n inArray(\n providerRunners.id,\n rows.map((row) => row.id),\n ),\n params.requireUnlinkedSession === false\n ? undefined\n : isNull(providerRunners.runnerSessionId),\n isNull(providerRunners.reservationReleasedAt),\n ),\n )\n .returning({id: providerRunners.id});\n\n const releasesByReservationId = new Map<\n string,\n {workspaceId: string; reservationId: string; count: number}\n >();\n const updatedIds = new Set(updated.map((row) => row.id));\n for (const row of rows) {\n if (!updatedIds.has(row.id)) continue;\n if (!row.releaseReservationId || !row.releaseReservationWorkspaceId) continue;\n const key = `${row.releaseReservationWorkspaceId}:${row.releaseReservationId}`;\n const release = releasesByReservationId.get(key) ?? {\n workspaceId: row.releaseReservationWorkspaceId,\n reservationId: row.releaseReservationId,\n count: 0,\n };\n release.count += 1;\n releasesByReservationId.set(key, release);\n }\n\n if (releasesByReservationId.size === 0) return 0;\n\n let released = 0;\n for (const release of releasesByReservationId.values()) {\n released += await releaseReservationUnits(tx, {\n workspaceId: release.workspaceId,\n provisionerId: params.provisionerId,\n releases: [{reservationId: release.reservationId, count: release.count}],\n });\n }\n return released;\n}\n\nfunction staleRunnerInstanceCutoff(thresholdSeconds: number): SQL {\n return sql`now() - (${thresholdSeconds} || ' seconds')::interval`;\n}\n\nfunction staleRunnerInstanceWhere(tx: Tx, cutoff: SQL): SQL<boolean> {\n return and(\n inArray(providerRunners.state, activeStates),\n lt(providerRunners.reportedAt, cutoff),\n lt(providerRunners.updatedAt, cutoff),\n exists(\n tx\n .select({id: provisionerTokens.id})\n .from(provisionerTokens)\n .where(\n and(\n eq(provisionerTokens.id, providerRunners.provisionerId),\n or(isNull(provisionerTokens.lastSeenAt), lt(provisionerTokens.lastSeenAt, cutoff)),\n ),\n ),\n ),\n notExists(\n tx\n .select({id: runningJobExecutions.id})\n .from(runningJobExecutions)\n .where(\n and(\n eq(runningJobExecutions.workspaceId, providerRunners.workspaceId),\n eq(runningJobExecutions.provisionerId, providerRunners.provisionerId),\n eq(runningJobExecutions.providerRunnerId, providerRunners.providerRunnerId),\n ),\n ),\n ),\n notExists(\n tx\n .select({id: runnerSessions.id})\n .from(runnerSessions)\n .where(\n and(\n eq(runnerSessions.workspaceId, providerRunners.workspaceId),\n eq(runnerSessions.provisionerId, providerRunners.provisionerId),\n eq(runnerSessions.providerRunnerId, providerRunners.providerRunnerId),\n sql`${runnerSessions.updatedAt} >= ${cutoff}`,\n ),\n ),\n ),\n ) as SQL<boolean>;\n}\n\nfunction groupRunnerInstanceIds(\n rows: Array<{\n workspaceId: string | null;\n provisionerId: string;\n providerRunnerId: string | null;\n }>,\n): Array<{workspaceId: string | null; provisionerId: string; providerRunnerIds: string[]}> {\n const groups = new Map<\n string,\n {workspaceId: string | null; provisionerId: string; providerRunnerIds: string[]}\n >();\n for (const row of rows) {\n if (!row.providerRunnerId) continue;\n const key = `${row.workspaceId ?? ''}:${row.provisionerId}`;\n const group = groups.get(key) ?? {\n workspaceId: row.workspaceId,\n provisionerId: row.provisionerId,\n providerRunnerIds: [],\n };\n group.providerRunnerIds.push(row.providerRunnerId);\n groups.set(key, group);\n }\n return [...groups.values()];\n}\n\nasync function hydrateRunnerSessionIdsFromConsumedTokens(\n tx: Tx,\n params: ReportRunnerInstancesParams,\n events: RunnerInstanceReportRow[],\n): Promise<RunnerInstanceReportRow[]> {\n if (!params.workspaceId) return events;\n const providerRunnerIds = [...new Set(events.map((event) => event.providerRunnerId))];\n if (providerRunnerIds.length === 0) return events;\n\n const tokenRows = await tx\n .select({\n providerRunnerId: ephemeralRegistrationTokens.providerRunnerId,\n consumedSessionId: ephemeralRegistrationTokens.consumedSessionId,\n })\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 isNotNull(ephemeralRegistrationTokens.consumedSessionId),\n ),\n )\n .orderBy(\n desc(ephemeralRegistrationTokens.consumedAt),\n desc(ephemeralRegistrationTokens.createdAt),\n );\n\n const consumedSessionIdsByRunnerInstanceId = new Map<string, string>();\n for (const row of tokenRows) {\n if (!row.consumedSessionId) continue;\n if (consumedSessionIdsByRunnerInstanceId.has(row.providerRunnerId)) continue;\n consumedSessionIdsByRunnerInstanceId.set(row.providerRunnerId, row.consumedSessionId);\n }\n\n if (consumedSessionIdsByRunnerInstanceId.size === 0) return events;\n\n return events.map((event) => {\n const consumedSessionId = consumedSessionIdsByRunnerInstanceId.get(event.providerRunnerId);\n if (!consumedSessionId || event.runnerSessionId === consumedSessionId) return event;\n return {...event, runnerSessionId: consumedSessionId};\n });\n}\n\nfunction aggregateEvents(\n events: RunnerInstanceReportEvent[],\n receivedAt: Date,\n): RunnerInstanceReportRow[] {\n const byRunnerInstanceId = new Map<string, RunnerInstanceReportRow>();\n for (const rawEvent of events) {\n const event = toRunnerInstanceReportRow(rawEvent, receivedAt);\n const existing = byRunnerInstanceId.get(event.providerRunnerId);\n if (existing) mergeMilestones(existing, event);\n if (!existing || compareRunnerInstanceReportEvents(event, existing) > 0) {\n byRunnerInstanceId.set(\n event.providerRunnerId,\n existing ? mergeProjectionMetadata(event, existing) : event,\n );\n }\n }\n return [...byRunnerInstanceId.values()];\n}\n\nfunction toRunnerInstanceReportRow(\n event: RunnerInstanceReportEvent,\n receivedAt: Date,\n): RunnerInstanceReportRow {\n const reportedAt = event.reportedAt > receivedAt ? receivedAt : event.reportedAt;\n return {\n ...event,\n reportedAt,\n startedAt: event.state === 'running' ? reportedAt : null,\n stoppingAt: event.state === 'stopping' ? reportedAt : null,\n stoppedAt: event.state === 'stopped' ? reportedAt : null,\n failedAt: event.state === 'failed' ? reportedAt : null,\n terminatedAt: event.state === 'terminated' ? reportedAt : null,\n };\n}\n\nfunction mergeMilestones(target: RunnerInstanceReportRow, source: RunnerInstanceReportRow) {\n target.startedAt = earliestDate(target.startedAt, source.startedAt);\n target.stoppingAt = earliestDate(target.stoppingAt, source.stoppingAt);\n target.stoppedAt = earliestDate(target.stoppedAt, source.stoppedAt);\n target.failedAt = earliestDate(target.failedAt, source.failedAt);\n target.terminatedAt = earliestDate(target.terminatedAt, source.terminatedAt);\n}\n\nfunction mergeProjectionMetadata(\n event: RunnerInstanceReportRow,\n existing: RunnerInstanceReportRow,\n): RunnerInstanceReportRow {\n return {\n ...event,\n reservationId: event.reservationId ?? existing.reservationId,\n templateKey: event.templateKey ?? existing.templateKey,\n runnerSessionId: event.runnerSessionId ?? existing.runnerSessionId,\n providerKind: event.providerKind ?? existing.providerKind,\n ...pickMilestones(existing),\n };\n}\n\nfunction pickMilestones(event: RunnerInstanceReportRow) {\n return {\n startedAt: event.startedAt,\n stoppingAt: event.stoppingAt,\n stoppedAt: event.stoppedAt,\n failedAt: event.failedAt,\n terminatedAt: event.terminatedAt,\n };\n}\n\nfunction earliestDate(a: Date | null, b: Date | null): Date | null {\n if (!a) return b;\n if (!b) return a;\n return a < b ? a : b;\n}\n\nfunction compareRunnerInstanceReportEvents(\n a: RunnerInstanceReportEvent,\n b: RunnerInstanceReportEvent,\n): number {\n const timeDelta = a.reportedAt.getTime() - b.reportedAt.getTime();\n const rankDelta = getRunnerInstanceStateRank(a.state) - getRunnerInstanceStateRank(b.state);\n if (rankDelta !== 0) return rankDelta;\n return timeDelta;\n}\n\nfunction getRunnerInstanceStateRank(state: RunnerInstanceState): number {\n switch (state) {\n case 'starting':\n return 1;\n case 'running':\n return 2;\n case 'stopping':\n return 3;\n case 'stopped':\n return 4;\n case 'failed':\n return 5;\n case 'terminated':\n return 6;\n }\n}\n\nfunction providerRunnerStateRank(state: SQL | typeof providerRunners.state): SQL<number> {\n return sql<number>`\n CASE ${state}\n WHEN 'starting' THEN 1\n WHEN 'running' THEN 2\n WHEN 'stopping' THEN 3\n WHEN 'stopped' THEN 4\n WHEN 'failed' THEN 5\n WHEN 'terminated' THEN 6\n ELSE 0\n END\n `;\n}\n\nfunction providerRunnerProjectionUpdateCondition(): SQL<boolean> {\n return sql<boolean>`\n ${providerRunnerStateRank(sql`excluded.state`)} > ${providerRunnerStateRank(providerRunners.state)}\n OR (\n ${providerRunnerStateRank(sql`excluded.state`)} = ${providerRunnerStateRank(providerRunners.state)}\n AND excluded.reported_at >= ${providerRunners.reportedAt}\n )\n `;\n}\n\nfunction providerRunnerMilestoneUpdateCondition(): SQL<boolean> {\n return sql<boolean>`\n ${milestoneNeedsUpdate(providerRunners.startedAt, sql`excluded.started_at`)}\n OR ${milestoneNeedsUpdate(providerRunners.stoppingAt, sql`excluded.stopping_at`)}\n OR ${milestoneNeedsUpdate(providerRunners.stoppedAt, sql`excluded.stopped_at`)}\n OR ${milestoneNeedsUpdate(providerRunners.failedAt, sql`excluded.failed_at`)}\n OR ${milestoneNeedsUpdate(providerRunners.terminatedAt, sql`excluded.terminated_at`)}\n `;\n}\n\nfunction milestoneNeedsUpdate(\n current: SQL | RunnerInstanceMilestoneColumn,\n incoming: SQL,\n): SQL<boolean> {\n return sql<boolean>`${incoming} IS NOT NULL AND (${current} IS NULL OR ${incoming} < ${current})`;\n}\n\nfunction firstObservedAt(current: SQL | RunnerInstanceMilestoneColumn, incoming: SQL) {\n return sql`\n CASE\n WHEN ${incoming} IS NULL THEN ${current}\n WHEN ${current} IS NULL THEN ${incoming}\n ELSE least(${current}, ${incoming})\n END\n `;\n}\n\nexport function isTerminalState(state: RunnerInstanceState): boolean {\n return terminalStates.includes(state as (typeof terminalStates)[number]);\n}\n\nfunction isDivergenceCountState(\n state: RunnerInstanceState,\n): state is (typeof divergenceCountStates)[number] {\n return divergenceCountStates.includes(state as (typeof divergenceCountStates)[number]);\n}\n"],"names":["logger","and","asc","desc","eq","exists","gt","inArray","isNotNull","isNull","lt","notExists","notInArray","or","sql","alias","sanitizeRunnerLabels","db","listRunningJobExecutionsByRunnerInstanceTx","releaseReservationUnits","ephemeralRegistrationTokens","provisionerTokens","reservations","providerRunners","toRunnerInstance","runnerSessions","runningJobExecutions","terminalStates","activeStates","divergenceCountStates","attachRunnerInstanceProviderId","params","updated","update","set","providerRunnerId","updatedAt","where","id","runnerInstanceId","provisionerId","state","returning","length","reportRunnerInstances","events","accepted","reservationsReleased","terminateIntentsHonored","transaction","tx","receivedAt","Date","aggregatedEvents","aggregateEvents","hasTerminalEvent","some","event","isTerminalState","execute","workspaceId","hydrateRunnerSessionIdsFromConsumedTokens","listTerminateIntentsHonoredByTerminatedReportsTx","values","map","reservationId","templateKey","labels","scope","logLevel","source","reason","runnerSessionId","providerKind","reportedAt","startedAt","stoppingAt","stoppedAt","failedAt","terminatedAt","insert","onConflictDoUpdate","target","targetWhere","providerRunnerProjectionUpdateCondition","firstObservedAt","setWhere","providerRunnerMilestoneUpdateCondition","releaseTerminalRunnerInstanceReservations","listActiveRunnerInstanceCountsByTemplateTx","rows","select","count","from","groupBy","flatMap","row","isDivergenceCountState","listActiveRunnerInstances","windowSeconds","orderBy","limit","listProvisionerTerminateIntents","listProvisionerTerminateIntentRowsTx","provisionerTerminateIntentsQuery","truncated","returnedRows","slice","warn","returnedCount","newerRunningJobExecutions","innerJoin","cancellationRequestedAt","providerRunnerIds","undefined","jobExecutionId","terminatedRunnerInstanceIds","Set","filter","reconcileRunnerInstances","observedRunnerInstanceIds","absentIds","staleAbsentRows","terminateGraceSeconds","releaseTerminalRunnerInstanceReservationsByIds","observedRows","boundJobExecutions","boundJobExecutionsByRunnerInstanceId","Map","jobExecution","reapStaleRunnerInstances","cutoff","staleRunnerInstanceCutoff","thresholdSeconds","candidateRows","staleRunnerInstanceWhere","reaped","workspaceIds","sort","updatedRows","group","groupRunnerInstanceIds","requireUnlinkedSession","terminalEvents","reservationWorkspacePredicate","releaseReservationId","intendedReservationId","releaseReservationWorkspaceId","reservationReleasedAt","for","releasesByReservationId","updatedIds","has","key","release","get","size","released","releases","lastSeenAt","groups","push","tokenRows","consumedSessionId","consumedAt","createdAt","consumedSessionIdsByRunnerInstanceId","byRunnerInstanceId","rawEvent","toRunnerInstanceReportRow","existing","mergeMilestones","compareRunnerInstanceReportEvents","mergeProjectionMetadata","earliestDate","pickMilestones","a","b","timeDelta","getTime","rankDelta","getRunnerInstanceStateRank","providerRunnerStateRank","milestoneNeedsUpdate","current","incoming","includes"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/db/runner-instances.ts"],"sourcesContent":["import {logger} from '@shipfox/node-opentelemetry';\nimport {\n and,\n asc,\n desc,\n eq,\n exists,\n gt,\n inArray,\n isNotNull,\n isNull,\n lt,\n notExists,\n notInArray,\n or,\n type SQL,\n sql,\n} from 'drizzle-orm';\nimport {alias} from 'drizzle-orm/pg-core';\nimport type {RunnerInstance, RunnerInstanceState} from '#core/entities/runner-instance.js';\nimport {sanitizeRunnerLabels} from '#core/runner-labels.js';\nimport type {Tx} from './db.js';\nimport {db} from './db.js';\nimport {\n listRunningJobExecutionsByRunnerInstanceTx,\n type RunnerInstanceBoundJobExecution,\n} from './job-executions.js';\nimport {releaseReservationUnits} from './reservations.js';\nimport {ephemeralRegistrationTokens} from './schema/ephemeral-registration-tokens.js';\nimport {provisionerTokens} from './schema/provisioner-tokens.js';\nimport {reservations} from './schema/reservations.js';\nimport {runnerControlSessions} from './schema/runner-control-sessions.js';\nimport {providerRunners, toRunnerInstance} from './schema/runner-instances.js';\nimport {runnerSessions} from './schema/runner-sessions.js';\nimport {runningJobExecutions} from './schema/running-job-executions.js';\n\nexport const terminalStates = [\n 'stopped',\n 'failed',\n 'terminated',\n] as const satisfies readonly RunnerInstanceState[];\nexport const activeStates = [\n 'starting',\n 'running',\n 'stopping',\n] as const satisfies readonly RunnerInstanceState[];\nexport const divergenceCountStates = ['starting', 'running'] as const satisfies readonly Extract<\n RunnerInstanceState,\n 'starting' | 'running'\n>[];\n\nexport type RunnerInstanceTerminateIntentReason = 'job-cancelled';\n\nexport interface RunnerInstanceTerminateIntent {\n providerRunnerId: string;\n reason: RunnerInstanceTerminateIntentReason;\n}\n\nexport interface ActiveRunnerInstanceTemplateCount {\n templateKey: string;\n state: (typeof divergenceCountStates)[number];\n count: number;\n}\n\nexport interface RunnerInstanceReportEvent {\n providerRunnerId: string;\n reservationId: string | null;\n templateKey: string | null;\n labels: string[];\n state: RunnerInstanceState;\n reason: string | null;\n runnerSessionId: string | null;\n providerKind: string | null;\n reportedAt: Date;\n}\n\nexport interface ReportRunnerInstancesParams {\n scope: 'installation' | 'workspace';\n workspaceId: string | null;\n provisionerId: string;\n events: RunnerInstanceReportEvent[];\n}\n\nexport interface ReconcileRunnerInstancesParams {\n workspaceId: string | null;\n provisionerId: string;\n observedRunnerInstanceIds: string[];\n terminateGraceSeconds: number;\n}\n\nexport interface ReconcileRunnerInstancesDbResult {\n observedRows: RunnerInstance[];\n boundJobExecutionsByRunnerInstanceId: Map<string, RunnerInstanceBoundJobExecution>;\n absentIds: string[];\n reservationsReleased: number;\n}\n\nexport interface ReapStaleRunnerInstancesResult {\n reaped: number;\n reservationsReleased: number;\n}\n\nexport async function attachRunnerInstanceProviderId(params: {\n runnerInstanceId: string;\n provisionerId: string;\n providerRunnerId: string;\n}): Promise<boolean> {\n const updated = await db()\n .update(providerRunners)\n .set({providerRunnerId: params.providerRunnerId, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n isNull(providerRunners.providerRunnerId),\n notInArray(providerRunners.state, [...terminalStates]),\n ),\n )\n .returning({id: providerRunners.id});\n return updated.length === 1;\n}\n\ninterface RunnerInstanceReportRow extends RunnerInstanceReportEvent {\n startedAt: Date | null;\n stoppingAt: Date | null;\n stoppedAt: Date | null;\n failedAt: Date | null;\n terminatedAt: Date | null;\n}\n\ntype RunnerInstanceMilestoneColumn =\n | typeof providerRunners.startedAt\n | typeof providerRunners.stoppingAt\n | typeof providerRunners.stoppedAt\n | typeof providerRunners.failedAt\n | typeof providerRunners.terminatedAt;\n\nexport async function reportRunnerInstances(params: ReportRunnerInstancesParams): Promise<{\n accepted: number;\n reservationsReleased: number;\n terminateIntentsHonored: RunnerInstanceTerminateIntent[];\n}> {\n if (params.events.length === 0)\n return {accepted: 0, reservationsReleased: 0, terminateIntentsHonored: []};\n\n return await db().transaction(async (tx) => {\n const receivedAt = new Date();\n const aggregatedEvents = aggregateEvents(params.events, receivedAt);\n const hasTerminalEvent = aggregatedEvents.some((event) => isTerminalState(event.state));\n\n if (hasTerminalEvent) {\n await tx.execute(\n sql`select pg_advisory_xact_lock(hashtext(${params.workspaceId ?? params.provisionerId}))`,\n );\n }\n\n const events = await hydrateRunnerSessionIdsFromConsumedTokens(tx, params, aggregatedEvents);\n const terminateIntentsHonored = await listTerminateIntentsHonoredByTerminatedReportsTx(\n tx,\n params,\n events,\n );\n\n const values = events.map((event) => ({\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n providerRunnerId: event.providerRunnerId,\n reservationId: event.reservationId,\n templateKey: event.templateKey,\n labels: sanitizeRunnerLabels(event.labels, {\n scope: params.scope,\n logLevel: 'debug',\n source: 'runner instance report',\n }),\n state: event.state,\n reason: event.reason,\n runnerSessionId: event.runnerSessionId,\n providerKind: event.providerKind,\n reportedAt: event.reportedAt > receivedAt ? receivedAt : event.reportedAt,\n startedAt: event.startedAt,\n stoppingAt: event.stoppingAt,\n stoppedAt: event.stoppedAt,\n failedAt: event.failedAt,\n terminatedAt: event.terminatedAt,\n }));\n\n await tx\n .insert(providerRunners)\n .values(values)\n .onConflictDoUpdate({\n target: [providerRunners.provisionerId, providerRunners.providerRunnerId],\n targetWhere: isNotNull(providerRunners.providerRunnerId),\n set: {\n reservationId: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(${providerRunners.reservationId}, excluded.reservation_id) ELSE ${providerRunners.reservationId} END`,\n templateKey: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(excluded.template_key, ${providerRunners.templateKey}) ELSE ${providerRunners.templateKey} END`,\n labels: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN excluded.labels ELSE ${providerRunners.labels} END`,\n state: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN excluded.state ELSE ${providerRunners.state} END`,\n reason: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN excluded.reason ELSE ${providerRunners.reason} END`,\n runnerSessionId: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(${providerRunners.runnerSessionId}, excluded.runner_session_id) ELSE ${providerRunners.runnerSessionId} END`,\n providerKind: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN coalesce(excluded.provider_kind, ${providerRunners.providerKind}) ELSE ${providerRunners.providerKind} END`,\n reportedAt: sql`CASE WHEN ${providerRunnerProjectionUpdateCondition()} THEN excluded.reported_at ELSE ${providerRunners.reportedAt} END`,\n startedAt: firstObservedAt(providerRunners.startedAt, sql`excluded.started_at`),\n stoppingAt: firstObservedAt(providerRunners.stoppingAt, sql`excluded.stopping_at`),\n stoppedAt: firstObservedAt(providerRunners.stoppedAt, sql`excluded.stopped_at`),\n failedAt: firstObservedAt(providerRunners.failedAt, sql`excluded.failed_at`),\n terminatedAt: firstObservedAt(providerRunners.terminatedAt, sql`excluded.terminated_at`),\n updatedAt: sql`now()`,\n },\n setWhere: sql`\n ${providerRunnerProjectionUpdateCondition()}\n OR ${providerRunnerMilestoneUpdateCondition()}\n `,\n });\n\n const reservationsReleased = hasTerminalEvent\n ? await releaseTerminalRunnerInstanceReservations(tx, params, events)\n : 0;\n\n return {accepted: events.length, reservationsReleased, terminateIntentsHonored};\n });\n}\n\nexport async function listActiveRunnerInstanceCountsByTemplateTx(\n tx: Tx,\n params: {workspaceId: string; provisionerId: string},\n): Promise<ActiveRunnerInstanceTemplateCount[]> {\n const rows = await tx\n .select({\n templateKey: providerRunners.templateKey,\n state: providerRunners.state,\n count: sql<number>`count(*)::int`,\n })\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.workspaceId, params.workspaceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n inArray(providerRunners.state, divergenceCountStates),\n isNotNull(providerRunners.templateKey),\n ),\n )\n .groupBy(providerRunners.templateKey, providerRunners.state);\n\n return rows.flatMap((row) =>\n row.templateKey && isDivergenceCountState(row.state)\n ? [{templateKey: row.templateKey, state: row.state, count: row.count}]\n : [],\n );\n}\n\nexport async function countStaleEnrolledRunnerInstances(params: {\n graceSeconds: number;\n}): Promise<number> {\n const [row] = await db()\n .select({count: sql<number>`count(*)::int`})\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.state, 'running'),\n isNull(providerRunners.workspaceId),\n isNull(providerRunners.runnerSessionId),\n lt(providerRunners.reportedAt, staleRunnerInstanceCutoff(params.graceSeconds)),\n exists(\n db()\n .select({id: runnerControlSessions.id})\n .from(runnerControlSessions)\n .where(\n and(\n eq(runnerControlSessions.runnerInstanceId, providerRunners.id),\n isNull(runnerControlSessions.closedAt),\n gt(runnerControlSessions.expiresAt, sql`now()`),\n ),\n ),\n ),\n ),\n );\n\n return row?.count ?? 0;\n}\n\nexport async function listActiveRunnerInstances(params: {\n workspaceId: string;\n windowSeconds: number;\n limit?: number;\n}): Promise<RunnerInstance[]> {\n const rows = await db()\n .select()\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.workspaceId, params.workspaceId),\n inArray(providerRunners.state, activeStates),\n sql`${providerRunners.updatedAt} > now() - (${params.windowSeconds} || ' seconds')::interval`,\n ),\n )\n .orderBy(desc(providerRunners.updatedAt), desc(providerRunners.id))\n .limit(params.limit ?? 1000);\n\n return rows.map(toRunnerInstance);\n}\n\nexport async function listProvisionerTerminateIntents(params: {\n workspaceId: string;\n provisionerId: string;\n limit: number;\n}): Promise<string[]> {\n return await db().transaction(async (tx) => {\n const rows = await listProvisionerTerminateIntentRowsTx(tx, params);\n return rows.map((row) => row.providerRunnerId);\n });\n}\n\nexport async function listProvisionerTerminateIntentRowsTx(\n tx: Tx,\n params: {\n workspaceId: string;\n provisionerId: string;\n limit: number;\n },\n): Promise<RunnerInstanceTerminateIntent[]> {\n const rows = await provisionerTerminateIntentsQuery(tx, params)\n .orderBy(asc(providerRunners.providerRunnerId))\n .limit(params.limit + 1);\n\n const truncated = rows.length > params.limit;\n const returnedRows = truncated ? rows.slice(0, params.limit) : rows;\n if (truncated) {\n logger().warn(\n {\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n limit: params.limit,\n returnedCount: returnedRows.length,\n },\n 'provisioner terminate intents truncated by poll-demand limit',\n );\n }\n\n return returnedRows.flatMap((row) =>\n row.providerRunnerId ? [{...row, providerRunnerId: row.providerRunnerId}] : [],\n );\n}\n\nfunction provisionerTerminateIntentsQuery(\n tx: Tx,\n params: {workspaceId: string; provisionerId: string; providerRunnerIds?: string[]},\n) {\n const newerRunningJobExecutions = alias(runningJobExecutions, 'newer_running_jobs');\n\n return tx\n .select({\n providerRunnerId: providerRunners.providerRunnerId,\n reason: sql<RunnerInstanceTerminateIntentReason>`'job-cancelled'`,\n })\n .from(runningJobExecutions)\n .innerJoin(\n providerRunners,\n and(\n eq(providerRunners.workspaceId, runningJobExecutions.workspaceId),\n eq(providerRunners.provisionerId, runningJobExecutions.provisionerId),\n eq(providerRunners.providerRunnerId, runningJobExecutions.providerRunnerId),\n ),\n )\n .where(\n and(\n eq(runningJobExecutions.workspaceId, params.workspaceId),\n eq(runningJobExecutions.provisionerId, params.provisionerId),\n isNotNull(providerRunners.providerRunnerId),\n isNotNull(runningJobExecutions.cancellationRequestedAt),\n inArray(providerRunners.state, activeStates),\n params.providerRunnerIds && params.providerRunnerIds.length > 0\n ? inArray(providerRunners.providerRunnerId, params.providerRunnerIds)\n : undefined,\n notExists(\n tx\n .select({id: newerRunningJobExecutions.id})\n .from(newerRunningJobExecutions)\n .where(\n and(\n eq(newerRunningJobExecutions.workspaceId, runningJobExecutions.workspaceId),\n eq(newerRunningJobExecutions.provisionerId, runningJobExecutions.provisionerId),\n eq(\n newerRunningJobExecutions.providerRunnerId,\n runningJobExecutions.providerRunnerId,\n ),\n or(\n gt(newerRunningJobExecutions.startedAt, runningJobExecutions.startedAt),\n and(\n eq(newerRunningJobExecutions.startedAt, runningJobExecutions.startedAt),\n gt(\n newerRunningJobExecutions.jobExecutionId,\n runningJobExecutions.jobExecutionId,\n ),\n ),\n ),\n ),\n ),\n ),\n ),\n )\n .groupBy(providerRunners.providerRunnerId);\n}\n\nasync function listTerminateIntentsHonoredByTerminatedReportsTx(\n tx: Tx,\n params: ReportRunnerInstancesParams,\n events: RunnerInstanceReportEvent[],\n): Promise<RunnerInstanceTerminateIntent[]> {\n if (!params.workspaceId) return [];\n const terminatedRunnerInstanceIds = [\n ...new Set(\n events.filter((event) => event.state === 'terminated').map((event) => event.providerRunnerId),\n ),\n ];\n if (terminatedRunnerInstanceIds.length === 0) return [];\n\n const rows = await provisionerTerminateIntentsQuery(tx, {\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n providerRunnerIds: terminatedRunnerInstanceIds,\n }).orderBy(asc(providerRunners.providerRunnerId));\n return rows.flatMap((row) =>\n row.providerRunnerId ? [{...row, providerRunnerId: row.providerRunnerId}] : [],\n );\n}\n\nexport async function reconcileRunnerInstances(\n params: ReconcileRunnerInstancesParams,\n): Promise<ReconcileRunnerInstancesDbResult> {\n const observedRunnerInstanceIds = [...new Set(params.observedRunnerInstanceIds)];\n\n return await db().transaction(async (tx) => {\n await tx.execute(\n sql`select pg_advisory_xact_lock(hashtext(${params.workspaceId ?? params.provisionerId}))`,\n );\n\n let absentIds: string[] = [];\n let reservationsReleased = 0;\n if (observedRunnerInstanceIds.length > 0) {\n const staleAbsentRows = await tx\n .select({\n id: providerRunners.id,\n providerRunnerId: providerRunners.providerRunnerId,\n })\n .from(providerRunners)\n .where(\n and(\n params.workspaceId\n ? eq(providerRunners.workspaceId, params.workspaceId)\n : isNull(providerRunners.workspaceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n inArray(providerRunners.state, activeStates),\n lt(\n providerRunners.reportedAt,\n sql`now() - (${params.terminateGraceSeconds} || ' seconds')::interval`,\n ),\n notInArray(providerRunners.providerRunnerId, observedRunnerInstanceIds),\n ),\n );\n\n if (staleAbsentRows.length > 0) {\n const updated = await tx\n .update(providerRunners)\n .set({\n state: 'terminated',\n terminatedAt: sql`coalesce(${providerRunners.terminatedAt}, now())`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n inArray(\n providerRunners.id,\n staleAbsentRows.map((row) => row.id),\n ),\n inArray(providerRunners.state, activeStates),\n lt(\n providerRunners.reportedAt,\n sql`now() - (${params.terminateGraceSeconds} || ' seconds')::interval`,\n ),\n ),\n )\n .returning({providerRunnerId: providerRunners.providerRunnerId});\n\n absentIds = updated.flatMap((row) => (row.providerRunnerId ? [row.providerRunnerId] : []));\n if (params.workspaceId) {\n reservationsReleased = await releaseTerminalRunnerInstanceReservationsByIds(tx, {\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n providerRunnerIds: absentIds,\n });\n }\n }\n }\n\n const observedRows =\n observedRunnerInstanceIds.length === 0\n ? []\n : (\n await tx\n .select()\n .from(providerRunners)\n .where(\n and(\n params.workspaceId\n ? eq(providerRunners.workspaceId, params.workspaceId)\n : isNull(providerRunners.workspaceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n inArray(providerRunners.providerRunnerId, observedRunnerInstanceIds),\n ),\n )\n ).map(toRunnerInstance);\n\n const boundJobExecutions = params.workspaceId\n ? await listRunningJobExecutionsByRunnerInstanceTx(tx, {\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n providerRunnerIds: observedRunnerInstanceIds,\n })\n : [];\n\n return {\n observedRows,\n boundJobExecutionsByRunnerInstanceId: new Map(\n boundJobExecutions.map((jobExecution) => [jobExecution.providerRunnerId, jobExecution]),\n ),\n absentIds,\n reservationsReleased,\n };\n });\n}\n\nexport async function reapStaleRunnerInstances(params: {\n thresholdSeconds: number;\n limit: number;\n}): Promise<ReapStaleRunnerInstancesResult> {\n const cutoff = staleRunnerInstanceCutoff(params.thresholdSeconds);\n\n return await db().transaction(async (tx) => {\n const candidateRows = await tx\n .select({\n id: providerRunners.id,\n workspaceId: providerRunners.workspaceId,\n provisionerId: providerRunners.provisionerId,\n providerRunnerId: providerRunners.providerRunnerId,\n })\n .from(providerRunners)\n .where(staleRunnerInstanceWhere(tx, cutoff))\n .orderBy(asc(providerRunners.updatedAt), asc(providerRunners.id))\n .limit(params.limit);\n\n if (candidateRows.length === 0) return {reaped: 0, reservationsReleased: 0};\n\n const workspaceIds = [\n ...new Set(candidateRows.flatMap((row) => (row.workspaceId ? [row.workspaceId] : []))),\n ].sort();\n for (const workspaceId of workspaceIds) {\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${workspaceId}))`);\n }\n\n const updatedRows = await tx\n .update(providerRunners)\n .set({\n state: 'failed',\n reason: 'stale-provisioner',\n failedAt: sql`coalesce(${providerRunners.failedAt}, now())`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n inArray(\n providerRunners.id,\n candidateRows.map((row) => row.id),\n ),\n staleRunnerInstanceWhere(tx, cutoff),\n ),\n )\n .returning({\n workspaceId: providerRunners.workspaceId,\n provisionerId: providerRunners.provisionerId,\n providerRunnerId: providerRunners.providerRunnerId,\n });\n\n let reservationsReleased = 0;\n for (const group of groupRunnerInstanceIds(updatedRows)) {\n reservationsReleased += await releaseTerminalRunnerInstanceReservationsByIds(tx, {\n workspaceId: group.workspaceId,\n provisionerId: group.provisionerId,\n providerRunnerIds: group.providerRunnerIds,\n requireUnlinkedSession: false,\n });\n }\n\n return {reaped: updatedRows.length, reservationsReleased};\n });\n}\n\nasync function releaseTerminalRunnerInstanceReservations(\n tx: Tx,\n params: ReportRunnerInstancesParams,\n events: RunnerInstanceReportEvent[],\n): Promise<number> {\n const terminalEvents = events.filter((event) => isTerminalState(event.state));\n if (terminalEvents.length === 0) return 0;\n\n return await releaseTerminalRunnerInstanceReservationsByIds(tx, {\n workspaceId: params.workspaceId,\n provisionerId: params.provisionerId,\n providerRunnerIds: terminalEvents.map((event) => event.providerRunnerId),\n });\n}\n\nasync function releaseTerminalRunnerInstanceReservationsByIds(\n tx: Tx,\n params: {\n workspaceId: string | null;\n provisionerId: string;\n providerRunnerIds: string[];\n requireUnlinkedSession?: boolean;\n },\n): Promise<number> {\n if (params.providerRunnerIds.length === 0) return 0;\n\n const reservationWorkspacePredicate =\n params.workspaceId === null\n ? sql``\n : sql`and ${eq(reservations.workspaceId, params.workspaceId)}`;\n\n const rows = await tx\n .select({\n id: providerRunners.id,\n releaseReservationId: sql<string | null>`coalesce(\n (select ${reservations.id}\n from ${reservations}\n where ${reservations.id} = ${providerRunners.intendedReservationId}\n and ${reservations.provisionerId} = ${params.provisionerId}\n ${reservationWorkspacePredicate}),\n (select ${reservations.id}\n from ${reservations}\n where ${reservations.id} = ${providerRunners.reservationId}\n and ${reservations.provisionerId} = ${params.provisionerId}\n ${reservationWorkspacePredicate})\n )`,\n releaseReservationWorkspaceId: sql<string | null>`coalesce(\n (select ${reservations.workspaceId}\n from ${reservations}\n where ${reservations.id} = ${providerRunners.intendedReservationId}\n and ${reservations.provisionerId} = ${params.provisionerId}\n ${reservationWorkspacePredicate}),\n (select ${reservations.workspaceId}\n from ${reservations}\n where ${reservations.id} = ${providerRunners.reservationId}\n and ${reservations.provisionerId} = ${params.provisionerId}\n ${reservationWorkspacePredicate})\n )`,\n })\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.provisionerId, params.provisionerId),\n inArray(providerRunners.providerRunnerId, params.providerRunnerIds),\n inArray(providerRunners.state, terminalStates),\n or(\n isNotNull(providerRunners.reservationId),\n isNotNull(providerRunners.intendedReservationId),\n ),\n params.workspaceId === null\n ? undefined\n : or(\n and(\n eq(providerRunners.workspaceId, params.workspaceId),\n or(\n exists(\n tx\n .select({id: reservations.id})\n .from(reservations)\n .where(\n and(\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n eq(reservations.id, providerRunners.reservationId),\n ),\n ),\n ),\n exists(\n tx\n .select({id: reservations.id})\n .from(reservations)\n .where(\n and(\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n eq(reservations.id, providerRunners.intendedReservationId),\n ),\n ),\n ),\n ),\n ),\n and(\n isNull(providerRunners.workspaceId),\n isNotNull(providerRunners.intendedReservationId),\n exists(\n tx\n .select({id: reservations.id})\n .from(reservations)\n .where(\n and(\n eq(reservations.workspaceId, params.workspaceId),\n eq(reservations.provisionerId, params.provisionerId),\n eq(reservations.id, providerRunners.intendedReservationId),\n ),\n ),\n ),\n ),\n ),\n params.requireUnlinkedSession === false\n ? undefined\n : isNull(providerRunners.runnerSessionId),\n isNull(providerRunners.reservationReleasedAt),\n ),\n )\n .for('update');\n\n if (rows.length === 0) return 0;\n\n const updated = await tx\n .update(providerRunners)\n .set({\n intendedReservationId: null,\n reservationReleasedAt: sql`now()`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n inArray(\n providerRunners.id,\n rows.map((row) => row.id),\n ),\n params.requireUnlinkedSession === false\n ? undefined\n : isNull(providerRunners.runnerSessionId),\n isNull(providerRunners.reservationReleasedAt),\n ),\n )\n .returning({id: providerRunners.id});\n\n const releasesByReservationId = new Map<\n string,\n {workspaceId: string; reservationId: string; count: number}\n >();\n const updatedIds = new Set(updated.map((row) => row.id));\n for (const row of rows) {\n if (!updatedIds.has(row.id)) continue;\n if (!row.releaseReservationId || !row.releaseReservationWorkspaceId) continue;\n const key = `${row.releaseReservationWorkspaceId}:${row.releaseReservationId}`;\n const release = releasesByReservationId.get(key) ?? {\n workspaceId: row.releaseReservationWorkspaceId,\n reservationId: row.releaseReservationId,\n count: 0,\n };\n release.count += 1;\n releasesByReservationId.set(key, release);\n }\n\n if (releasesByReservationId.size === 0) return 0;\n\n let released = 0;\n for (const release of releasesByReservationId.values()) {\n released += await releaseReservationUnits(tx, {\n workspaceId: release.workspaceId,\n provisionerId: params.provisionerId,\n releases: [{reservationId: release.reservationId, count: release.count}],\n });\n }\n return released;\n}\n\nfunction staleRunnerInstanceCutoff(thresholdSeconds: number): SQL {\n return sql`now() - (${thresholdSeconds} || ' seconds')::interval`;\n}\n\nfunction staleRunnerInstanceWhere(tx: Tx, cutoff: SQL): SQL<boolean> {\n return and(\n inArray(providerRunners.state, activeStates),\n lt(providerRunners.reportedAt, cutoff),\n lt(providerRunners.updatedAt, cutoff),\n exists(\n tx\n .select({id: provisionerTokens.id})\n .from(provisionerTokens)\n .where(\n and(\n eq(provisionerTokens.id, providerRunners.provisionerId),\n or(isNull(provisionerTokens.lastSeenAt), lt(provisionerTokens.lastSeenAt, cutoff)),\n ),\n ),\n ),\n notExists(\n tx\n .select({id: runningJobExecutions.id})\n .from(runningJobExecutions)\n .where(\n and(\n eq(runningJobExecutions.workspaceId, providerRunners.workspaceId),\n eq(runningJobExecutions.provisionerId, providerRunners.provisionerId),\n eq(runningJobExecutions.providerRunnerId, providerRunners.providerRunnerId),\n ),\n ),\n ),\n notExists(\n tx\n .select({id: runnerSessions.id})\n .from(runnerSessions)\n .where(\n and(\n eq(runnerSessions.workspaceId, providerRunners.workspaceId),\n eq(runnerSessions.provisionerId, providerRunners.provisionerId),\n eq(runnerSessions.providerRunnerId, providerRunners.providerRunnerId),\n sql`${runnerSessions.updatedAt} >= ${cutoff}`,\n ),\n ),\n ),\n ) as SQL<boolean>;\n}\n\nfunction groupRunnerInstanceIds(\n rows: Array<{\n workspaceId: string | null;\n provisionerId: string;\n providerRunnerId: string | null;\n }>,\n): Array<{workspaceId: string | null; provisionerId: string; providerRunnerIds: string[]}> {\n const groups = new Map<\n string,\n {workspaceId: string | null; provisionerId: string; providerRunnerIds: string[]}\n >();\n for (const row of rows) {\n if (!row.providerRunnerId) continue;\n const key = `${row.workspaceId ?? ''}:${row.provisionerId}`;\n const group = groups.get(key) ?? {\n workspaceId: row.workspaceId,\n provisionerId: row.provisionerId,\n providerRunnerIds: [],\n };\n group.providerRunnerIds.push(row.providerRunnerId);\n groups.set(key, group);\n }\n return [...groups.values()];\n}\n\nasync function hydrateRunnerSessionIdsFromConsumedTokens(\n tx: Tx,\n params: ReportRunnerInstancesParams,\n events: RunnerInstanceReportRow[],\n): Promise<RunnerInstanceReportRow[]> {\n if (!params.workspaceId) return events;\n const providerRunnerIds = [...new Set(events.map((event) => event.providerRunnerId))];\n if (providerRunnerIds.length === 0) return events;\n\n const tokenRows = await tx\n .select({\n providerRunnerId: ephemeralRegistrationTokens.providerRunnerId,\n consumedSessionId: ephemeralRegistrationTokens.consumedSessionId,\n })\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 isNotNull(ephemeralRegistrationTokens.consumedSessionId),\n ),\n )\n .orderBy(\n desc(ephemeralRegistrationTokens.consumedAt),\n desc(ephemeralRegistrationTokens.createdAt),\n );\n\n const consumedSessionIdsByRunnerInstanceId = new Map<string, string>();\n for (const row of tokenRows) {\n if (!row.consumedSessionId) continue;\n if (consumedSessionIdsByRunnerInstanceId.has(row.providerRunnerId)) continue;\n consumedSessionIdsByRunnerInstanceId.set(row.providerRunnerId, row.consumedSessionId);\n }\n\n if (consumedSessionIdsByRunnerInstanceId.size === 0) return events;\n\n return events.map((event) => {\n const consumedSessionId = consumedSessionIdsByRunnerInstanceId.get(event.providerRunnerId);\n if (!consumedSessionId || event.runnerSessionId === consumedSessionId) return event;\n return {...event, runnerSessionId: consumedSessionId};\n });\n}\n\nfunction aggregateEvents(\n events: RunnerInstanceReportEvent[],\n receivedAt: Date,\n): RunnerInstanceReportRow[] {\n const byRunnerInstanceId = new Map<string, RunnerInstanceReportRow>();\n for (const rawEvent of events) {\n const event = toRunnerInstanceReportRow(rawEvent, receivedAt);\n const existing = byRunnerInstanceId.get(event.providerRunnerId);\n if (existing) mergeMilestones(existing, event);\n if (!existing || compareRunnerInstanceReportEvents(event, existing) > 0) {\n byRunnerInstanceId.set(\n event.providerRunnerId,\n existing ? mergeProjectionMetadata(event, existing) : event,\n );\n }\n }\n return [...byRunnerInstanceId.values()];\n}\n\nfunction toRunnerInstanceReportRow(\n event: RunnerInstanceReportEvent,\n receivedAt: Date,\n): RunnerInstanceReportRow {\n const reportedAt = event.reportedAt > receivedAt ? receivedAt : event.reportedAt;\n return {\n ...event,\n reportedAt,\n startedAt: event.state === 'running' ? reportedAt : null,\n stoppingAt: event.state === 'stopping' ? reportedAt : null,\n stoppedAt: event.state === 'stopped' ? reportedAt : null,\n failedAt: event.state === 'failed' ? reportedAt : null,\n terminatedAt: event.state === 'terminated' ? reportedAt : null,\n };\n}\n\nfunction mergeMilestones(target: RunnerInstanceReportRow, source: RunnerInstanceReportRow) {\n target.startedAt = earliestDate(target.startedAt, source.startedAt);\n target.stoppingAt = earliestDate(target.stoppingAt, source.stoppingAt);\n target.stoppedAt = earliestDate(target.stoppedAt, source.stoppedAt);\n target.failedAt = earliestDate(target.failedAt, source.failedAt);\n target.terminatedAt = earliestDate(target.terminatedAt, source.terminatedAt);\n}\n\nfunction mergeProjectionMetadata(\n event: RunnerInstanceReportRow,\n existing: RunnerInstanceReportRow,\n): RunnerInstanceReportRow {\n return {\n ...event,\n reservationId: event.reservationId ?? existing.reservationId,\n templateKey: event.templateKey ?? existing.templateKey,\n runnerSessionId: event.runnerSessionId ?? existing.runnerSessionId,\n providerKind: event.providerKind ?? existing.providerKind,\n ...pickMilestones(existing),\n };\n}\n\nfunction pickMilestones(event: RunnerInstanceReportRow) {\n return {\n startedAt: event.startedAt,\n stoppingAt: event.stoppingAt,\n stoppedAt: event.stoppedAt,\n failedAt: event.failedAt,\n terminatedAt: event.terminatedAt,\n };\n}\n\nfunction earliestDate(a: Date | null, b: Date | null): Date | null {\n if (!a) return b;\n if (!b) return a;\n return a < b ? a : b;\n}\n\nfunction compareRunnerInstanceReportEvents(\n a: RunnerInstanceReportEvent,\n b: RunnerInstanceReportEvent,\n): number {\n const timeDelta = a.reportedAt.getTime() - b.reportedAt.getTime();\n const rankDelta = getRunnerInstanceStateRank(a.state) - getRunnerInstanceStateRank(b.state);\n if (rankDelta !== 0) return rankDelta;\n return timeDelta;\n}\n\nfunction getRunnerInstanceStateRank(state: RunnerInstanceState): number {\n switch (state) {\n case 'starting':\n return 1;\n case 'running':\n return 2;\n case 'stopping':\n return 3;\n case 'stopped':\n return 4;\n case 'failed':\n return 5;\n case 'terminated':\n return 6;\n }\n}\n\nfunction providerRunnerStateRank(state: SQL | typeof providerRunners.state): SQL<number> {\n return sql<number>`\n CASE ${state}\n WHEN 'starting' THEN 1\n WHEN 'running' THEN 2\n WHEN 'stopping' THEN 3\n WHEN 'stopped' THEN 4\n WHEN 'failed' THEN 5\n WHEN 'terminated' THEN 6\n ELSE 0\n END\n `;\n}\n\nfunction providerRunnerProjectionUpdateCondition(): SQL<boolean> {\n return sql<boolean>`\n ${providerRunnerStateRank(sql`excluded.state`)} > ${providerRunnerStateRank(providerRunners.state)}\n OR (\n ${providerRunnerStateRank(sql`excluded.state`)} = ${providerRunnerStateRank(providerRunners.state)}\n AND excluded.reported_at >= ${providerRunners.reportedAt}\n )\n `;\n}\n\nfunction providerRunnerMilestoneUpdateCondition(): SQL<boolean> {\n return sql<boolean>`\n ${milestoneNeedsUpdate(providerRunners.startedAt, sql`excluded.started_at`)}\n OR ${milestoneNeedsUpdate(providerRunners.stoppingAt, sql`excluded.stopping_at`)}\n OR ${milestoneNeedsUpdate(providerRunners.stoppedAt, sql`excluded.stopped_at`)}\n OR ${milestoneNeedsUpdate(providerRunners.failedAt, sql`excluded.failed_at`)}\n OR ${milestoneNeedsUpdate(providerRunners.terminatedAt, sql`excluded.terminated_at`)}\n `;\n}\n\nfunction milestoneNeedsUpdate(\n current: SQL | RunnerInstanceMilestoneColumn,\n incoming: SQL,\n): SQL<boolean> {\n return sql<boolean>`${incoming} IS NOT NULL AND (${current} IS NULL OR ${incoming} < ${current})`;\n}\n\nfunction firstObservedAt(current: SQL | RunnerInstanceMilestoneColumn, incoming: SQL) {\n return sql`\n CASE\n WHEN ${incoming} IS NULL THEN ${current}\n WHEN ${current} IS NULL THEN ${incoming}\n ELSE least(${current}, ${incoming})\n END\n `;\n}\n\nexport function isTerminalState(state: RunnerInstanceState): boolean {\n return terminalStates.includes(state as (typeof terminalStates)[number]);\n}\n\nfunction isDivergenceCountState(\n state: RunnerInstanceState,\n): state is (typeof divergenceCountStates)[number] {\n return divergenceCountStates.includes(state as (typeof divergenceCountStates)[number]);\n}\n"],"names":["logger","and","asc","desc","eq","exists","gt","inArray","isNotNull","isNull","lt","notExists","notInArray","or","sql","alias","sanitizeRunnerLabels","db","listRunningJobExecutionsByRunnerInstanceTx","releaseReservationUnits","ephemeralRegistrationTokens","provisionerTokens","reservations","runnerControlSessions","providerRunners","toRunnerInstance","runnerSessions","runningJobExecutions","terminalStates","activeStates","divergenceCountStates","attachRunnerInstanceProviderId","params","updated","update","set","providerRunnerId","updatedAt","where","id","runnerInstanceId","provisionerId","state","returning","length","reportRunnerInstances","events","accepted","reservationsReleased","terminateIntentsHonored","transaction","tx","receivedAt","Date","aggregatedEvents","aggregateEvents","hasTerminalEvent","some","event","isTerminalState","execute","workspaceId","hydrateRunnerSessionIdsFromConsumedTokens","listTerminateIntentsHonoredByTerminatedReportsTx","values","map","reservationId","templateKey","labels","scope","logLevel","source","reason","runnerSessionId","providerKind","reportedAt","startedAt","stoppingAt","stoppedAt","failedAt","terminatedAt","insert","onConflictDoUpdate","target","targetWhere","providerRunnerProjectionUpdateCondition","firstObservedAt","setWhere","providerRunnerMilestoneUpdateCondition","releaseTerminalRunnerInstanceReservations","listActiveRunnerInstanceCountsByTemplateTx","rows","select","count","from","groupBy","flatMap","row","isDivergenceCountState","countStaleEnrolledRunnerInstances","staleRunnerInstanceCutoff","graceSeconds","closedAt","expiresAt","listActiveRunnerInstances","windowSeconds","orderBy","limit","listProvisionerTerminateIntents","listProvisionerTerminateIntentRowsTx","provisionerTerminateIntentsQuery","truncated","returnedRows","slice","warn","returnedCount","newerRunningJobExecutions","innerJoin","cancellationRequestedAt","providerRunnerIds","undefined","jobExecutionId","terminatedRunnerInstanceIds","Set","filter","reconcileRunnerInstances","observedRunnerInstanceIds","absentIds","staleAbsentRows","terminateGraceSeconds","releaseTerminalRunnerInstanceReservationsByIds","observedRows","boundJobExecutions","boundJobExecutionsByRunnerInstanceId","Map","jobExecution","reapStaleRunnerInstances","cutoff","thresholdSeconds","candidateRows","staleRunnerInstanceWhere","reaped","workspaceIds","sort","updatedRows","group","groupRunnerInstanceIds","requireUnlinkedSession","terminalEvents","reservationWorkspacePredicate","releaseReservationId","intendedReservationId","releaseReservationWorkspaceId","reservationReleasedAt","for","releasesByReservationId","updatedIds","has","key","release","get","size","released","releases","lastSeenAt","groups","push","tokenRows","consumedSessionId","consumedAt","createdAt","consumedSessionIdsByRunnerInstanceId","byRunnerInstanceId","rawEvent","toRunnerInstanceReportRow","existing","mergeMilestones","compareRunnerInstanceReportEvents","mergeProjectionMetadata","earliestDate","pickMilestones","a","b","timeDelta","getTime","rankDelta","getRunnerInstanceStateRank","providerRunnerStateRank","milestoneNeedsUpdate","current","incoming","includes"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"runner-sessions.d.ts","sourceRoot":"","sources":["../../src/db/runner-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,kCAAkC,CAAC;AAWpE,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,WAAW,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACrD;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,aAAa,CAAC,CAmBxB;AAED,wBAAsB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CASjG;AAED,wBAAsB,2CAA2C,CAAC,MAAM,EAAE;IACxE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACrD,0BA6EA;AAED,MAAM,WAAW,iCAAiC;IAChD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,iCAAiC,GACxC,OAAO,CAAC,MAAM,CAAC,CAuCjB"}
1
+ {"version":3,"file":"runner-sessions.d.ts","sourceRoot":"","sources":["../../src/db/runner-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,kCAAkC,CAAC;AAWpE,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,WAAW,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACrD;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,aAAa,CAAC,CAmBxB;AAED,wBAAsB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CASjG;AAED,wBAAsB,2CAA2C,CAAC,MAAM,EAAE;IACxE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACrD,0BAwFA;AAED,MAAM,WAAW,iCAAiC;IAChD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,iCAAiC,GACxC,OAAO,CAAC,MAAM,CAAC,CAuCjB"}