mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-07 00:37:36 +00:00
140 lines
3.9 KiB
Go
140 lines
3.9 KiB
Go
package monitoring
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/unifiedresources"
|
|
)
|
|
|
|
// MonitoredSystemUsageSnapshot describes whether the monitor can currently
|
|
// supply a canonical monitored-system count that is safe for billing and
|
|
// admission enforcement to consume.
|
|
type MonitoredSystemUsageSnapshot struct {
|
|
Count int
|
|
ReadState unifiedresources.ReadState
|
|
Available bool
|
|
UnavailableReason string
|
|
}
|
|
|
|
const (
|
|
MonitoredSystemUsageUnavailableMonitorState = "monitor_state_unavailable"
|
|
MonitoredSystemUsageUnavailableSupplementalInventoryUnsettled = "supplemental_inventory_unsettled"
|
|
MonitoredSystemUsageUnavailableSupplementalInventoryRebuildPending = "supplemental_inventory_rebuild_pending"
|
|
)
|
|
|
|
// MonitoredSystemUsage returns the canonical monitored-system count only when
|
|
// the current unified view is settled enough for billing boundaries. When
|
|
// supplemental provider-owned sources are still settling, the result fails
|
|
// closed with Available=false.
|
|
func (m *Monitor) MonitoredSystemUsage() MonitoredSystemUsageSnapshot {
|
|
if m == nil {
|
|
return MonitoredSystemUsageSnapshot{UnavailableReason: MonitoredSystemUsageUnavailableMonitorState}
|
|
}
|
|
|
|
readState := m.GetUnifiedReadStateOrSnapshot()
|
|
if readState == nil {
|
|
return MonitoredSystemUsageSnapshot{UnavailableReason: MonitoredSystemUsageUnavailableMonitorState}
|
|
}
|
|
|
|
orgID := normalizedMonitorUsageOrgID(m)
|
|
readyAt, settled := m.supplementalInventoryReadyAt(orgID)
|
|
if !settled {
|
|
return MonitoredSystemUsageSnapshot{
|
|
ReadState: readState,
|
|
UnavailableReason: MonitoredSystemUsageUnavailableSupplementalInventoryUnsettled,
|
|
}
|
|
}
|
|
if !readyAt.IsZero() {
|
|
freshness := m.currentUnifiedResourceFreshness()
|
|
if freshness.IsZero() || freshness.Before(readyAt) {
|
|
return MonitoredSystemUsageSnapshot{
|
|
ReadState: readState,
|
|
UnavailableReason: MonitoredSystemUsageUnavailableSupplementalInventoryRebuildPending,
|
|
}
|
|
}
|
|
}
|
|
|
|
return MonitoredSystemUsageSnapshot{
|
|
Count: unifiedresources.MonitoredSystemCount(readState),
|
|
ReadState: readState,
|
|
Available: true,
|
|
}
|
|
}
|
|
|
|
func normalizedMonitorUsageOrgID(m *Monitor) string {
|
|
if m == nil {
|
|
return "default"
|
|
}
|
|
orgID := strings.TrimSpace(m.GetOrgID())
|
|
if orgID == "" {
|
|
return "default"
|
|
}
|
|
return orgID
|
|
}
|
|
|
|
func (m *Monitor) supplementalInventoryReadyAt(orgID string) (time.Time, bool) {
|
|
providers := m.supplementalProviderSnapshot()
|
|
if len(providers) == 0 {
|
|
return time.Time{}, true
|
|
}
|
|
|
|
var watermark time.Time
|
|
for _, provider := range providers {
|
|
if provider == nil {
|
|
continue
|
|
}
|
|
|
|
readinessProvider, hasReadiness := provider.(MonitorSupplementalInventoryReadinessProvider)
|
|
if !hasReadiness {
|
|
if len(supplementalProviderOwnedSourcesForOrg(provider, orgID)) > 0 {
|
|
return time.Time{}, false
|
|
}
|
|
continue
|
|
}
|
|
|
|
readyAt, settled := readinessProvider.SupplementalInventoryReadyAt(m, orgID)
|
|
if !settled {
|
|
return time.Time{}, false
|
|
}
|
|
if readyAt.After(watermark) {
|
|
watermark = readyAt
|
|
}
|
|
}
|
|
|
|
return watermark, true
|
|
}
|
|
|
|
func supplementalProviderOwnedSourcesForOrg(
|
|
provider MonitorSupplementalRecordsProvider,
|
|
orgID string,
|
|
) []unifiedresources.DataSource {
|
|
if provider == nil {
|
|
return nil
|
|
}
|
|
|
|
var sources []unifiedresources.DataSource
|
|
if tenantOwner, ok := provider.(interface {
|
|
SnapshotOwnedSourcesForOrg(string) []unifiedresources.DataSource
|
|
}); ok {
|
|
sources = tenantOwner.SnapshotOwnedSourcesForOrg(orgID)
|
|
} else if owner, ok := provider.(interface {
|
|
SnapshotOwnedSources() []unifiedresources.DataSource
|
|
}); ok {
|
|
sources = owner.SnapshotOwnedSources()
|
|
}
|
|
|
|
if len(sources) == 0 {
|
|
return nil
|
|
}
|
|
|
|
out := make([]unifiedresources.DataSource, 0, len(sources))
|
|
for _, source := range sources {
|
|
normalized := unifiedresources.DataSource(strings.ToLower(strings.TrimSpace(string(source))))
|
|
if normalized == "" {
|
|
continue
|
|
}
|
|
out = append(out, normalized)
|
|
}
|
|
return out
|
|
}
|