package host import ( "strconv" "strings" "github.com/carlosframework/platform/internal/registry" ) // headroomFor is the reading the edges loop publishes: nil unless the box // has the region-HA capability. A box that publishes headroom is rewritten // on every timed pass, so a one-box region (flag off) must not carry one. func headroomFor(caps []string, dataDir string, reg *registry.Registry) *edgeHeadroom { if len(caps) == 0 { return nil } h := readHeadroom(dataDir, awakeCount(reg)) h.MemTotalMiB, h.DiskTotalMiB = capacityMiB(readMemBytes, func() (uint64, uint64, error) { return diskBytes(dataDir) }) return h } // capacityMiB is the box's total memory and its data volume's size, in // MiB: the totals region HA spec 2's placement policy judges the free // figures against (ยง7). A reading that fails is 0, which the policy reads // as a box it cannot judge, and so does not place on. func capacityMiB(mem func() (total, avail *int64), disk func() (total, avail uint64, err error)) (memMiB, diskMiB int64) { if total, _ := mem(); total != nil && *total > 0 { memMiB = *total / (1 << 20) } if total, _, err := disk(); err == nil { diskMiB = int64(total / (1 << 20)) } return memMiB, diskMiB } // parseMemAvailableMiB returns the MemAvailable line in MiB, or 0. func parseMemAvailableMiB(meminfo string) int64 { for _, line := range strings.Split(meminfo, "\n") { rest, ok := strings.CutPrefix(line, "MemAvailable:") if !ok { continue } fields := strings.Fields(rest) if len(fields) == 0 { return 0 } kb, err := strconv.ParseInt(fields[0], 10, 64) if err != nil { return 0 } return kb / 1024 } return 0 }