Hi Brian
Thanks for your detailed response.

Nothing detects whether there is a vclock or not. If there isn't one
> provided (the value is `null` in Java), then one isn't sent to Riak -
> it is not a requirement for a store operation for it to be present. If
> an object exists when such a store is performed and allow_multi=true
> for the bucket, then a sibling is created.
>

By detection I meant that when withoutFetch is used StoreObject would throw
an exception
if no RiakVClock annotation exist. I checked the code and it looks like
getRiakVClock will not throw it
and as you say VClock null will be used

>
> The .withoutFetch() method was added to the StoreObject as a requested
> feature. It is meant for when you are storing an object that was
> previously fetched from Riak and want to avoid doing another fetch. If
> that previous fetch returned nothing (the key was not found) then the
> vector clock will be null.
>

I guess another use case would be storing an object if I'm sure key does
not exist i.e. I can guarantee key uniqueness.
For that usage I will use VClock field with null. In that caes if sibblings
are created, each of them will have vtag generated,
and  riak's java client VClock field is in fact vtag?

According to what Sean Cribbs is saying, client sees only one vclock
http://markmail.org/message/n65vsfsqrjpduhwd#query:+page:1+mid:j6ob5r3dtq3nzgxo+state:results

Am I understanding that correctly?


When talking about deleted keys ... unless you change the default
> `delete_mode` in Riak's app.config, you're not usually going to get a
> tombstone - they are reaped after 3s.  Unless either you do a fetch
> immediately following a delete, you're doing store operations without
> vclocks with allow_multi=true for the bucket (which is basically
> "doing it wrong") immediately after a delete and a sibling gets
> created, or hit a very small window with multiple writers under heavy
> load where the read/write cycle interleaves with a delete and a
> tombstone sibling gets created.
>

I was thinking about that 3rd case actually, where interleaved delete
happens,
or case where fetch is executed and another node does delete. 3s is plenty
of time.
I can imagine it would be fairly easy to reproduce that case.


> With that being said, yes, unless you set 'returnDeletedVClock(true)`
> they are silently discarded by the Java client and not passed to the
> Converter. If that has been set, the default JSONConverter will return
> a new instance of whatever POJO is being used (if possible - if
> there's not a default constructor it will throw an exception) and then
> set a @RiakTombstone annotated boolean field to `true` if one exists.
> It detects this by calling the .isDeleted() method of the returned
> IRiakObject.
>

Understood. I think in case of custom converter I need to implement it
myself in similar fashion i.e. using isDeleted()
and setting it in my POJO when fromDomain() gets called.
To handle deleted objects correctly (i.e. do not resurrect them) in in
those corner cases mentioned above I assume I need to set
returnDeletedVClock(true)
and during sibbling resolving pick the one that has isDeleted equal true.
At this point should I store it again with its vclock, or better abort
store by using MutationWithCondition?
I guess 2nd option is better since I want that key to remain 'deleted' and
1st option would resurrect it?

When I have a moment I'm willing to make changes for DomainBucket to
support withoutFetch unless you have it on your plate already.
But first I need to learn how to use git...

Daniel
_______________________________________________
riak-users mailing list
riak-users@lists.basho.com
http://lists.basho.com/mailman/listinfo/riak-users_lists.basho.com

Reply via email to