fix(bat-api): 完成 issue #19 同机 live 联调
bat-rust / Build and test Go API (push) Canceled after 0s
bat-rust / Build and test Rust (push) Canceled after 0s

This commit is contained in:
2026-08-29 22:58:01 +08:00
parent 90083302a2
commit 7f465523e1
22 changed files with 819 additions and 115 deletions
+63
View File
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"bat-api/internal/backendrpc"
@@ -206,16 +207,22 @@ func DiscoverAndIndex(ctx context.Context, backend Backend, resourceRootOverride
// Catalog / resource discovery
var snapshot *SnapshotSummary
var resourceRoot string
catalogAvailabilityKnown := false
catalogAvailable := false
if raw, err := backend.CatalogStatus(ctx); err != nil {
out.Warnings = append(out.Warnings, fmt.Sprintf("catalog.status: %v", err))
} else {
catalogAvailable, catalogAvailabilityKnown = parseCatalogAvailability(raw)
snap, root, ok := parseCatalogStatus(raw)
if ok {
snapshot = snap
resourceRoot = root
}
}
if catalogAvailabilityKnown && !catalogAvailable {
return emptyRPCResult(out, snapshot, "catalog.status available=false; no published release"), nil
}
if resourceRoot == "" {
if state, err := backend.ResourceState(ctx); err != nil {
@@ -243,12 +250,32 @@ func DiscoverAndIndex(ctx context.Context, backend Backend, resourceRootOverride
return out, nil
}
if resourceRootOverride == "" {
info, statErr := os.Stat(resourceRoot)
if statErr != nil || !info.IsDir() {
warning := fmt.Sprintf("published resource root is unavailable: %s", resourceRoot)
if statErr != nil {
warning = fmt.Sprintf("%s (%v)", warning, statErr)
} else {
warning = fmt.Sprintf("%s (not a directory)", warning)
}
return emptyRPCResult(out, snapshot, warning), nil
}
}
entries, manifestVersion, rootFromManifest, err := fetchAllManifestEntries(ctx, backend)
if err != nil {
out.Warnings = append(out.Warnings, fmt.Sprintf("resource.manifest: %v", err))
// Fallback: load local manifest file under root.
idx, loadErr := LoadIndexFromResourceRoot(resourceRoot)
if loadErr != nil {
if resourceRootOverride == "" {
return emptyRPCResult(
out,
snapshot,
fmt.Sprintf("published release cannot be indexed: %v", loadErr),
), nil
}
return out, fmt.Errorf("manifest RPC and local load failed: rpc=%v local=%w", err, loadErr)
}
idx.Source = "rpc+local_manifest"
@@ -279,6 +306,13 @@ func DiscoverAndIndex(ctx context.Context, backend Backend, resourceRootOverride
entries,
)
if err != nil {
if resourceRootOverride == "" {
return emptyRPCResult(
out,
snapshot,
fmt.Sprintf("published release failed local validation: %v", err),
), nil
}
return out, err
}
out.ResourceRoot = idx.ResourceRoot
@@ -287,6 +321,22 @@ func DiscoverAndIndex(ctx context.Context, backend Backend, resourceRootOverride
return out, nil
}
func emptyRPCResult(out *DiscoverResult, snapshot *SnapshotSummary, warning string) *DiscoverResult {
out.ResourceRoot = ""
out.Snapshot = snapshot
out.Index = &ReleaseIndex{
Source: "rpc",
RPCAvailable: true,
DoctorHealthy: out.DoctorHealthy,
Snapshot: snapshot,
byRel: map[string]int{},
}
if warning != "" {
out.Warnings = append(out.Warnings, warning)
}
return out
}
func parseCatalogStatus(raw json.RawMessage) (*SnapshotSummary, string, bool) {
if len(raw) == 0 || string(raw) == "null" {
return nil, "", false
@@ -333,6 +383,19 @@ func parseCatalogStatus(raw json.RawMessage) (*SnapshotSummary, string, bool) {
return snap, root, true
}
func parseCatalogAvailability(raw json.RawMessage) (bool, bool) {
if len(raw) == 0 || string(raw) == "null" {
return false, false
}
var payload struct {
Available *bool `json:"available"`
}
if err := json.Unmarshal(raw, &payload); err != nil || payload.Available == nil {
return false, false
}
return *payload.Available, true
}
func fetchAllManifestEntries(ctx context.Context, backend Backend) ([]manifestEntry, int, string, error) {
const pageSize = 500
offset := 0