Inconvenient siblings resolution in reads #78

ondrejcernos opened this Issue Nov 6, 2012 · 5 comments


None yet

4 participants


When there are conflicting values, riakc_obj:get_value/1 fails with siblings exception. In my client code, I have a sibling resolution function that performs some automatic analysis, chooses one value and stores the resolved object to the DB. So far so good. The problem is I cannot use the chosen sibling as an object to retrieve value from, as the above mentioned call throws the same sibling exception as for the unresolved version. See the following:

6> Pid = pooler:take_member().
8> {ok, Obj} = riakc_pb_socket:get(Pid, <<"user">>, <<"TestVCUser1">>).
9> riakc_obj:value_count(Obj).
10> SelectedSibling = riakc_obj:select_sibling(1, Obj).
11> riakc_obj:get_value(SelectedSibling).
** exception throw: siblings
in function riakc_obj:get_value/1 (src/riakc_obj.erl, line 183)

This is unfortunate - my get_value_from_riak_object function doesn't need bucket and object key, so I cannot re-read the value from the DB without changing the function signature and provide these values wherever I need to retrieve value from riak object.

Is this behaviour necessary? Is there a reason the resolved sibling cannot be used for value retrieval? If not, could it be changed so that it doesn't throw the sibling exception?


@ondrejcernos I'll try to look into this issue within the next couple days.


Won't riakc_obj:get_values/1 solve your issue? It looks like you already have the index of the sibling.


Well, besides the need to repeat myself (select sibling, select value) it does solve the issue. But this issue is not about inability to get to the selected value but about the inconvenience and surprise - I really didn't expect the sibling exception being raised when get_value is called on the selected sibling and imho it breaks the principle of least surprise.


This is a semi-confusing behavior that was brought over from the original, internal riak_object representation: both the original value as-read, and the new, to-be-written value are kept in the object. We call the latter the "update value". What select_sibling/2 is doing is setting the to-be-written "update value". To fetch it, use the get_update_value/1 function instead of just get_value/1. The same goes for get_update_metadata/1.

I agree that this sounds annoying, but there's a bonus: if no update value has been set, get_update_value/1 calls get_value/1 and returns that result instead. So, you should be able to forget get_value/1 all together, and just call get_update_value/1 every time.


Hi, ok, thanks, will do. Please consider documenting the usage in official documentation of the PB client, I am probably not the only one who ran into this.

@seancribbs seancribbs closed this May 30, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment