feat: improve resource reconciliation and observability

This commit is contained in:
2026-09-11 10:51:57 +00:00 Unverified
parent 0067a2cdcd
commit e3df2f4d76
28 changed files with 2407 additions and 217 deletions
+65
View File
@@ -78,7 +78,9 @@ class FakeObjects implements BuildObjectApi {
readonly selectors: string[] = [];
readonly deletes: Array<{ name: string; options?: DeleteOptions }> = [];
onLockRead?: () => void;
onReplace?: (value: ConfigMap) => Promise<void> | void;
private lockRead = false;
private replacing = false;
async create(value: ConfigMap): Promise<unknown> {
if (
@@ -115,6 +117,14 @@ class FakeObjects implements BuildObjectApi {
)
)
throw { code: 422 };
if (!this.replacing && this.onReplace) {
this.replacing = true;
try {
await this.onReplace(value);
} finally {
this.replacing = false;
}
}
const current = this.maps.get(value.metadata.name);
if (
!current ||
@@ -346,4 +356,59 @@ describe("KubernetesBuildStore", () => {
"1",
);
});
test("fences a stale replace when an expired lease is taken over", async () => {
const fake = new FakeObjects();
const kuber = store(fake);
const record = build("fenced", "2026-09-02T00:00:00.000Z");
record.status.reconcileLease = {
holder: "stale-replica",
token: "stale-token",
expiresAt: new Date(0).toISOString(),
};
fake.maps.set(name("build", record.metadata.name), configMap(record));
const stale = (await kuber.getBuild(record.metadata.name))!;
stale.metadata.resourceVersion = "2";
stale.status.logBytes = 99;
stale.status.reconcileLease!.expiresAt = "2100-01-01T00:00:00.000Z";
let successorToken = "";
fake.onReplace = async () => {
const successor = await kuber.acquireBuildReconciliationLease(
record.metadata.name,
"current-replica",
60_000,
);
successorToken = successor!.token;
};
await expect(kuber.replaceBuild(stale, "1", "stale-token")).rejects.toThrow(
"concurrently modified",
);
fake.onReplace = undefined;
const takenOver = (await kuber.getBuild(record.metadata.name))!;
expect(takenOver.metadata.resourceVersion).toBe("2");
expect(takenOver.status.logBytes).toBe(0);
expect(takenOver.status.reconcileLease).toMatchObject({
holder: "current-replica",
token: successorToken,
});
expect(takenOver.status.reconcileLease?.expiresAt).not.toBe(
"2100-01-01T00:00:00.000Z",
);
const current = structuredClone(takenOver);
current.metadata.resourceVersion = "3";
current.status.logBytes = 7;
await kuber.replaceBuild(
current,
takenOver.metadata.resourceVersion,
successorToken,
);
expect((await kuber.getBuild(record.metadata.name))?.status).toMatchObject({
logBytes: 7,
reconcileLease: { token: successorToken },
});
});
});