78 lines
2.0 KiB
Go
78 lines
2.0 KiB
Go
package usecase
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"gitea.maximumdirect.net/eric/promptkit/internal/domain"
|
|
"gitea.maximumdirect.net/eric/promptkit/internal/generation"
|
|
"gitea.maximumdirect.net/eric/promptkit/internal/llm"
|
|
)
|
|
|
|
type smokeHTTPGetter interface {
|
|
GetWithEvidence(context.Context, string, int) (*http.Response, llm.HTTPExecutionEvidence, error)
|
|
}
|
|
|
|
type reachabilityProbe struct {
|
|
client smokeHTTPGetter
|
|
}
|
|
|
|
type reachabilityProbeOutcome struct {
|
|
supported bool
|
|
reason domain.SmokeTestReason
|
|
initialEndpoint string
|
|
reachable *bool
|
|
evidence llm.HTTPExecutionEvidence
|
|
failure domain.ExecutionFailureKind
|
|
}
|
|
|
|
func (p reachabilityProbe) run(
|
|
ctx context.Context,
|
|
endpoint string,
|
|
timeoutSeconds int,
|
|
) (reachabilityProbeOutcome, error) {
|
|
if p.client == nil {
|
|
return reachabilityProbeOutcome{
|
|
reason: domain.SmokeTestReasonHTTPDiagnosticsUnavailable,
|
|
}, nil
|
|
}
|
|
|
|
endpoint, err := endpointWithoutUserInfo(endpoint)
|
|
if err != nil {
|
|
return reachabilityProbeOutcome{}, fmt.Errorf("prepare reachability endpoint: %w", err)
|
|
}
|
|
result := reachabilityProbeOutcome{supported: true, initialEndpoint: endpoint}
|
|
response, evidence, requestErr := p.client.GetWithEvidence(ctx, endpoint, timeoutSeconds)
|
|
if response != nil && response.Body != nil {
|
|
_ = response.Body.Close()
|
|
}
|
|
result.evidence = evidence
|
|
if evidence.ResponseReceived || response != nil {
|
|
result.reachable = boolPointer(true)
|
|
return result, nil
|
|
}
|
|
if evidence.DispatchInvoked {
|
|
result.reachable = boolPointer(false)
|
|
}
|
|
if requestErr != nil {
|
|
result.failure = generation.ClassifyFailure(fmt.Errorf("%w: %w", llm.ErrTransport, requestErr))
|
|
if !evidence.DispatchInvoked {
|
|
return result, fmt.Errorf("execute reachability request: %w", requestErr)
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func endpointWithoutUserInfo(endpoint string) (string, error) {
|
|
parsed, err := url.Parse(endpoint)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
parsed.User = nil
|
|
return parsed.String(), nil
|
|
}
|
|
|
|
func boolPointer(value bool) *bool { return &value }
|