天天看點

Go語言:samuel的go-zookeeper用戶端監測連接配接是否已建立

 samuel的zk用戶端在建立連接配接時,會傳回3個參數,其中第二個參數可用于檢測連接配接的建立狀态,僅當state等于StateHasSession時,用戶端才是可用的。

func Connect(servers []string, sessionTimeout time.Duration, options ...connOption) (*Conn, <-chan Event, error)
           

type State

type State int32
           
const (
    StateUnknown           State = -1
    StateDisconnected      State = 0
    StateConnecting        State = 1
    StateAuthFailed        State = 4
    StateConnectedReadOnly State = 5
    StateSaslAuthenticated State = 6
    StateExpired           State = -112

    StateConnected  = State(100)
    StateHasSession = State(101)
)
           

網上的示例通常忽略第二個參數,但是因為zk用戶端内部會另起一個goroutine去建立連接配接,是以當Connect傳回時連接配接并沒有建立成功,這裡傳回的error為空也不代表連接配接已經建立。而有些應用場合需要确定連接配接是否已成功建立,例如在下面的一個zk查詢用戶端程式中,需要等待連接配接建立成功之後才向終端輸出指令提示符“>”。

package main

import (
        "fmt"
        "github.com/samuel/go-zookeeper/zk"
        "log"
        "time"
)

func main() {
        var err error
        var conn *zk.Conn
        var evtchan <-chan zk.Event
        var evt zk.Event

        conn, evtchan, err = zk.Connect([]string{"127.0.0.1:2181"},
                time.Second*5,
                zk.WithLogInfo(false),
        )
        if err != nil {
                log.Fatalf("zk connect error:%v\n", err.Error())
                return
        }

        log.Printf("=====>  before loop check  <=======")
        //check the zkclient's state until it's the state of "StateHasSession"
        for {
                evt = <-evtchan
                log.Printf("zk event:%s %s\n", evt.Type, evt.State)
                if evt.State == zk.StateHasSession {
                        break
                }
        }

        for {
                var children []string
                var cmdstr string

                fmt.Print(">")
                fmt.Scanln(&cmdstr)
                fmt.Printf("%s\n", cmdstr)
                children, _, err = conn.Children(cmdstr)
                if err != nil {
                        fmt.Printf("%v\n", err.Error())
                        continue
                }
                for index, child := range children {
                        fmt.Printf("[%d]%s\n", index, child)
                }
                var byteArr []byte
                byteArr, _, err = conn.Get(cmdstr)
                if err != nil {
                        fmt.Printf("%v\n", err.Error())
                        continue
                }

                fmt.Printf("%s\n", string(byteArr))
        }
}
           

 可以看到,zk的整個連接配接建立過程是在列印"before loop check"之後執行的,而當用戶端達到“StateHasSession”狀态後,才輸出指令提示符“>”,等待輸入指令。

[[email protected] hippo]# go run example.go
2020/11/03 23:24:11 =====>  before loop check  <=======
2020/11/03 23:24:11 zk event:EventSession StateConnecting
2020/11/03 23:24:11 zk event:EventSession StateConnected
2020/11/03 23:24:11 zk event:EventSession StateHasSession
>