53 lines
1.3 KiB
Go
53 lines
1.3 KiB
Go
package controlplane
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
)
|
|
|
|
var ErrSnapshotStreamClosed = errors.New("worker snapshot stream closed")
|
|
|
|
type SessionRunner struct {
|
|
reporter *RuntimeReporter
|
|
watcher *SnapshotWatcher
|
|
}
|
|
|
|
func NewSessionRunner(reporter *RuntimeReporter, watcher *SnapshotWatcher) (*SessionRunner, error) {
|
|
if reporter == nil || watcher == nil {
|
|
return nil, ErrInvalidOptions
|
|
}
|
|
return &SessionRunner{reporter: reporter, watcher: watcher}, nil
|
|
}
|
|
|
|
// Run registers exactly once, then runs snapshot intake and Runtime reporting
|
|
// against that session. A stream ending without context cancellation is a
|
|
// failure so the owning process can apply its reconnect policy.
|
|
func (runner *SessionRunner) Run(ctx context.Context) error {
|
|
if runner == nil || ctx == nil {
|
|
return ErrInvalidOptions
|
|
}
|
|
registration, err := runner.reporter.Register(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
groupCtx, cancel := context.WithCancel(ctx)
|
|
defer cancel()
|
|
results := make(chan error, 2)
|
|
go func() { results <- runner.watcher.Watch(groupCtx, registration.SessionID) }()
|
|
go func() { results <- runner.reporter.RunRegistered(groupCtx) }()
|
|
|
|
first := <-results
|
|
cancel()
|
|
second := <-results
|
|
if ctx.Err() != nil {
|
|
return ctx.Err()
|
|
}
|
|
if first == nil {
|
|
return ErrSnapshotStreamClosed
|
|
}
|
|
if errors.Is(first, context.Canceled) && second != nil {
|
|
return second
|
|
}
|
|
return first
|
|
}
|