Thanks for the reply and thoughts, mine below inline.

On 23 Mar 2011, at 20:21, Kresten Krab Thorup wrote:

> From the client side, the moniker RiakObject is actually not too good.  In 
> technical terms, it is of cause a riak_object  - but to a Java programmer, it 
> doesn't feel right for it to have that name.  It's more like a 
> KeyValueHolder, a RiakEntry (makes you think of Map.Entry), or something like 
> that.  I'll vote for calling it RiakEntry, or just plain Entry (we have name 
> spaces in Java, you know...)

Agree, agree, agree. Originally I had Riak, Bucket and Entry, honest I did. I 
even considered implementing Map and Map.Entry for Bucket and RiakObject but 
that was a step too far. I don't know why I toned it down. That'll teach me to 
have some faith, eh? Nice to be validated, but I prefer RiakEntry, I know we 
have name spaces but you don't see that half way down a page of code so a 
little verbosity in naming helps readability.

> It is hard to convey that it is important to get one of these "riak objects", 
> update it, and stash it back in there.  I.e. the fact that a RiakEntry has 
> the "optimistic concurrency state" (in popular speek) needed to later do the 
> update.  

I  had a crack at implementing RiakEntry/Object today. Only the value, content 
type (which go hand in hand) and (Riak)Links were mutable, which fits with this 
quite well. 

> One naturally just want to create a new one and put into the store; and that 
> aspect should perhaps be hinted in the name of this core class, and in the 
> flow of the API.
> 
> Perhaps, for this very reason, store() should be an operation *directly on 
> the RiakEntry*; and then guide people by the way these are obtained.
> 
> I like the idea of modeling buckets explicitly, but then why not have store 
> method on the RiakEntry?

The only thing that worries me here is the tendency towards an ORM and all the 
conceptual weight/horror with (eg. Hibernate's) sessions and detachment. It 
might be mixing metaphors. Is it not better to be upfront that an entry is a 
thing and a bucket is the thing you put it in?


> Anyway, here is some sample code we can discuss from
> 
>     Riak c = ...;  // probably some ugly factory pattern to create a 
> RiakClient here //

So far I have just been coding with constructors for the 2 adapters (HTTP/PBC) 
but when there is to an SPI for adding new clients then there will be a 
factory, sorry.

> 
>     Bucket b = c.get("people");
> 
>     // example 1
>     Entry e = b.get("russelb");   // does GET /riak/people/russeldb
>     e.set("application/json", "{ name: \"Russel Brown\" }" );
>     e.store();
> 
> Then, have a special method to create new entries:
> 
>     // example 2
>     Entry e2 = b.create("krab");     // does not issue GET /riak/people/krab
>     b.set("Kresten Krab Thorup"); // implies text/plain;charset=utf-8
>     b.store();
> 
> The latter (example 2) would issue a "PUT" w/no vector clock; whereas the 
> former (example 1) automatically grabs the vector clock from the GET.  If you 
> sure Bucket.get("no-such-key") then the only "harm done" is that you spent an 
> extra round trip to the server trying to find the VC for no-such-key.

The idea of a separate get/create on the bucket is great and encodes all that 
complexity about vclocks without exposing it. Awesome. Leads nicely into the 
next set of problems too (conflict resolution.)

I think that idea alone solves a bunch of problems I was having with riak 
object creation. I hope that I can take this (and Jon's ideas (just read them, 
too)) and quickly push some code incorporating them.

I need to add an example of using this (unimplemented) API as part of the repo 
and I'll get on with that.

Thank you.

> 
> In fluent style, this would be
> 
>     c.getBucket("people").get("krab").set("Kresten Crap Throwup").store();
> 
>     // and/or
> 
>     c.get("people", "krab").set("XXX").store();
> 
> Which captures the flow that the vector clock needs to be there for the store.
> 
> Likewise, this will make it much more sound to delete things, because you 
> also need the entry (includin gth VC) to delete an object properly
> 
>       bucket.get("krab").delete()
> 
> makes a lot more sense than
> 
>        bucket.create("krab").delete()
> 
> WHICH IS GREAT!  Because we want people to pass in VC to delete operations 
> ... those should really also be replayable, which I am sure they will be one 
> day :-)
> 
> 
> Kresten
> 
> 
> 
> On Mar 23, 2011, at 11:05 , Russell Brown wrote:
> 
>> Hi,
>> I'm trying to make the Java client easier to use and less tied to underlying 
>> implementation so I've started designing a new API. 
>> 
>> I've put some interfaces up at 
>> https://github.com/russelldb/riak-java-client-api
>> 
>> I'd really appreciate any comments you may have.
>> 
>> My intention is to adapt the existing client(s) to these interfaces and 
>> deprecate the old client API gradually (so there will be backward 
>> compatibility for a few releases.) I'll also be reusing the existing client 
>> implementations underneath the API, this isn't a wholesale re-write. 
>> 
>> I hope you can take some time to let me know what you think. I'll put my 
>> thickest skin on.
>> 
>> Many thanks
>> 
>> Russell
>> 
>> PS It is all maven'd up so just clone and mvn eclipse:eclipse if you want to 
>> get a good look.
>> <ATT00001..txt>
> 

_______________________________________________
riak-users mailing list
[email protected]
http://lists.basho.com/mailman/listinfo/riak-users_lists.basho.com

Reply via email to