package domain import ( "errors" "time" "git.cin.su/m/Assistant/contracts/work" ) var ErrDryRunDispatchRejected = errors.New("dry-run dispatch rejected") func BuildDryRunDispatch(intent work.AgentDispatchIntent, workerID string, token work.AgentFencingToken, now time.Time, ttl time.Duration) (work.DryRunDispatch, error) { if ValidateDispatchIntent(intent) != nil || workerID == "" || token == 0 || now.IsZero() || ttl <= 0 { return work.DryRunDispatch{}, ErrDryRunDispatchRejected } lease, err := AcquireAgentLease(intent.RunID, workerID, token, now, ttl) if err != nil { return work.DryRunDispatch{}, ErrDryRunDispatchRejected } heartbeat := work.AgentCallback{RunID: intent.RunID, WorkerID: workerID, FencingToken: token, Sequence: 1, Kind: work.AgentCallbackHeartbeat, ObservedAt: now.Add(ttl / 3)} result := work.AgentCallback{RunID: intent.RunID, WorkerID: workerID, FencingToken: token, Sequence: 2, Kind: work.AgentCallbackResult, ObservedAt: now.Add((ttl * 2) / 3)} if ValidateAgentCallback(heartbeat, lease, 0) != nil || ValidateAgentCallback(result, lease, heartbeat.Sequence) != nil { return work.DryRunDispatch{}, ErrDryRunDispatchRejected } return work.DryRunDispatch{Intent: intent, Lease: lease, Callbacks: []work.AgentCallback{heartbeat, result}}, nil }