erlangejabberdriakriak-cs

ejabberd_riak delete functions


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)

Solution

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