123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- package xorm
- import (
- "math/rand"
- "sync"
- "time"
- )
- type GroupPolicy interface {
- Slave(*EngineGroup) *Engine
- }
- type GroupPolicyHandler func(*EngineGroup) *Engine
- func (h GroupPolicyHandler) Slave(eg *EngineGroup) *Engine {
- return h(eg)
- }
- func RandomPolicy() GroupPolicyHandler {
- var r = rand.New(rand.NewSource(time.Now().UnixNano()))
- return func(g *EngineGroup) *Engine {
- return g.Slaves()[r.Intn(len(g.Slaves()))]
- }
- }
- func WeightRandomPolicy(weights []int) GroupPolicyHandler {
- var rands = make([]int, 0, len(weights))
- for i := 0; i < len(weights); i++ {
- for n := 0; n < weights[i]; n++ {
- rands = append(rands, i)
- }
- }
- var r = rand.New(rand.NewSource(time.Now().UnixNano()))
- return func(g *EngineGroup) *Engine {
- var slaves = g.Slaves()
- idx := rands[r.Intn(len(rands))]
- if idx >= len(slaves) {
- idx = len(slaves) - 1
- }
- return slaves[idx]
- }
- }
- func RoundRobinPolicy() GroupPolicyHandler {
- var pos = -1
- var lock sync.Mutex
- return func(g *EngineGroup) *Engine {
- var slaves = g.Slaves()
- lock.Lock()
- defer lock.Unlock()
- pos++
- if pos >= len(slaves) {
- pos = 0
- }
- return slaves[pos]
- }
- }
- func WeightRoundRobinPolicy(weights []int) GroupPolicyHandler {
- var rands = make([]int, 0, len(weights))
- for i := 0; i < len(weights); i++ {
- for n := 0; n < weights[i]; n++ {
- rands = append(rands, i)
- }
- }
- var pos = -1
- var lock sync.Mutex
- return func(g *EngineGroup) *Engine {
- var slaves = g.Slaves()
- lock.Lock()
- defer lock.Unlock()
- pos++
- if pos >= len(rands) {
- pos = 0
- }
- idx := rands[pos]
- if idx >= len(slaves) {
- idx = len(slaves) - 1
- }
- return slaves[idx]
- }
- }
- func LeastConnPolicy() GroupPolicyHandler {
- return func(g *EngineGroup) *Engine {
- var slaves = g.Slaves()
- connections := 0
- idx := 0
- for i := 0; i < len(slaves); i++ {
- openConnections := slaves[i].DB().Stats().OpenConnections
- if i == 0 {
- connections = openConnections
- idx = i
- } else if openConnections <= connections {
- connections = openConnections
- idx = i
- }
- }
- return slaves[idx]
- }
- }
|