package main

import (
    "math/rand"
    "net"
    "time"

    "stathat.com/c/consistent"
)

// 代理服务的结构
type BackendSvr struct {
    identify  string //代理服务器地址
    isLive    bool // 服务是否存活
    failTimes int  //失败次数
}

var (
    Consisthash *consistent.Consistent   //一致性哈希列表
    BackendSvrs map[string]*BackendSvr   //代理服务器map集合   key为服务器地址  value为代理服务器结构
)

// 初始化代理服务,加入一致性哈希列表,开始检测服务
func initBackendSvrs(serverList []string) {
    Consisthash = consistent.New()  //新建一致性哈希列表
    BackendSvrs = make(map[string]*BackendSvr)  //初始化代理服务器集合
    for _, server := range serverList {  
        Consisthash.Add(server)  //添加代理服务器地址到哈希列表
        BackendSvrs[server] = &BackendSvr{
            identify:  server,
            isLive:    true,
            failTimes: 0,
        }
    }
    go checkBackendSvrs() //检查代理服务器是否正常工作
}

// 根据客户端链接,从哈希集群中选择一台机器
func getBackendSvr(conn net.Conn) (*BackendSvr, bool) {
    remoteAddr := conn.RemoteAddr().String()
    identify, _ := Consisthash.Get(remoteAddr)
    BackendSvr, ok := BackendSvrs[identify]
    return BackendSvr, ok
}

// 代理服务检测存活
func checkBackendSvrs() {
    rand.Seed(time.Now().UnixNano())
    // 设置定时(每10s对服务进行检测)执行管道
    ticker := time.Tick(time.Duration(10) * time.Second)
    for _ = range ticker {
        for _, server := range BackendSvrs {
            if server.failTimes >= Config.FailOver && server.isLive == true {
                server.isLive = false
                Consisthash.Remove(server.identify) //从哈希列表中删除当前服务器地址
                              //是否需要这里同时删除 BackendSvrs 中 对应的当前代理服务器地址!!!!!!!!!!!!!!!!!!!
            }
        }
    }
}

// 设置定时器
func timer(input chan interface{}) {
    timerOne := time.NewTimer(time.Second * 5)
    timerTwo := time.NewTimer(time.Second * 10)
    for {
        select {
        case msg := <-input:
            println(msg)

        case <-timerOne.C:
            println("5s timer")
            timerOne.Reset(time.Second * 5)

        case <-timerTwo.C:
            println("10s timer")
            timerTwo.Reset(time.Second * 10)
        }
    }
}