proxy-pool/internal/gateway/controlplane/session_runner.go
youfak 27035947dd
Some checks are pending
ci / proto (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
ci / race (push) Waiting to run
ci / integration (push) Waiting to run
feat: coordinate gateway control plane session
2026-07-31 13:29:26 +08:00

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
}