Search code examples
gorpc

Is it possible to send a function as response of RPC


I am trying to implement a server and multiple clients. Clients will register with server, and server should give a specific function to the clients to call. I do not want the specific function to be another rpc call. I am trying to make a distributed system for map reduce, where the function will be executed in client processes.

Is there a way to pass a function as response to remote procedure call in Go? Following is what i have tried:

In server :

type ResgisterResponse struct {
    Ack     bool
    MapFunc func()
}

func (a *API) RegisterWorker(addr string, reply *ResgisterResponse) error {
    a.worker[addr] = "idle" //idle, working, complete
    fmt.Printf("Wokers : %+v\n", a.worker)
    *reply = ResgisterResponse{
        Ack: true,
        MapFunc: func() {
            fmt.Println("Hello Worker")
        },
    }
    return nil
}

and in client :

var reply struct {
        Ack     bool
        MapFunc func()
    }
err = client.Call("API.RegisterWorker", getLocalAddr()+":"+localPort, &reply)
must(err)
fmt.Println("Worker registered")
reply.MapFunc()

I get nil pointer error for this ofcourse.

panic: runtime error: invalid memory address or nil pointer dereference

Solution

  • Sending plain functions over the network will not work because of the language design. In a single program you can pass functions as arguments because they are compiled in the same binary. In the server process you can fetch their address/reference since they are mapped in memory but when you send the function you actually send the pointer to it which is not a valid address in the client's memory (hence the invalid pointer error).

    To solve your problem I would go for the client registering a set of available functions with a server based on an id (could be a string mentioning the function name). The server will send back the function id in the Run RPC call and the client will select the function based on this id and run it

    There are also some experimental libraries that can evaluate Go code at runtime but I would not consider them safe. This is one example.