Download this file
| 1 | package console |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "errors" |
| 6 | "sort" |
| 7 | |
| 8 | "github.com/carlosframework/platform/internal/hostclaim" |
| 9 | "github.com/carlosframework/platform/internal/hostops" |
| 10 | ) |
| 11 | |
| 12 | // SweepClaimHolds recovers the directory half even after an operation's |
| 13 | // claim intent has been cleared by successful completion or freeing. |
| 14 | func (s *Server) SweepClaimHolds(ctx context.Context) error { |
| 15 | if !s.cfg.HostClaim { |
| 16 | return nil |
| 17 | } |
| 18 | a := s.cfg.ClaimAuthority |
| 19 | if a == nil { |
| 20 | return hostops.ErrContract |
| 21 | } |
| 22 | roster, err := a.Directory.Read(ctx) |
| 23 | if err != nil { |
| 24 | return err |
| 25 | } |
| 26 | ids := make([]string, 0, len(roster.Roster.Holds)) |
| 27 | for id := range roster.Roster.Holds { |
| 28 | ids = append(ids, id) |
| 29 | } |
| 30 | sort.Strings(ids) |
| 31 | var all []error |
| 32 | for _, id := range ids { |
| 33 | hold := roster.Roster.Holds[id] |
| 34 | claim, err := hostclaim.Read(ctx, a.Store, hold.Host) |
| 35 | if err != nil { |
| 36 | all = append(all, err) |
| 37 | continue |
| 38 | } |
| 39 | if !claim.Absent && claim.ETag != hold.ExpectedClaimETag && (claim.Claim.Free() || claim.Claim.Op.Kind == hostclaim.KindServing) { |
| 40 | err = a.Directory.ReleaseFinishedHold(ctx, a.Signer, id) |
| 41 | } else if !claim.Absent && claim.Claim.Op.Intent["actors_hold"] == id { |
| 42 | continue |
| 43 | } else { |
| 44 | // CancelHold first invalidates the reserved claim revision, rereads both |
| 45 | // objects, and refuses if an uncertain Start actually attached this hold. |
| 46 | err = a.Directory.CancelHold(ctx, a.Signer, id) |
| 47 | } |
| 48 | if err != nil { |
| 49 | all = append(all, err) |
| 50 | } |
| 51 | } |
| 52 | return errors.Join(all...) |
| 53 | } |
| 54 | |