Bound bridge startup provider probes

This commit is contained in:
Haitao Pan 2026-05-26 11:14:56 +08:00
parent 3b088f71e2
commit 22d4154597
2 changed files with 95 additions and 1 deletions

View File

@ -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()

View 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
}