Star

go客户端连接池报错

package main

import (
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"github.com/vesoft-inc/nebula-go/examples/connpool"
	"log"
	"net/http"
)

const (
	userName = "admin"
	password = "password"
	ip = "xxx.xxx.xxx.xxx"
	port = 3699
	dbName = "xxxxx"
	size = 3
)
func DBPool()(connpool.ConnectionPool, error){
	pool, err := connpool.New(size,
		connpool.Connection{
			Ip:       ip,
			Port:     port,
			User:     userName,
			Password: password,
		},
		connpool.SpaceDesc{
			Name:          dbName,
			Exists:        false,
			NumPartitions: 10,
			ReplicaFactor: 1,
			Charset:       "utf8",
			Collate:       "utf8_bin",
		},
	)
	return pool, err
}

func main() {
	// Echo instance
	e := echo.New()
	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())
	//定义post请求, url为:/tactics, 绑定saveTactic控制器函数
	//e.POST("/tactics", saveTactic)
	//定义get请求,url模式为:/tactics/:id  (:id是参数,例如: /tactics/10, 会匹配这个url模式),绑定getTactic控制器函数
	//pool.Execute("drop tag hadi")
	e.GET("/tactics/:id", getTactic)
	e.Logger.Fatal(e.Start(":1323"))
}

func getTactic(c echo.Context) error {
	pool, err :=DBPool()
	// 获取url上的path参数,url模式里面定义了参数:id
	id := c.Param("id")
	if err != nil {
		log.Fatal(err)
	}
	defer pool.Close()
	pool.Execute("create tag hadi33(name string)")
	//响应一个字符串,这里直接把id以字符串的形式返回给客户端。
	return c.String(http.StatusOK, id)
}

报错误如下:

panic: runtime error: invalid memory address or nil pointer dereference
        panic: send on closed channel
[signal 0xc0000005 code=0x0 addr=0x50 pc=0x82b826]

goroutine 9 [running]:
github.com/vesoft-inc/nebula-go/examples/connpool.(*SimpleConnectionPool).start.func1.1(0xc0000881b0, 0x0)
        C:/Users/admin/go/pkg/mod/github.com/vesoft-inc/nebula-go@v1.0.1-0.20200917082518-10778ef6a6cf/examples/connpool/simpleconnpool.go:79 +0x4a
panic(0x86a880, 0xaf0f80)
        C:/Go/src/runtime/panic.go:969 +0x176
github.com/vesoft-inc/nebula-go.(*GraphClient).Execute(...)
        C:/Users/admin/go/pkg/mod/github.com/vesoft-inc/nebula-go@v1.0.1-0.20200917082518-10778ef6a6cf/client.go:99
github.com/vesoft-inc/nebula-go/examples/connpool.(*SimpleConnectionPool).start.func1(0xc0000881b0, 0x0, 0x0, 0x0, 0x0)
        C:/Users/admin/go/pkg/mod/github.com/vesoft-inc/nebula-go@v1.0.1-0.20200917082518-10778ef6a6cf/examples/connpool/simpleconnpool.go:81 +0x66
created by github.com/vesoft-inc/nebula-go/examples/connpool.(*SimpleConnectionPool).start
        C:/Users/admin/go/pkg/mod/github.com/vesoft-inc/nebula-go@v1.0.1-0.20200917082518-10778ef6a6cf/examples/connpool/simpleconnpool.go:76 +0xe8
exit status 2

原因是与关闭连接有关,如果去掉defer pool.Close(),则可以正常执行结果。但是连接应该在何处关闭呢?预格式化文本

看你直接使用的 example 中的 connpool, 这个连接池还比较初级,当初的实现目标仅是为了 demo,后面我们规划了更完善的 connection pool 的实现,会随着 2.0 的版本一起发布。

这里的问题是,pool.Execute(…) 之后你没有对 response 做等待处理,直接返回(随之关闭 pool),因为 pool 中的 graph 的 client 处理请求是异步的,所以,在你调用 Execute 之后会立马返回,但实际的执行结果还没有回来,所以你要在外面阻塞等待一下 response,然后才能 Close,不然 response 的 channel 被关闭了,返回数据再往 channel 去写的时候就会抛你上面的错误了。

具体的处理逻辑可以参考示例代码

浙ICP备20010487号