| 1 | package hostexec |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "errors" |
| 6 | "os" |
| 7 | |
| 8 | "github.com/carlosframework/platform/internal/rootparticipation" |
| 9 | ) |
| 10 | |
| 11 | func (b *RootBroker) servingView(ctx context.Context, peer ControllerProcess, q ExecutionRequest, authority ExecutionAuthority) (ExecutionResponse, error) { |
| 12 | if authority.Kind != "serving" || (authority.Installation == "" && !authority.ParticipationOnly) { |
| 13 | return ExecutionResponse{}, ErrInactive |
| 14 | } |
| 15 | unlock, err := b.cfg.State.Lock(ctx, "transaction.lock") |
| 16 | if err != nil { |
| 17 | return ExecutionResponse{}, err |
| 18 | } |
| 19 | defer unlock() |
| 20 | if _, err := b.cfg.State.Read("update.json"); !errors.Is(err, os.ErrNotExist) { |
| 21 | return ExecutionResponse{}, ErrInactive |
| 22 | } |
| 23 | census, err := (rootparticipation.Ledger{State: b.cfg.State, Box: authority.Box, Enrollment: authority.Enrollment}).Census() |
| 24 | if err != nil || census.Migration != authority.Migration { |
| 25 | return ExecutionResponse{}, errors.Join(err, ErrState) |
| 26 | } |
| 27 | if _, err := ReadRoot(ctx, b.cfg.State, b.cfg.Clock, q, true); err != nil { |
| 28 | return ExecutionResponse{}, err |
| 29 | } |
| 30 | fresh, err := b.cfg.Authority(ctx, q, peer) |
| 31 | if err != nil || fresh != authority { |
| 32 | return ExecutionResponse{}, errors.Join(err, ErrLost) |
| 33 | } |
| 34 | if err := b.cfg.Alive(ctx, peer); err != nil { |
| 35 | return ExecutionResponse{}, err |
| 36 | } |
| 37 | b.mu.Lock() |
| 38 | defer b.mu.Unlock() |
| 39 | if b.closed || ctx.Err() != nil { |
| 40 | return ExecutionResponse{}, ErrLost |
| 41 | } |
| 42 | return ExecutionResponse{Schema: 1, Host: q.Host, Incarnation: q.Incarnation, Stamp: q.Stamp, Session: q.Session, Op: q.Op, BootID: peer.KernelBootID, Status: "serving"}, nil |
| 43 | } |
| 44 | |