55 lines
2.0 KiB
Go
55 lines
2.0 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
rvboxv1 "github.com/rvbox/rvbox/gen/go/rvbox/v1"
|
|
"github.com/rvbox/rvbox/internal/domain"
|
|
)
|
|
|
|
var ErrInvalidReconcileResult = errors.New("invalid reconciliation result")
|
|
|
|
// ReconcileStore is the narrowly scoped durable operation required after the
|
|
// server has confirmed a terminal command. Keeping the interface small lets the
|
|
// network loop remain independent of SQLite and of the Windows supervisor.
|
|
type ReconcileStore interface {
|
|
DiscardTerminal(context.Context, domain.UUID, time.Time) error
|
|
}
|
|
|
|
// ApplyReconcileResult commits server-authorized terminal discards before the
|
|
// session starts new work. It returns the active command IDs that the caller
|
|
// must first terminate through the supervisor; marking those terminal is not
|
|
// safe until the owned process and output readers have stopped.
|
|
func ApplyReconcileResult(ctx context.Context, store ReconcileStore, result *rvboxv1.ReconcileResult, now time.Time) ([]domain.UUID, error) {
|
|
if store == nil || result == nil || now.IsZero() {
|
|
return nil, ErrInvalidReconcileResult
|
|
}
|
|
seen := make(map[domain.UUID]struct{}, len(result.GetTerminateLocalIssueUuids())+len(result.GetDiscardLocalTerminalIssueUuids()))
|
|
terminate := make([]domain.UUID, 0, len(result.GetTerminateLocalIssueUuids()))
|
|
for _, set := range [][]string{result.GetTerminateLocalIssueUuids(), result.GetDiscardLocalTerminalIssueUuids()} {
|
|
for _, text := range set {
|
|
issue, err := domain.ParseUUIDv7(text)
|
|
if err != nil {
|
|
return nil, ErrInvalidReconcileResult
|
|
}
|
|
if _, duplicate := seen[issue]; duplicate {
|
|
return nil, ErrInvalidReconcileResult
|
|
}
|
|
seen[issue] = struct{}{}
|
|
}
|
|
}
|
|
for _, text := range result.GetDiscardLocalTerminalIssueUuids() {
|
|
issue, _ := domain.ParseUUIDv7(text)
|
|
if err := store.DiscardTerminal(ctx, issue, now); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
for _, text := range result.GetTerminateLocalIssueUuids() {
|
|
issue, _ := domain.ParseUUIDv7(text)
|
|
terminate = append(terminate, issue)
|
|
}
|
|
return terminate, nil
|
|
}
|