Bound bridge startup provider probes
This commit is contained in:
parent
3b088f71e2
commit
22d4154597
@ -3,11 +3,14 @@ package acp
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"xworkmate-bridge/internal/gatewayruntime"
|
||||
"xworkmate-bridge/internal/memory"
|
||||
)
|
||||
|
||||
const bootstrapProviderProbeTimeout = 2 * time.Second
|
||||
|
||||
// Bootstrap initializes the control plane components
|
||||
func (s *Server) Bootstrap() {
|
||||
s.mu.Lock()
|
||||
@ -67,7 +70,7 @@ func (s *Server) Bootstrap() {
|
||||
"category": category,
|
||||
})
|
||||
if compat, ok := s.providers[id]; ok {
|
||||
probe := compat.Probe(context.Background())
|
||||
probe := probeProviderForBootstrap(compat, bootstrapProviderProbeTimeout)
|
||||
s.catalog.ProviderProbeSummary = append(s.catalog.ProviderProbeSummary, map[string]any{
|
||||
"providerId": id,
|
||||
"available": probe.Available,
|
||||
@ -77,6 +80,32 @@ func (s *Server) Bootstrap() {
|
||||
}
|
||||
}
|
||||
|
||||
func probeProviderForBootstrap(
|
||||
compat ProviderCompat,
|
||||
timeout time.Duration,
|
||||
) ProviderProbeResult {
|
||||
if compat == nil {
|
||||
return ProviderProbeResult{Available: false, Status: "provider unavailable"}
|
||||
}
|
||||
if timeout <= 0 {
|
||||
timeout = bootstrapProviderProbeTimeout
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
resultCh := make(chan ProviderProbeResult, 1)
|
||||
go func() {
|
||||
resultCh <- compat.Probe(ctx)
|
||||
}()
|
||||
|
||||
select {
|
||||
case result := <-resultCh:
|
||||
return result
|
||||
case <-ctx.Done():
|
||||
return ProviderProbeResult{Available: false, Status: ctx.Err().Error()}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) getAvailableProviderIDs() []string {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
65
internal/acp/bootstrap_test.go
Normal file
65
internal/acp/bootstrap_test.go
Normal file
@ -0,0 +1,65 @@
|
||||
package acp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestProbeProviderForBootstrapTimesOut(t *testing.T) {
|
||||
start := time.Now()
|
||||
result := probeProviderForBootstrap(
|
||||
blockingProviderCompat{},
|
||||
20*time.Millisecond,
|
||||
)
|
||||
|
||||
if result.Available {
|
||||
t.Fatalf("expected timed out provider to be unavailable")
|
||||
}
|
||||
if result.Status != context.DeadlineExceeded.Error() {
|
||||
t.Fatalf("expected deadline status, got %q", result.Status)
|
||||
}
|
||||
if elapsed := time.Since(start); elapsed > time.Second {
|
||||
t.Fatalf("bootstrap probe blocked too long: %s", elapsed)
|
||||
}
|
||||
}
|
||||
|
||||
type blockingProviderCompat struct{}
|
||||
|
||||
func (blockingProviderCompat) ID() string { return "blocking" }
|
||||
|
||||
func (blockingProviderCompat) Metadata() map[string]any {
|
||||
return map[string]any{"providerId": "blocking"}
|
||||
}
|
||||
|
||||
func (blockingProviderCompat) Probe(context.Context) ProviderProbeResult {
|
||||
select {}
|
||||
}
|
||||
|
||||
func (blockingProviderCompat) StartSession(
|
||||
context.Context,
|
||||
string,
|
||||
string,
|
||||
map[string]any,
|
||||
SessionNotificationSink,
|
||||
) (map[string]any, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (blockingProviderCompat) SendMessage(
|
||||
context.Context,
|
||||
string,
|
||||
string,
|
||||
map[string]any,
|
||||
SessionNotificationSink,
|
||||
) (map[string]any, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (blockingProviderCompat) CancelSession(context.Context, string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (blockingProviderCompat) CloseSession(context.Context, string) error {
|
||||
return nil
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user