Reputation: 1647
I am writing Elixir to get record from remote nodes, I have write a module,
defmodule Connect do
def connect do
node_ap_dev_ejd = :'[email protected]'
:net_adm.ping(node_ap)
fbUsersFun = fn(x) -> :binary.part(x,{0,3}) == <<"*ab">> end
f = fn()-> :mnesia.dirty_select(:'cz_map',[{{:cz_map, :'$1', :'_',:'_',:'_'},[],[:'$1']}]) end
fbUserList = :rpc.call(node_ap_dev_ejd,:mnesia,:activity,[:async_dirty,f])
list = Enum.filter(fbUserList ,fbUsersFun)
length(list)
end
end
I can run the code if I put it in iex shell line by line, however if I compile the code and run Connect.connect , this error appear, I have no idea of it, please suggest
** (Protocol.UndefinedError) protocol Enumerable not implemented for
{:badrpc, {:EXIT, {:undef, [{#Function<1.96315226/0 in Connect.connect/0>, [], []}, {:mnesia_tm, :non_transaction, 5, [file: 'mnesia_tm.erl', line: 738]}]}}}
(elixir) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) lib/enum.ex:112: Enumerable.reduce/3
(elixir) lib/enum.ex:666: Enum.filter/2
second_function.ex:10: Connect.connect/0
Upvotes: 1
Views: 560
Reputation: 115
I'm having the same issue working mnesia with erlang, the error is because of the anonymous function "f", the thing is that the remote node does not recognize that function because it was created in another node.
EDIT:
I managed to solve the problem in erlang, I will show you how I did it in erlang, I don't know much about elixir but I´m sure if it can be done in erlang it will in elixir.
So this segment
f = fn()-> :mnesia.dirty_select(:'cz_map',[{{:cz_map, :'$1', :'_',:'_',:'_'},[],[:'$1']}]) end
fbUserList = :rpc.call(node_ap_dev_ejd,:mnesia,:activity,[:async_dirty,f])
In erlang is like this
f = fun()-> mnesia:dirty_select(cz_map,[{{cz_map, '$1', '_', '_', '_'},[],['$1']}]) end,
fbUserList = rpc:call(node_ap_dev_ejd, mnesia, activity, [async_dirty, f])
Instead declaring an anonymous fun you have to do something like this
fbUserList = rpc:call(node_ap_dev_ejd, mnesia, activity, [async_dirty, mnesia:dirty_select/2, [cz_map, [{{cz_map, '$1', '_', '_', '_'},[],['$1']}]]])
You can find a clear explanation here what kind of types can be sent on an erlang message?
I hope this information helps you.
Upvotes: 0
Reputation: 16781
It means that the Enumerable
protocol is not implemented for the data {:badrpc, ...}
.
Most likely, that error comes from this line:
list = Enum.filter(fbUserList ,fbUsersFun)
In that line, you're trying to filter fbUserList
which I guess is {:badrpc, ...}
instead of an enumerable. Tuples are not enumerables; lists and maps (and other things) are.
The solution probably lies in a case
expression which checks the result returned by :rpc.call/4
in order to defend from errors:
case :rpc.call(node_ap_dev_ejd, :mnesia, :activity, [:async_dirty, f]) do
{:badrpc, _} -> raise "bad rpc error"
fbUserList -> Enum.filter(fbUserList, ...) # and so on
end
Upvotes: 2