2016-05-14 43 views
1

使用卡桑德拉如下插入数据,我担心在IntializeCassandra初始化的东西不再在附近?插入卡桑德拉正在返回空指针错误

var csession gocql.Session 

func IntializeCassandra(){ 
    fmt.Println("Intializing Cassandra") 
    cluster := gocql.NewCluster("10.0.0.60") 
    cluster.Keyspace = "tickdata" 
    cluster.Consistency = gocql.Quorum 
    csession, _ := cluster.CreateSession() 
    defer csession.Close() 
} 

func main() { 
    IntializeCassandra() 
} 

在回调函数后来,当我尝试将数据插入卡珊德拉,我得到一个空指针错误

func msgHandler(src *net.UDPAddr, n int, b []byte) { 
    t := time.Now().UTC() 
    tformat := t.Format("2006-01-02 15:04:05") 
    md := &MarketData.MD{} 
    proto.Unmarshal(b[:n], md) 
    log.Printf("%d %d %d %d %s %.5f %.5f", md.Firm, md.Symbol, md.Expiry, md.Id, tformat, md.Bid, md.Ask) 
    if err := csession.Query(`INSERT INTO timeseries (firm, symbol, expiry, quote_id, time, bid, ask) VALUES (?, ?, ?, ?, ?, ?, ?)`, 
     md.Firm, md.Symbol, md.Expiry, md.Id, tformat, md.Bid, md.Ask).Exec(); err != nil { 
     log.Fatal(err) 
    } 


panic: runtime error: invalid memory address or nil pointer dereference 
[signal 0xb code=0x1 addr=0x0 pc=0x594687] 

回答

0

我不认为你想defer csession.Close()它在哪里。当IntializeCassandra即将返回时,将会调用csession.Close(),以便立即发生。

编辑:我只是意识到这是这个代码的另一个大问题。 csession, _ := cluster.CreateSession()会创建一个名为csession的局部变量,该变量会影响全局变量。您应该使用=而不是:=

+0

不,我想通了。由于某种原因,其他功能不会看到会议。所以我把主调内的csession,然后将指针作为参数传递给其他函数。 – Ivan

+0

'csession'应该在包装中的任何位置都可见。 –

0

代码有两个问题: 你应该在这里检查错误。如果失败,则不要继续

csession, err := cluster.CreateSession() 
if err != nil { 
    log.Fatal(err) 
} 

而且你不需要推迟session.Close()或session.Close(),因为它会作废并关闭连接。在从IntializeCassandra返回到main()的会话之后,在main中写入defer session.Close()。你也应该有一个叫做Csession的全局变量,可以在任何地方使用