import * as Effect from "effect/Effect";
import * as Schedule from "effect/Schedule";
/**
* Retry an operation while it fails with a VPC Lattice `ConflictException` —
* raised while a resource still has in-flight associations being torn down.
* Bounded so a genuinely stuck resource fails fast rather than hanging the
* engine.
*
* The explicit `Effect.Effect` return annotation is load-bearing:
* inlining `Effect.retry` in provider lifecycle code lets `Retry.Return`'s
* conditional type survive into declaration emit and widen the provider layer
* to `unknown`, breaking every downstream consumer of `AWS.providers()`.
*/
export const retryOnConflict = (
effect: Effect.Effect,
): Effect.Effect =>
Effect.retry(effect, {
while: (e) => e._tag === "ConflictException",
schedule: Schedule.max([Schedule.spaced("3 seconds"), Schedule.recurs(10)]),
});
/**
* Re-run an observation effect until the observed resource is no longer in a
* transitional `*_IN_PROGRESS` state (VPC Lattice services and associations
* spend a while `CREATE_IN_PROGRESS` and reject updates/deletes until active).
* Bounded; explicit return annotation for the declaration-emit reason above.
*/
export const waitUntilStable = <
A extends { status?: string },
E extends { readonly _tag: string },
R,
>(
observe: Effect.Effect,
): Effect.Effect =>
Effect.repeat(observe, {
schedule: Schedule.max([Schedule.spaced("3 seconds"), Schedule.recurs(20)]),
until: (s) => s === undefined || !(s.status ?? "").endsWith("IN_PROGRESS"),
});
/**
* Re-run an observation until the resource is observably absent. Delete APIs
* commonly return before VPC Lattice removes the resource; a merely stable
* `ACTIVE` response is not deletion success. Bounded to about 60 seconds.
*/
export const waitUntilAbsent = (
observe: Effect.Effect,
): Effect.Effect =>
Effect.repeat(observe, {
schedule: Schedule.max([Schedule.spaced("2 seconds"), Schedule.recurs(30)]),
until: (resource) => resource === undefined,
});