134 lines
1.8 KiB
Go
134 lines
1.8 KiB
Go
package chain
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/go-gost/gost/pkg/bypass"
|
|
)
|
|
|
|
type Node struct {
|
|
name string
|
|
addr string
|
|
transport *Transport
|
|
bypass bypass.Bypass
|
|
marker *failMarker
|
|
}
|
|
|
|
func NewNode(name, addr string) *Node {
|
|
return &Node{
|
|
name: name,
|
|
addr: addr,
|
|
marker: &failMarker{},
|
|
}
|
|
}
|
|
|
|
func (node *Node) Name() string {
|
|
return node.name
|
|
}
|
|
|
|
func (node *Node) Addr() string {
|
|
return node.addr
|
|
}
|
|
|
|
func (node *Node) WithTransport(tr *Transport) *Node {
|
|
node.transport = tr
|
|
return node
|
|
}
|
|
|
|
func (node *Node) WithBypass(bp bypass.Bypass) *Node {
|
|
node.bypass = bp
|
|
return node
|
|
}
|
|
|
|
func (node *Node) Copy() *Node {
|
|
n := &Node{}
|
|
*n = *node
|
|
return n
|
|
}
|
|
|
|
type NodeGroup struct {
|
|
nodes []*Node
|
|
selector Selector
|
|
}
|
|
|
|
func NewNodeGroup(nodes ...*Node) *NodeGroup {
|
|
return &NodeGroup{
|
|
nodes: nodes,
|
|
}
|
|
}
|
|
|
|
func (g *NodeGroup) AddNode(node *Node) {
|
|
g.nodes = append(g.nodes, node)
|
|
}
|
|
|
|
func (g *NodeGroup) WithSelector(selector Selector) *NodeGroup {
|
|
g.selector = selector
|
|
return g
|
|
}
|
|
|
|
func (g *NodeGroup) Next() *Node {
|
|
if g == nil || len(g.nodes) == 0 {
|
|
return nil
|
|
}
|
|
|
|
selector := g.selector
|
|
if selector == nil {
|
|
return g.nodes[0]
|
|
}
|
|
|
|
return selector.Select(g.nodes...)
|
|
}
|
|
|
|
type failMarker struct {
|
|
failTime int64
|
|
failCount uint32
|
|
mux sync.RWMutex
|
|
}
|
|
|
|
func (m *failMarker) FailTime() int64 {
|
|
if m == nil {
|
|
return 0
|
|
}
|
|
|
|
m.mux.RLock()
|
|
defer m.mux.RUnlock()
|
|
|
|
return m.failTime
|
|
}
|
|
|
|
func (m *failMarker) FailCount() uint32 {
|
|
if m == nil {
|
|
return 0
|
|
}
|
|
|
|
m.mux.RLock()
|
|
defer m.mux.RUnlock()
|
|
|
|
return m.failCount
|
|
}
|
|
|
|
func (m *failMarker) Mark() {
|
|
if m == nil {
|
|
return
|
|
}
|
|
|
|
m.mux.Lock()
|
|
defer m.mux.Unlock()
|
|
|
|
m.failTime = time.Now().Unix()
|
|
m.failCount++
|
|
}
|
|
|
|
func (m *failMarker) Reset() {
|
|
if m == nil {
|
|
return
|
|
}
|
|
|
|
m.mux.Lock()
|
|
defer m.mux.Unlock()
|
|
|
|
m.failTime = 0
|
|
m.failCount = 0
|
|
}
|