complete method
Marks claim as dispatched successfully.
Implementations should retain the completed key long enough to cover the schedule's replay window. This operation is idempotent.
Implementation
@override
Future<void> complete(ScheduleClaim claim) async {
final durableStore = _durableStore;
if (durableStore != null) {
final completed = await durableStore.completeScheduleClaim(
lockName: _lockKey(claim.occurrence),
owner: claim.token,
completedKey: _completedKey(claim.occurrence),
completedSeconds: _seconds(completedTtl),
);
if (!completed) {
throw StateError(
'Schedule claim is no longer owned by this runtime.',
);
}
return;
}
// Generic Store implementations do not have a compound operation for
// fencing a write against a lock owner. Check ownership before writing so
// stale claims are rejected; the Durable Object implementation above is
// the atomic path used in production Cloudflare deployments.
final lock = await locks.restoreLock(
_lockKey(claim.occurrence),
claim.token,
);
if (!await lock.isOwnedByCurrentProcess()) {
throw StateError('Schedule claim is no longer owned by this runtime.');
}
final stored = await store.put(
_completedKey(claim.occurrence),
'completed',
_seconds(completedTtl),
);
if (!stored) {
throw StateError('Schedule completion could not be recorded.');
}
await lock.release();
}