Implement node auto switching

This commit is contained in:
Tyler 2019-10-12 23:57:59 -04:00
parent a6ec9bedd2
commit ba383db391
3 changed files with 55 additions and 26 deletions

View File

@ -19,8 +19,10 @@ type Lavalink struct {
shards string shards string
userID string userID string
nodes []Node nodes []*Node
players map[string]*Player players map[string]*Player
BestNodeFunc func([]*Node) (*Node, error)
} }
var ( var (
@ -36,19 +38,20 @@ var (
// NewLavalink creates a new Lavalink manager // NewLavalink creates a new Lavalink manager
func NewLavalink(shards string, userID string) *Lavalink { func NewLavalink(shards string, userID string) *Lavalink {
return &Lavalink{ return &Lavalink{
shards: shards, shards: shards,
userID: userID, userID: userID,
/* nodes: make([]Node, 1),*/
players: make(map[string]*Player), players: make(map[string]*Player),
BestNodeFunc: BestNodeByLoad,
} }
} }
// AddNodes adds a node to the Lavalink manager // AddNodes adds a node to the Lavalink manager
func (lavalink *Lavalink) AddNodes(nodeConfigs ...NodeConfig) error { func (lavalink *Lavalink) AddNodes(nodeConfigs ...NodeConfig) error {
nodes := make([]Node, len(nodeConfigs)) nodes := make([]*Node, len(nodeConfigs))
for i, c := range nodeConfigs { for i, c := range nodeConfigs {
n := Node{ n := &Node{
config: c, config: c,
manager: lavalink, manager: lavalink,
} }
@ -71,7 +74,7 @@ func (lavalink *Lavalink) AddNodes(nodeConfigs ...NodeConfig) error {
func (lavalink *Lavalink) removeNode(node *Node) error { func (lavalink *Lavalink) removeNode(node *Node) error {
idx := -1 idx := -1
for i, n := range lavalink.nodes { for i, n := range lavalink.nodes {
if n == *node { if n == node {
idx = i idx = i
break break
} }
@ -82,6 +85,18 @@ func (lavalink *Lavalink) removeNode(node *Node) error {
node.stop() node.stop()
for _, player := range lavalink.players {
if player.node == node {
n, err := lavalink.BestNode()
if err != nil {
continue
}
player.ChangeNode(n)
}
}
// temp var for easier reading // temp var for easier reading
n := lavalink.nodes n := lavalink.nodes
z := len(n) - 1 z := len(n) - 1
@ -99,11 +114,7 @@ func (lavalink *Lavalink) BestNode() (*Node, error) {
return nil, errNoNodes return nil, errNoNodes
} }
sort.SliceStable(lavalink.nodes, func(i, j int) bool { return lavalink.BestNodeFunc(lavalink.nodes)
return lavalink.nodes[i].load < lavalink.nodes[j].load
})
return &lavalink.nodes[0], nil
} }
// GetPlayer gets a player for a guild // GetPlayer gets a player for a guild
@ -116,3 +127,11 @@ func (lavalink *Lavalink) GetPlayer(guild string) (*Player, error) {
return p, nil return p, nil
} }
func BestNodeByLoad(n []*Node) (*Node, error) {
sort.SliceStable(n, func(i, j int) bool {
return n[i].load < n[j].load
})
return n[0], nil
}

11
node.go
View File

@ -183,11 +183,12 @@ func (node *Node) CreatePlayer(guildID string, sessionID string, event VoiceServ
} }
player := &Player{ player := &Player{
guildID: guildID, guildID: guildID,
manager: node.manager, manager: node.manager,
node: node, node: node,
handler: handler, handler: handler,
vol: 100, vol: 100,
lastVoiceServerUpdate: event,
} }
node.manager.players[guildID] = player node.manager.players[guildID] = player

View File

@ -6,15 +6,16 @@ import (
// Player is a Lavalink player // Player is a Lavalink player
type Player struct { type Player struct {
guildID string guildID string
time int time int
position int position int
paused bool paused bool
vol int vol int
track string track string
manager *Lavalink manager *Lavalink
node *Node node *Node
handler EventHandler handler EventHandler
lastVoiceServerUpdate VoiceServerUpdate
} }
// GuildID returns this player's Guild ID // GuildID returns this player's Guild ID
@ -173,9 +174,17 @@ func (player *Player) Forward(sessionID string, event VoiceServerUpdate) error {
Event: &event, Event: &event,
} }
player.lastVoiceServerUpdate = event
return player.node.wsConn.WriteJSON(msg) return player.node.wsConn.WriteJSON(msg)
} }
func (player *Player) ChangeNode(node *Node) error {
player.node = node
return player.PlayAt(player.track, player.position, 0)
}
// Destroy will destroy this player // Destroy will destroy this player
func (player *Player) Destroy() error { func (player *Player) Destroy() error {
msg := basicMessage{ msg := basicMessage{