feat(wip): sketch out the scheduling strategy
This commit is contained in:
@@ -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))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user