英文:
Go's garbage collector is deleting ZeroMQ sockets when in use
问题
我正在使用ZeroMQ和Go开发一个分布式系统。它类似于一个分布式账本,可以获取内容并进行追加。我有自动化客户端发送GET和ADD请求。程序在运行几秒钟后会崩溃,并显示错误信息"panic: socket operation on non-socket"。
我尝试使用debug.SetGCPercent(-1)关闭垃圾回收器,但我确定这个解决方案并不完全正确。
这是服务器初始化的代码:
package server
import (
"backend/config"
"backend/gset"
"backend/tools"
zmq "github.com/pebbe/zmq4"
)
type Server struct {
Zctx *zmq.Context
Peers map[string]*zmq.Socket
Receive_socket zmq.Socket
Id string
Gset map[string]string
Port string
My_init map[string]bool
My_echo map[string]bool
My_vote map[string]bool
Peers_echo map[string]bool
Peers_vote map[string]bool
}
func CreateServer(node config.Node, peers []config.Node, zctx *zmq.Context) *Server {
id := node.Host + node.Port
port := node.Port
server_sockets := make(map[string]*zmq.Socket)
my_gset := gset.Create()
my_init := make(map[string]bool)
my_echo := make(map[string]bool)
my_vote := make(map[string]bool)
peers_echo := make(map[string]bool)
peers_vote := make(map[string]bool)
receive_socket, _ := zctx.NewSocket(zmq.ROUTER)
receive_socket.Bind("tcp://*:" + node.Port)
tools.Log(id, "Bound tcp://*:"+node.Port)
// Connect my dealer sockets to all other servers' router
for i := 0; i < len(peers); i++ {
s, _ := zctx.NewSocket(zmq.DEALER)
s.SetIdentity(id)
s.Connect("tcp://localhost:" + peers[i].Port)
// append socket to socket list
server_sockets["tcp://localhost:"+peers[i].Port] = s
}
return &Server{
Peers: server_sockets,
Receive_socket: *receive_socket,
Id: id,
Port: port,
Gset: my_gset,
My_init: my_init,
My_echo: my_echo,
My_vote: my_vote,
Peers_echo: peers_echo,
Peers_vote: peers_vote,
}
}
这是控制服务器的函数:
func Normal_listener_task(s *server.Server) {
for {
message, err := s.Receive_socket.RecvMessage(0)
if err != nil {
fmt.Println(zmq.AsErrno(err))
panic(err)
}
messaging.HandleMessage(s, message)
}
}
完整的代码在我的GitHub上这里。
如果有人知道为什么会出现这种情况,你将拯救我的论文。谢谢!
英文:
I am developing a distributed system uisng ZeroMQ and Go. It's like a distributed ledger so you can get the contects and append. I have automated clients making GET and ADD requests. The program runs fine for a couple of seconds but then crashes with the error "panic: socket operation on non-socket".
I tried turning off the garbage collector using debug.SetGCPercent(-1) but im sure this solution is not entirely correct.
This is the server initialization code
package server
import (
"backend/config"
"backend/gset"
"backend/tools"
zmq "github.com/pebbe/zmq4"
)
type Server struct {
Zctx *zmq.Context
Peers map[string]*zmq.Socket
Receive_socket zmq.Socket
Id string
Gset map[string]string
Port string
My_init map[string]bool
My_echo map[string]bool
My_vote map[string]bool
Peers_echo map[string]bool
Peers_vote map[string]bool
}
func CreateServer(node config.Node, peers []config.Node, zctx *zmq.Context) *Server {
id := node.Host + node.Port
port := node.Port
server_sockets := make(map[string]*zmq.Socket)
my_gset := gset.Create()
my_init := make(map[string]bool)
my_echo := make(map[string]bool)
my_vote := make(map[string]bool)
peers_echo := make(map[string]bool)
peers_vote := make(map[string]bool)
receive_socket, _ := zctx.NewSocket(zmq.ROUTER)
receive_socket.Bind("tcp://*:" + node.Port)
tools.Log(id, "Bound tcp://*:"+node.Port)
// Connect my dealer sockets to all other servers' router
for i := 0; i < len(peers); i++ {
s, _ := zctx.NewSocket(zmq.DEALER)
s.SetIdentity(id)
s.Connect("tcp://localhost:" + peers[i].Port)
// append socket to socket list
server_sockets["tcp://localhost:"+peers[i].Port] = s
}
return &Server{
Peers: server_sockets,
Receive_socket: *receive_socket,
Id: id,
Port: port,
Gset: my_gset,
My_init: my_init,
My_echo: my_echo,
My_vote: my_vote,
Peers_echo: peers_echo,
Peers_vote: peers_vote,
}
}
And this is the function that contols the server
func Normal_listener_task(s *server.Server) {
for {
message, err := s.Receive_socket.RecvMessage(0)
if err != nil {
fmt.Println(zmq.AsErrno(err))
panic(err)
}
messaging.HandleMessage(s, message)
}
}
The entire code is in my github here
If anyone knows why this is happening you will save my thesis. Thank you
答案1
得分: 2
问题是我在声明receive_socket
时使用了Receive_socket zmq.Socket
,而实际上应该是*Receive_socket zmq.Socket
。指针只是一个副本,因此被垃圾回收器视为垃圾。
英文:
The problem was that I was declaring the receive_socket with Receive_socket zmq.Socket
when it should have been *Receive_socket zmq.Socket
. The pointer was just a copy, therefore being considered trash by the GC.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论