samuel / go-zookeeper

Native ZooKeeper client for Go. This project is no longer maintained. Please use https://github.com/go-zookeeper/zk instead.
BSD 3-Clause "New" or "Revised" License
1.64k stars 672 forks source link

client cannot work when a server node in the cluster died #235

Open aluode99 opened 4 years ago

aluode99 commented 4 years ago

I use this client to connect to the cluster. When a server node in the cluster dies, the client cannot be used. However, if a multi-node zk cluster dies one node, the entire cluster can still provide services.

aluode99 commented 4 years ago

the code doesn't work as expected. if len(servers) == 0 { return nil, nil, errors.New("zk: server list must not be empty") }

srvs := make([]string, len(servers))

for i, addr := range servers {
    if strings.Contains(addr, ":") {
        srvs[i] = addr
    } else {
        srvs[i] = addr + ":" + strconv.Itoa(DefaultPort)
    }
}

// Randomize the order of the servers to avoid creating hotspots
stringShuffle(srvs)

ec := make(chan Event, eventChanSize)
conn := &Conn{
    dialer:         net.DialTimeout,
    hostProvider:   &DNSHostProvider{},
    conn:           nil,
    state:          StateDisconnected,
    eventChan:      ec,
    shouldQuit:     make(chan struct{}),
    connectTimeout: 1 * time.Second,
    sendChan:       make(chan *request, sendChanSize),
    requests:       make(map[int32]*request),
    watchers:       make(map[watchPathType][]chan Event),
    passwd:         emptyPassword,
    logger:         DefaultLogger,
    logInfo:        true, // default is true for backwards compatability
    buf:            make([]byte, bufferSize),
}

// Set provided options.
for _, option := range options {
    option(conn)
}

if err := conn.hostProvider.Init(srvs); err != nil {
    return nil, nil, err
}

conn.setTimeouts(int32(sessionTimeout / time.Millisecond))

go func() {
    conn.loop()
    conn.flushRequests(ErrClosing)
    conn.invalidateWatches(ErrClosing)
    close(conn.eventChan)
}()
return conn, ec, nil

}

the function stringShuffle has no ecffect.

func stringShuffle(s []string) { for i := len(s) - 1; i > 0; i-- { j := rand.Intn(i + 1) s[i], s[j] = s[j], s[i] } }