| 1 | package activator |
| 2 | |
| 3 | import ( |
| 4 | "errors" |
| 5 | |
| 6 | "github.com/carlosframework/platform/internal/registry" |
| 7 | ) |
| 8 | |
| 9 | // errClaimsNoGenerations refuses a claims-on swap whose claim runtime cannot |
| 10 | // start a generation of its own (ClaimRuntime.Generations and Pins). It is |
| 11 | // returned before anything is raised, stopped or spawned. |
| 12 | var errClaimsNoGenerations = errors.New("swap: claims are on and the claim runtime cannot start a generation of its own") |
| 13 | |
| 14 | // claimsSwapRefusal is the guard every claims-backed swap (work that is not |
| 15 | // hostwrite.Legacy) meets before its side effects: before the admission |
| 16 | // runs inside the work, before an overlap raises the parent, before a hold |
| 17 | // stops its incumbent (final review F9, index P2-9). On this base it always |
| 18 | // refuses. A runtime without Generations and Pins gets |
| 19 | // errClaimsNoGenerations, as before. One with both still meets the closed |
| 20 | // isolated launch (ErrClaimIsolationUnavailable, as the admission's |
| 21 | // refusal: NoOwnership, so the attempt is abandoned, never failed). The |
| 22 | // booleans stay for plan 5; they alone never open this guard. |
| 23 | // |
| 24 | // overlap names the one exception, and it is a test seam: claimSpawn, the |
| 25 | // stand-in for a working isolated launch, lets an overlap through to its |
| 26 | // claims-on spawn. Only this package's tests set it (no production file |
| 27 | // assigns it; TestClaimSpawnIsATestSeam checks that), so production always |
| 28 | // refuses here. A hold has no stand-in: its pinned wake would run the |
| 29 | // closed claims launch itself, so it is refused even then. |
| 30 | func (a *Service) claimsSwapRefusal(overlap bool) error { |
| 31 | if r := a.cfg.Claims; r == nil || !r.Generations || !r.Pins { |
| 32 | return errClaimsNoGenerations |
| 33 | } |
| 34 | if overlap && a.claimSpawn != nil { |
| 35 | return nil |
| 36 | } |
| 37 | return claimAdmission(ErrClaimIsolationUnavailable, false) |
| 38 | } |
| 39 | |
| 40 | // claimGenAt is generation n's handle for a claims-on spawn: the generation |
| 41 | // sockets where the row has them, and the canonical socket (with a real |
| 42 | // number) where it does not. |
| 43 | func (a *Service) claimGenAt(rt registry.Route, n uint64) Gen { |
| 44 | if gp, ok := a.backend.(genPather); ok { |
| 45 | if g, ok := gp.GenPaths(rt, n); ok { |
| 46 | return g |
| 47 | } |
| 48 | } |
| 49 | return Gen{N: n, Socket: rt.Socket, Control: rt.Socket + ".control"} |
| 50 | } |
| 51 | |