fbox/node.go

101 lines
2.1 KiB
Go

package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"os"
"path/filepath"
shortuuid "github.com/lithammer/shortuuid/v3"
log "github.com/sirupsen/logrus"
)
var (
nodeID string
nodes map[string]Node
)
func init() {
nodes = make(map[string]Node)
}
type Node struct {
ID string
Addr string
}
func (n Node) String() string {
return fmt.Sprintf("Node{ID: %s Addr: %s}", n.ID, n.Addr)
}
func genNodeID(path string) (string, error) {
fn := filepath.Join(path, "id")
uuid := shortuuid.New()
if err := os.WriteFile(fn, []byte(uuid), 0644); err != nil {
log.WithError(err).Error("error writing node id")
return "", fmt.Errorf("error writing node id: %w", err)
}
return uuid, nil
}
func getNodeID(path string) (string, error) {
fn := filepath.Join(path, "id")
data, err := os.ReadFile(fn)
if err != nil {
log.WithError(err).Errorf("error reading node id: %s", fn)
return "", fmt.Errorf("error reading node id: %s", err)
}
return string(data), nil
}
func getNodeIds() []string {
var res []string
for k := range nodes {
res = append(res, k)
}
return res
}
// TODO: Add other node selection algorithms
// For example: affinity+random selection
func selectNode() Node {
keys := getNodeIds()
n := rand.Int() % len(keys)
key := keys[n]
return nodes[key]
}
func refreshNodes(addr string) error {
uri := fmt.Sprintf("http://%s/nodes", addr)
res, err := request(http.MethodGet, uri, nil, nil)
if err != nil {
log.WithError(err).Error("error making nodes request")
return fmt.Errorf("error nodes metadata request: %w", err)
}
if res.StatusCode != 200 {
log.WithField("Status", res.Status).Error("error making nodes request")
return fmt.Errorf("error making nodes request: %s", res.Status)
}
defer res.Body.Close()
data, err := ioutil.ReadAll(res.Body)
if err != nil {
log.WithError(err).Error("error reading nodes response")
return fmt.Errorf("error reading nodes response: %w", err)
}
if err := json.Unmarshal(data, &nodes); err != nil {
log.WithError(err).Error("error reading nodes response")
return fmt.Errorf("error reading nodes response: %w", err)
}
return nil
}