Reputation: 9774
How do I send a message to a remote Elixir GenServer and then receive the results of the call using the C Erlang Interface?
I want to run something in C analogous to
{result1, result2} = GenServer.call(MyModule.NodeName, {:dothing, "blah"})
Here's what I have so far. It compiles and connects to the remote server and runs ei_reg_send
without causing an error, but the remote server doesn't receive a response. (I have a logger turned on so I know when the call comes through.)
#include <erl_interface.h>
#include <ei.h>
#define COOKIE "cookieval"
#define HOST "name@host"
int main() {
ei_init();
ei_cnode ec;
int n = 0;
int sockfd;
int self;
if((self = ei_connect_init(&ec, "nss", COOKIE, n++)) < 0) {
return 1;
}
if((sockfd = ei_connect(&ec, HOST)) < 0) {
return 2;
}
ei_x_buff request;
ei_x_new(&request);
ei_x_format(&request, "{dothing, ~a}", "blah");
if(ei_reg_send(&ec, sockfd, "MyModule.NodeName", request.buff, request.index) < 0) {
return 3;
}
ei_x_free(&request);
// code makes it to here, but there's no indication that the genserver was called
return 0;
}
Upvotes: 0
Views: 226
Reputation: 23556
You cannot do GenServer.call/2
in C Node. At least not directly, due to fact that this is not public API how the messages in that case look like (not that it changes a lot, but you cannot rely on that). Instead what you can do is that you send regular message and handle that within handle_info
.
Upvotes: 3
Reputation: 9774
Calling a GenServer with a predetermined name directly from C was, as pointed out, more difficult than expected. What I ended up doing was creating a module function in Elixir that called the GenServer itself and returned the results to the caller. Then I interfaced with this in C using RPC functions.
ei_x_buff request;
ei_x_new(&request);
ei_x_format_wo_ver(&request, "[~s]", "My Argument");
ei_x_buff response;
ei_x_new(&response);
ei_rpc(&ec, sockfd, "Elixir.MyModule", "dothing", request.buff, request.index, &response);
See http://erlang.org/doc/man/ei_connect.html#ei_rpc
Note that ei_rpc
doesn't return a "version magic number" in its response buffer but ei_rpc_from
does.
Upvotes: 0