Home > Software engineering >  Go's garbage collector is deleting ZeroMQ sockets when in use
Go's garbage collector is deleting ZeroMQ sockets when in use

Time:01-31

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

CodePudding user response:

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.

  • Related