2016-05-14 58 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的全局變量,可以在任何地方使用