Skip to content

Commit df3b681

Browse files
committed
fix(daemon): anchor provider session retention at expiry
1 parent 380e11b commit df3b681

3 files changed

Lines changed: 10 additions & 16 deletions

File tree

src/daemon/handlers/__tests__/lease-artifacts.test.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ test('artifacts refuses a released provider session after the retention window',
9797
assert.deepEqual(world.providerCalls, []);
9898
});
9999

100-
test('artifacts retains an expired provider session only through the release window', async () => {
100+
test('artifacts refuses an expired provider session after retention before lazy cleanup', async () => {
101101
let now = 1_000;
102102
const world = createWorld({
103103
now: () => now,
@@ -108,15 +108,6 @@ test('artifacts retains an expired provider session only through the release win
108108
});
109109
const lease = await allocateLease(world, 'tenant-a', 'run-a');
110110

111-
now = lease.expiresAt + 1;
112-
const retained = await listArtifacts(world, {
113-
tenantId: 'tenant-a',
114-
runId: 'run-a',
115-
providerSessionId: 'session-tenant-a',
116-
});
117-
assert.equal(retained.ok, true);
118-
119-
world.providerCalls.length = 0;
120111
now = lease.expiresAt + 51;
121112
await assertProviderSessionNotOwned(world, {
122113
tenantId: 'tenant-a',

src/daemon/lease-registry.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ export class LeaseRegistry {
376376
for (const lease of this.leases.values()) {
377377
if (lease.expiresAt > now) continue;
378378
this.leases.delete(lease.leaseId);
379-
this.unbindLease(lease);
379+
this.unbindLease(lease, lease.expiresAt);
380380
const expiredLease = { ...lease };
381381
expired.push(expiredLease);
382382
this.onLeaseExpired?.(expiredLease);
@@ -390,7 +390,7 @@ export class LeaseRegistry {
390390
const lease = this.leases.get(normalizedLeaseId);
391391
if (!lease || lease.expiresAt > this.now()) return undefined;
392392
this.leases.delete(lease.leaseId);
393-
this.unbindLease(lease);
393+
this.unbindLease(lease, lease.expiresAt);
394394
const expiredLease = { ...lease };
395395
this.onLeaseExpired?.(expiredLease);
396396
return expiredLease;
@@ -473,7 +473,7 @@ export class LeaseRegistry {
473473
}
474474
}
475475

476-
private unbindLease(lease: DeviceLease): void {
476+
private unbindLease(lease: DeviceLease, releasedAt = this.now()): void {
477477
this.runBindings.delete(
478478
this.bindingKey({
479479
tenantId: lease.tenantId,
@@ -487,7 +487,7 @@ export class LeaseRegistry {
487487
if (deviceBindingKey) {
488488
this.deviceBindings.delete(deviceBindingKey);
489489
}
490-
this.providerSessionOwnership.markLeaseReleased(lease);
490+
this.providerSessionOwnership.markLeaseReleased(lease, releasedAt);
491491
}
492492

493493
private bindingKey(params: {

src/daemon/provider-session-ownership.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,14 @@ export class ProviderSessionOwnershipRegistry {
4848
this.records.set(this.key(provider, providerSessionId), ownership);
4949
}
5050

51-
markLeaseReleased(lease: Pick<DeviceLease, 'leaseId' | 'leaseProvider'>): void {
51+
markLeaseReleased(
52+
lease: Pick<DeviceLease, 'leaseId' | 'leaseProvider'>,
53+
releasedAt = this.now(),
54+
): void {
5255
const provider = lease.leaseProvider?.trim();
5356
if (!provider) return;
5457
this.prune();
55-
const retainedUntil = this.now() + this.retentionMs;
58+
const retainedUntil = releasedAt + this.retentionMs;
5659
for (const [key, record] of this.records) {
5760
if (record.provider !== provider || record.leaseId !== lease.leaseId) continue;
5861
this.records.set(key, { ...record, retainedUntil });

0 commit comments

Comments
 (0)