basho/riak-dotnet-client

vector clock help

Closed this issue · 7 comments

I've gotten to a point where I'm trying to update an object, so I do a second put, and when I query the object I get something that looks like this:

result              {CorrugatedIron.RiakResult<CorrugatedIron.Models.RiakObject>}   CorrugatedIron.RiakResult<CorrugatedIron.Models.RiakObject>
base                {CorrugatedIron.RiakResult}                                     CorrugatedIron.RiakResult
Continuation        (null)                                                          object
Done                null                                                            bool?
Value               {CorrugatedIron.Models.RiakObject}                              CorrugatedIron.Models.RiakObject
BinIndexes          Count=0                                                         System.Collections.Generic.Dictionary<string,CorrugatedIron.Models.Index.BinIndex>
Bucket              "Sessions_Test"                                                 string
BucketType          (null)                                                          object
CharSet             (null)                                                          object
ContentEncoding     (null)                                                          object
ContentType         "application/json"                                              string
HasChanged          false                                                           bool
IntIndexes          Count=0                                                         System.Collections.Generic.Dictionary<string,CorrugatedIron.Models.Index.IntIndex>
Key                 "04a2a3ad-a311-4bb8-b922-168941b0e8b4"                          string
LastModified        1418246902                                                      uint
LastModifiedUsec    763156                                                          uint
Links               Count=0                                                         System.Collections.Generic.List<CorrugatedIron.Models.RiakLink>
Siblings            Count=2                                                         System.Collections.Generic.List<CorrugatedIron.Models.RiakObject>
UserMetaData        Count=0                                                         System.Collections.Generic.Dictionary<string,string>
VTag                "AiafIpXhiJiqO7guS0I2"                                          string
VTags               Count=2                                                         System.Collections.Generic.List<string>
[0]                 "AiafIpXhiJiqO7guS0I2"                                          string
[1]                 "1tI6H6FTh9R4S9hOv1V80E"                                        string
Raw View                                                                            
Value               {byte[353]}                                                     byte[]
VectorClock         {byte[35]}                                                      byte[]
Static members                                                                      
Non-public members                                                                  
Non-public members                                                                  

First of all when I did the put I was hoping it would squash the original and replace it but it doesn't, I went looking for a way to possibly do that... whats the correct way to do that

yeah I definitely need help squashing that original

Ah this should help, so the problem I'm having is when I have a RiakResult that has two vtags, my custom deserializer fails:

    public static SessionIdentity UnserializeIdentity(RiakResult<RiakObject> result)
        {
            //result.Value.Siblings.
            SessionIdentity si = new SessionIdentity();
            var d = JsonConvert.DeserializeObject<dynamic>(System.Text.Encoding.UTF8.GetString(result.Value.Value));

            si.Cookie = d.Cookie;
            si.ZID = d.ZID;
            si.Created = d.Created;
            si.Expires = d.Expires;
            si.Guest = d.Guest;
            si.UserId = d.UserId;
            si.UserName = d.UserName;
            return si;
        }

And I have to use this custom deserializer because the properties of SessionIdentity have internal only set accessors; I designed this to keep other people from trying to do janky shit with the object outside of the .Session namespace; so I'd like to keep them that way hence this deserializer (CI GetObject cannot do this either because it's not in the .Session namespace.) So I guess what I need to do is iterate over .Values.Siblings? any advice on what to do ?

Another note, this method didn't even exist before I started making test cases, otherwise this code is done literally from inside of the SessionIdentity object to keep people from doing weird shit with it.

Funny thing is this code I'm 99% sure was working before I changed to using bucket type and memory backing for this bucket.... I'll do a little more poking around but I'm almost out of ideas

AGH weird, so it was last_write_wins I just needed to set it in the bucket type, also I'd tried riakbucketoptions and I'll bet it was because I wasn't doing options for both the put and the get to do this but this fixed it seems:

laptop riak # bin/riak-admin bucket-type update Sessions '{ "props": { "last_write_wins": "true" } }'

damn thats gonna be hard to get used to, PROGRESS!

Yeah theres's just so much that needs to be done with Riak outside of the client, in riak specifically that largely dictates the behavior of the client... like NotFoundOk lots to figure out

it's cool I really like it just a different way of thinking than I'm used to

I would like to recommend against using '{ "props": { "last_write_wins": "true" } }' and to "get used" to using allow_mult : true. The reason being that Riak works best when you deal with siblings instead of letting Riak deal with them. last_write_wins : true should only be used when your data is immutable, for instance.

In the above case, you iterate over Siblings and choose the correct one, using the vclock from that in your next update of the object. This will resolve the siblings.

Please feel free to re-open this issue or open a new one if you have questions.

Yeah for sure, it makes more sense to adapt vector clocks, i'm just thinking for now at least until I get everything working I'm gonna go with last_write_wins. It does make more sense though I will give you that, object versioning is a neat idea it just requires more work than I can provide right now given that I'm solely responsible for 2348974 things and just signed for a partnership. Rest assured I'll be coming back to this when i have time to figure out how I want to deal with it.

It's kinda like Search, thats another thing I can't really implement until my data model is complete and I have a better idea of what the requirements will be. If I do it now chances are it will become a bloated mess by the time Ive rolled to production, but it's something I'm keeping in mind as I work on this.