I am setting up an ejabbered + riak cluster, where i have to use basic riak (get,put,delete..)functions in the file ejabberd/src/ejabberd_riak.erl
The functions put, get, get_by_index etc. work great and using the usage of the module in the file I could figure out what is what.
I'm facing an issue with the function delete_by_index and also get_keys_by_index, which is called by delete_by_index, anyhow.
The error thrown when I do this ->
ejabberd_riak:get_keys_by_index(game <<"language">>,
term_to_binary("English")).
{error,<<"Phase 0: invalid module named in PhaseSpec function:\n must be a valid module name (failed to load ejabberd_r"...>>}
(ejabberd@172.43.12.133)57> 12:28:55.177 [error] database error:
** Function: get_keys_by_index
** Table: game
** Index = <<"language">>
** Key: <<131,107,0,7,69,110,103,108,105,115,104>>
** Error: Phase 0: invalid module named in PhaseSpec function:
must be a valid module name (failed to load ejabberd_riak: nofile)
ejabberd_riak
on the riak sideYou are currently using riak as separate erlang application, communicating with the database by protobuf. In this configuration you have independent (from each other) module sets loaded in ejabbered and riak applications. ejabberd_riak
module loaded in ejabberd application, but not in riak application.
However get_by_index
uses mapred that demands ejabberd_riak loaded on the riak side
-spec get_keys_by_index(atom(), binary(),
any()) -> {ok, [any()]} | {error, any()}.
%% @doc Returns a list of primary keys of objects indexed by `Key'.
get_keys_by_index(Table, Index, Key) ->
{NewIndex, NewKey} = encode_index_key(Index, Key),
Bucket = make_bucket(Table),
case catch riakc_pb_socket:mapred(
get_random_pid(),
{index, Bucket, NewIndex, NewKey},
[{map, {modfun, ?MODULE, map_key}, none, true}]) of
%% ^^^^^^
%% here is the problem
{ok, [{_, Keys}]} ->
{ok, Keys};
{ok, []} ->
{ok, []};
{error, _} = Error ->
log_error(Error, get_keys_by_index, [{table, Table},
{index, Index},
{key, Key}]),
Error
end.
You can customize your riak and add ejabberd_riak
to the riak application (you don't need to start the whole ejabberd application on the riak side, however)
With monckeypatching approach, you should copy ejabberd_riak.erl, ejabberd.hrl, logger.hrl to the riak/deps/riak_kv/src
. Then rebuild riak. You should distribute your files over the whole cluster, as map
phase is executed on each cluster node.