package master import ( "database/sql" "fmt" "sort" "git.wntrmute.dev/mc/mcp/internal/masterdb" ) // PickNode selects the best worker node for a new service deployment. // Algorithm: fewest placed services, ties broken alphabetically. func PickNode(db *sql.DB) (string, error) { workers, err := masterdb.ListWorkerNodes(db) if err != nil { return "", fmt.Errorf("list workers: %w", err) } if len(workers) == 0 { return "", fmt.Errorf("no worker nodes available") } counts, err := masterdb.CountPlacementsPerNode(db) if err != nil { return "", fmt.Errorf("count placements: %w", err) } // Sort: fewest placements first, then alphabetically. sort.Slice(workers, func(i, j int) bool { ci := counts[workers[i].Name] cj := counts[workers[j].Name] if ci != cj { return ci < cj } return workers[i].Name < workers[j].Name }) return workers[0].Name, nil } // FindMasterNode returns the name of the node with role "master". func FindMasterNode(db *sql.DB) (string, error) { nodes, err := masterdb.ListNodes(db) if err != nil { return "", fmt.Errorf("list nodes: %w", err) } for _, n := range nodes { if n.Role == "master" { return n.Name, nil } } return "", fmt.Errorf("no master node found") } // FindEdgeNode returns the name of the first edge node. func FindEdgeNode(db *sql.DB) (string, error) { edges, err := masterdb.ListEdgeNodes(db) if err != nil { return "", fmt.Errorf("list edge nodes: %w", err) } if len(edges) == 0 { return "", fmt.Errorf("no edge nodes available") } return edges[0].Name, nil }