chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import { tryCatch } from "@trigger.dev/core";
|
||||
import { ManageConcurrencyPresenter } from "~/presenters/v3/ManageConcurrencyPresenter.server";
|
||||
import { BaseService } from "./baseService.server";
|
||||
import { updateEnvConcurrencyLimits } from "../runQueue.server";
|
||||
import { controlPlaneResolver } from "~/v3/runOpsMigration/controlPlaneResolver.server";
|
||||
|
||||
type Input = {
|
||||
userId: string;
|
||||
projectId: string;
|
||||
organizationId: string;
|
||||
environments: { id: string; amount: number }[];
|
||||
};
|
||||
|
||||
type Result =
|
||||
| {
|
||||
success: true;
|
||||
}
|
||||
| {
|
||||
success: false;
|
||||
error: string;
|
||||
};
|
||||
|
||||
export class AllocateConcurrencyService extends BaseService {
|
||||
async call({ userId, projectId, organizationId, environments }: Input): Promise<Result> {
|
||||
// fetch the current concurrency
|
||||
const presenter = new ManageConcurrencyPresenter(this._prisma, this._replica);
|
||||
const [error, result] = await tryCatch(
|
||||
presenter.call({
|
||||
userId,
|
||||
projectId,
|
||||
organizationId,
|
||||
})
|
||||
);
|
||||
|
||||
if (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: "Unknown error",
|
||||
};
|
||||
}
|
||||
|
||||
const previousExtra = result.environments.reduce(
|
||||
(acc, e) => Math.max(0, e.maximumConcurrencyLimit - e.planConcurrencyLimit) + acc,
|
||||
0
|
||||
);
|
||||
const requested = new Map(environments.map((e) => [e.id, e.amount]));
|
||||
const newExtra = result.environments.reduce((acc, env) => {
|
||||
const targetExtra = requested.has(env.id)
|
||||
? Math.max(0, requested.get(env.id)!)
|
||||
: Math.max(0, env.maximumConcurrencyLimit - env.planConcurrencyLimit);
|
||||
return acc + targetExtra;
|
||||
}, 0);
|
||||
const change = newExtra - previousExtra;
|
||||
|
||||
const totalExtra = result.extraAllocatedConcurrency + change;
|
||||
|
||||
if (change > result.extraUnallocatedConcurrency) {
|
||||
return {
|
||||
success: false,
|
||||
error: `You don't have enough unallocated concurrency available. You requested ${totalExtra} but only have ${result.extraUnallocatedConcurrency}.`,
|
||||
};
|
||||
}
|
||||
|
||||
for (const environment of environments) {
|
||||
const existingEnvironment = result.environments.find((e) => e.id === environment.id);
|
||||
|
||||
if (!existingEnvironment) {
|
||||
return {
|
||||
success: false,
|
||||
error: `Environment not found ${environment.id}`,
|
||||
};
|
||||
}
|
||||
|
||||
const newConcurrency = existingEnvironment.planConcurrencyLimit + environment.amount;
|
||||
|
||||
const updatedEnvironment = await this._prisma.runtimeEnvironment.update({
|
||||
where: {
|
||||
id: environment.id,
|
||||
},
|
||||
data: {
|
||||
maximumConcurrencyLimit: newConcurrency,
|
||||
},
|
||||
include: {
|
||||
project: true,
|
||||
organization: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!updatedEnvironment.paused) {
|
||||
await updateEnvConcurrencyLimits(updatedEnvironment);
|
||||
}
|
||||
|
||||
// maximumConcurrencyLimit changed in the control-plane; drop any cached copy.
|
||||
controlPlaneResolver.invalidateEnvironment(environment.id);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user