feat(wip): sketch out the scheduling strategy

This commit is contained in:
2026-06-10 22:51:28 +02:00
parent 1ff4446081
commit e9ff5ecf06
12 changed files with 271 additions and 47 deletions

View File

@@ -1,6 +1,7 @@
package main
import (
"fmt"
"io"
"log/slog"
"math"
@@ -18,6 +19,11 @@ type cpuHandler struct {
logger *slog.Logger
}
type memHandler struct {
amount int64
logger *slog.Logger
}
// readIntFromFile reads the given file until the end
// and converts the contained string into an integer
func readIntFromFile(path string) (int, error) {
@@ -28,6 +34,25 @@ func readIntFromFile(path string) (int, error) {
return strconv.Atoi(strings.TrimSpace(string(b)))
}
func readTotalMemoryKb() (int, error) {
b, err := os.ReadFile("/proc/meminfo")
if err != nil {
return 0, err
}
s := string(b)
for line := range strings.Lines(s) {
if !strings.Contains(line, "MemTotal:") {
continue
}
fields := strings.Fields(line)
if len(fields) < 2 {
return 0, fmt.Errorf("expected line '%s' to have at least 2 fields", line)
}
return strconv.Atoi(fields[1])
}
return 0, fmt.Errorf("failed to find MemTotal in /proc/meminfo")
}
func enumerateCPUCores(logger *slog.Logger) ([]string, int, int, error) {
files, err := os.ReadDir("/sys/devices/system/cpu/")
if err != nil {
@@ -135,6 +160,17 @@ func (s *cpuHandler) handleCurrent(w http.ResponseWriter, r *http.Request) {
}
}
func (s *cpuHandler) handleCount(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
s.logger.Error("unexepcted method for cpu count", "method", r.Method)
writeResponse("invalid method", http.StatusBadRequest, w, s.logger)
return
}
count := len(s.corePaths)
writeResponse(strconv.Itoa(count), http.StatusOK, w, s.logger)
}
func (s *cpuHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
requestedPath := getStrippedRequestPath(r.URL, r.Pattern)
switch requestedPath {
@@ -147,12 +183,25 @@ func (s *cpuHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
case "frequency/current":
s.handleCurrent(w, r)
return
case "count":
s.handleCount(w, r)
return
default:
s.logger.Error("unknown resource", "path", requestedPath)
writeResponse("not found", http.StatusNotFound, w, s.logger)
}
}
func (m *memHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
requestedPath := getStrippedRequestPath(r.URL, r.Pattern)
if requestedPath == "amount" {
writeResponse(strconv.FormatInt(m.amount, 10), http.StatusOK, w, m.logger)
} else {
m.logger.Error("unknown resource", "path", requestedPath)
writeResponse("not found", http.StatusNotFound, w, m.logger)
}
}
func main() {
appEnv := os.Getenv("AGENT_ENV")
loggerOpts := &slog.HandlerOptions{
@@ -176,6 +225,18 @@ func main() {
minFreq: minF,
corePaths: freqPaths,
}
memKb, err := readTotalMemoryKb()
if err != nil {
logger.Error("failed to read memory size", "err", err.Error())
os.Exit(1)
}
memHandler := &memHandler{
amount: int64(memKb) * 1024,
logger: logger,
}
http.Handle("/cpu/", logRequests(logger, cpuHandler))
http.Handle("/mem/", logRequests(logger, memHandler))
logger.Info("exit", "result", http.ListenAndServe(":8080", nil))
}