Home  >  Article  >  Backend Development  >  Go's garbage collector deletes ZeroMQ sockets when in use

Go's garbage collector deletes ZeroMQ sockets when in use

WBOY
WBOYforward
2024-02-05 21:30:08962browse

Go 的垃圾收集器在使用时删除 ZeroMQ 套接字

Question content

I am developing a distributed system using zeromq and go. It's like a distributed ledger, so you can take content and append to it. I have clients that automatically make get and add requests. The program runs fine for a few seconds, but then crashes with the error "panic: Socket operation on non-socket".

I tried using debug.setgcpercent(-1) to turn off the garbage collector, but I'm sure this solution isn't 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,
    }
}

This is the function that controls 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

If anyone knows why this is happening, you will save my paper. Thank you


Correct answer


The problem is that I declared receive_socket with Receive_socket zmq.Socket, but it should be *Receive_socket zmq .Socket. The pointer is just a copy and therefore considered garbage by the GC.

The above is the detailed content of Go's garbage collector deletes ZeroMQ sockets when in use. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete