mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 08:14:55 +08:00
fix(repo):统一发布健康与只读质量门禁
This commit is contained in:
@@ -55,17 +55,33 @@ type GameMainConfigSummary struct {
|
||||
DefaultConnectionGroup string `json:"default_connection_group,omitempty"`
|
||||
}
|
||||
|
||||
// DistributionHealth is the release-level authorization used by read paths.
|
||||
//
|
||||
// In RPC mode Ready is copied from Rust's release.status
|
||||
// official_distribution_ready fact. The local manifest checks only establish
|
||||
// that this process has a usable read snapshot; they do not replace Rust's
|
||||
// release verifier.
|
||||
type DistributionHealth struct {
|
||||
Ready bool `json:"ready"`
|
||||
Source string `json:"source"`
|
||||
Status string `json:"status,omitempty"`
|
||||
StatusCode string `json:"status_code,omitempty"`
|
||||
IntegrityStatus string `json:"integrity_status,omitempty"`
|
||||
Diagnostics []string `json:"diagnostics,omitempty"`
|
||||
}
|
||||
|
||||
// ReleaseIndex is the in-memory view of a published resource root.
|
||||
type ReleaseIndex struct {
|
||||
mu sync.RWMutex
|
||||
|
||||
ResourceRoot string `json:"resource_root"`
|
||||
Source string `json:"source"` // "rpc" | "resource_root" | "empty"
|
||||
RPCAvailable bool `json:"rpc_available"`
|
||||
DoctorHealthy *bool `json:"doctor_healthy,omitempty"`
|
||||
Snapshot *SnapshotSummary `json:"snapshot,omitempty"`
|
||||
ManifestVersion int `json:"manifest_version,omitempty"`
|
||||
Entries []ResourceEntry `json:"entries"`
|
||||
ResourceRoot string `json:"resource_root"`
|
||||
Source string `json:"source"` // "rpc" | "resource_root" | "empty"
|
||||
RPCAvailable bool `json:"rpc_available"`
|
||||
DoctorHealthy *bool `json:"doctor_healthy,omitempty"`
|
||||
Distribution DistributionHealth `json:"distribution"`
|
||||
Snapshot *SnapshotSummary `json:"snapshot,omitempty"`
|
||||
ManifestVersion int `json:"manifest_version,omitempty"`
|
||||
Entries []ResourceEntry `json:"entries"`
|
||||
// byRel maps relative path (host/path...) to entry index.
|
||||
byRel map[string]int
|
||||
// MissingOnDisk lists relative paths present in the index but absent on disk.
|
||||
@@ -74,16 +90,17 @@ type ReleaseIndex struct {
|
||||
|
||||
// Summary returns a JSON-serializable overview without the full entry list.
|
||||
type ReleaseSummary struct {
|
||||
ResourceRoot string `json:"resource_root"`
|
||||
Source string `json:"source"`
|
||||
RPCAvailable bool `json:"rpc_available"`
|
||||
DoctorHealthy *bool `json:"doctor_healthy,omitempty"`
|
||||
Snapshot *SnapshotSummary `json:"snapshot,omitempty"`
|
||||
ManifestVersion int `json:"manifest_version,omitempty"`
|
||||
EntryCount int `json:"entry_count"`
|
||||
PresentCount int `json:"present_count"`
|
||||
MissingCount int `json:"missing_count"`
|
||||
Ready bool `json:"ready"`
|
||||
ResourceRoot string `json:"resource_root"`
|
||||
Source string `json:"source"`
|
||||
RPCAvailable bool `json:"rpc_available"`
|
||||
DoctorHealthy *bool `json:"doctor_healthy,omitempty"`
|
||||
Distribution DistributionHealth `json:"distribution"`
|
||||
Snapshot *SnapshotSummary `json:"snapshot,omitempty"`
|
||||
ManifestVersion int `json:"manifest_version,omitempty"`
|
||||
EntryCount int `json:"entry_count"`
|
||||
PresentCount int `json:"present_count"`
|
||||
MissingCount int `json:"missing_count"`
|
||||
Ready bool `json:"ready"`
|
||||
}
|
||||
|
||||
// Summary builds a compact release overview.
|
||||
@@ -96,20 +113,32 @@ func (idx *ReleaseIndex) Summary() ReleaseSummary {
|
||||
present++
|
||||
}
|
||||
}
|
||||
distribution := idx.Distribution
|
||||
distribution.Diagnostics = append([]string(nil), idx.Distribution.Diagnostics...)
|
||||
localComplete := idx.ResourceRoot != "" && len(idx.Entries) > 0 && present == len(idx.Entries)
|
||||
// Hand-built indexes are retained for compatibility with local tests and
|
||||
// diagnostics. Any index explicitly sourced from RPC must carry the Rust
|
||||
// health fact; an RPC index without it is never considered distributable.
|
||||
if distribution.Source == "" {
|
||||
distribution.Ready = localComplete && idx.Source != "rpc" && idx.Source != "rpc+local_manifest"
|
||||
} else {
|
||||
distribution.Ready = distribution.Ready && localComplete
|
||||
}
|
||||
return ReleaseSummary{
|
||||
ResourceRoot: idx.ResourceRoot,
|
||||
Source: idx.Source,
|
||||
RPCAvailable: idx.RPCAvailable,
|
||||
DoctorHealthy: idx.DoctorHealthy,
|
||||
Distribution: distribution,
|
||||
Snapshot: idx.Snapshot,
|
||||
ManifestVersion: idx.ManifestVersion,
|
||||
EntryCount: len(idx.Entries),
|
||||
PresentCount: present,
|
||||
MissingCount: len(idx.MissingOnDisk),
|
||||
// A release is distributable only when every manifest entry is present
|
||||
// and has the expected size. Serving a partial release can leave clients
|
||||
// with an apparently valid bootstrap and an unrecoverable download set.
|
||||
Ready: idx.ResourceRoot != "" && len(idx.Entries) > 0 && present == len(idx.Entries),
|
||||
// A release is distributable only when Rust authorizes it and every
|
||||
// entry in this process's read snapshot is usable. Serving a partial
|
||||
// release can leave clients with an unrecoverable download set.
|
||||
Ready: distribution.Ready,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +187,7 @@ func BuildIndexFromManifestEntries(
|
||||
snapshot *SnapshotSummary,
|
||||
manifestVersion int,
|
||||
entries []manifestEntry,
|
||||
distribution DistributionHealth,
|
||||
) (*ReleaseIndex, error) {
|
||||
rootAbs, err := filepath.Abs(resourceRoot)
|
||||
if err != nil {
|
||||
@@ -168,7 +198,8 @@ func BuildIndexFromManifestEntries(
|
||||
Source: source,
|
||||
RPCAvailable: rpcAvailable,
|
||||
DoctorHealthy: doctorHealthy,
|
||||
Snapshot: snapshot,
|
||||
Distribution: distribution,
|
||||
Snapshot: snapshotWithDistributionHealth(snapshot, distribution),
|
||||
ManifestVersion: manifestVersion,
|
||||
byRel: make(map[string]int),
|
||||
}
|
||||
@@ -258,7 +289,21 @@ func LoadIndexFromResourceRoot(resourceRoot string) (*ReleaseIndex, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return BuildIndexFromManifestEntries(rootAbs, "resource_root", false, nil, snapshot, manifest.Version, entries)
|
||||
return BuildIndexFromManifestEntries(
|
||||
rootAbs,
|
||||
"resource_root",
|
||||
false,
|
||||
nil,
|
||||
snapshot,
|
||||
manifest.Version,
|
||||
entries,
|
||||
DistributionHealth{
|
||||
Ready: true,
|
||||
Source: "resource_root_override",
|
||||
Status: "ready",
|
||||
StatusCode: "resource_root.ready",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type manifestEntry struct {
|
||||
|
||||
Reference in New Issue
Block a user