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