1

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

  1. 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.

  2. 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)
minocha
  • 1,043
  • 1
  • 12
  • 26

1 Answers1

1

You should probably load ejabberd_riak on the riak side

You 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.

Community
  • 1
  • 1
Lol4t0
  • 12,444
  • 4
  • 29
  • 65
  • @Lol4to This is interesting and thank you for the reply.. can you point me as to how I can add `ejabberd_riak` to the riak application? Any documentation/link or any folder I should be adding ejabberd src files to ? Currently I have three machines serving as a cluster for riak, would I have to repeat the same process for all the machines or just the master Node? – minocha May 21 '16 at 07:40
  • can you change the riak_rv to `riak_kv`. This worked like a charm and now I get the whole point for the build. Thank you very much! If not for this info it would have taken me a couple of extra days since I was not looking in the right place, especially since I was installing deb builds and not from source. – minocha May 24 '16 at 19:45
  • @minocha, thanks for that `riak-Rv` catch! Actually I believe that copying file requirement is `ejabberd` bug and should be fixed at some point – Lol4t0 May 24 '16 at 19:52