diff --git a/lavalink.go b/lavalink.go index 576b06c..3762067 100644 --- a/lavalink.go +++ b/lavalink.go @@ -4,13 +4,14 @@ import ( "errors" "log" "os" + "sort" ) // Log sets the log.Logger gavalink will write to var Log *log.Logger func init() { - Log = log.New(os.Stdout, "(gavalink)", 0) + Log = log.New(os.Stdout, "(gavalink) ", 0) } // Lavalink manages a connection to Lavalink Nodes @@ -91,7 +92,11 @@ func (lavalink *Lavalink) BestNode() (*Node, error) { if len(lavalink.nodes) < 1 { return nil, errNoNodes } - // TODO: lookup latency + + sort.SliceStable(lavalink.nodes, func(i, j int) bool { + return lavalink.nodes[i].load < lavalink.nodes[j].load + }) + return &lavalink.nodes[0], nil } diff --git a/model.go b/model.go index e093d97..c1d6930 100644 --- a/model.go +++ b/model.go @@ -62,27 +62,29 @@ const ( opDestroy = "destroy" opPlayerUpdate = "playerUpdate" opEvent = "event" + opStats = "stats" eventTrackEnd = "TrackEndEvent" eventTrackException = "TrackExceptionEvent" eventTrackStuck = "TrackStuckEvent" ) type message struct { - Op string `json:"op"` - GuildID string `json:"guildId,omitempty"` - SessionID string `json:"sessionId,omitempty"` - Event *VoiceServerUpdate `json:"event,omitempty"` - Track string `json:"track,omitempty"` - StartTime string `json:"startTime,omitempty"` - EndTime string `json:"endTime,omitempty"` - Pause bool `json:"pause,omitempty"` - Position int `json:"position,omitempty"` - Volume int `json:"volume,omitempty"` - State *state `json:"state,omitempty"` - Type string `json:"type,omitempty"` - Reason string `json:"reason,omitempty"` - Error string `json:"error,omitempty"` - ThresholdMs int `json:"thresholdMs,omitempty"` + Op string `json:"op"` + GuildID string `json:"guildId,omitempty"` + SessionID string `json:"sessionId,omitempty"` + Event VoiceServerUpdate `json:"event,omitempty"` + Track string `json:"track,omitempty"` + StartTime string `json:"startTime,omitempty"` + EndTime string `json:"endTime,omitempty"` + Pause bool `json:"pause,omitempty"` + Position int `json:"position,omitempty"` + Volume int `json:"volume,omitempty"` + State state `json:"state,omitempty"` + Type string `json:"type,omitempty"` + Reason string `json:"reason,omitempty"` + Error string `json:"error,omitempty"` + ThresholdMs int `json:"thresholdMs,omitempty"` + StatCPU statCPU `json:"cpu,omitempty"` // TODO: stats } @@ -91,6 +93,10 @@ type state struct { Position int `json:"position"` } +type statCPU struct { + Load float32 `json:"lavalinkLoad"` +} + // VoiceServerUpdate is a raw Discord VOICE_SERVER_UPDATE event type VoiceServerUpdate struct { GuildID string `json:"guild_id"` diff --git a/node.go b/node.go index 1b5c8b1..44ee658 100644 --- a/node.go +++ b/node.go @@ -29,6 +29,7 @@ type NodeConfig struct { // Node wraps a Lavalink Node type Node struct { config NodeConfig + load float32 manager *Lavalink wsConn *websocket.Conn } @@ -84,8 +85,11 @@ func (node *Node) listen() { return } err = node.onEvent(msgType, msg) - // TODO: better error handling - Log.Println(err) + // TODO: better error handling? + + if err != nil { + Log.Println(err) + } } } @@ -124,6 +128,9 @@ func (node *Node) onEvent(msgType int, msg []byte) error { } return err + case opStats: + node.load = m.StatCPU.Load + Log.Println("dbg-node", node.config.WebSocket, "load", node.load) default: return errUnknownPayload } @@ -137,7 +144,7 @@ func (node *Node) CreatePlayer(guildID string, sessionID string, event VoiceServ Op: opVoiceUpdate, GuildID: guildID, SessionID: sessionID, - Event: &event, + Event: event, } data, err := json.Marshal(msg) if err != nil {