Golang等观察者恐慌

时间:2015-11-09 17:39:50

标签: go panic etcd

所有!

我的代码如下:

package main

import (
        "log"

        "github.com/coreos/go-etcd/etcd"
)

func main() {
        client := etcd.NewClient(
                []string{
                        "http://172.20.20.10:2379",
                        "http://172.20.20.11:2379",
                        "http://172.20.20.12:2379",
                },
        )
        for {
                watchChan := make(chan *etcd.Response)
                go client.Watch("/config", 0, false, watchChan, nil)

                log.Println("Waiting for an update...")
                r := <-watchChan

                log.Printf(">>> got an updated config: %s: %s\n", r.Node.Key, r.Node.Value)
        }
}

但是......当一些节点(例如172.20.20.11)发生故障时,恐慌就是抱怨无效的内存地址或无指针取消引用......

> $ ./etcd-watcher
2015/11/09 18:46:19 Waiting for an update...
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x10 pc=0x22fe]

goroutine 1 [running]:
main.main()
    /Users/Stalker/Workspace/src/snippets/etcd-watcher.go:26 +0x2be

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
     /Users/Stalker/App/Go/1.5.1/src/runtime/asm_amd64.s:1696 +0x1

goroutine 19 [runnable]:
net/http.(*persistConn).writeLoop(0xc8200c6dc0)
    /Users/Stalker/App/Go/1.5.1/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /Users/Stalker/App/Go/1.5.1/src/net/http/transport.go:686 +0xc9d

有人可以解释一下发生了什么,以及如何让这个简单的例子正常工作? 非常感谢您的建议! 亚历

1 个答案:

答案 0 :(得分:4)

图书馆可以关闭watchChan频道。这将在r中返回零值,然后在您尝试记录r.Node时发生混乱。 当你拿回指针时,你应该检查它不是nil。我还建议检查接收器通道是否已关闭并采取相应措施。

r, open := <-watchChan
if !open {
    // channel is closed
}
if r == nil {
   // the watch channel return a nil value
}