0.6.0-17 Released

5 views
Skip to first unread message

Nate McCall

unread,
Sep 28, 2010, 1:14:04 AM9/28/10
to hector...@googlegroups.com

Janne Jalkanen

unread,
Sep 28, 2010, 3:16:52 AM9/28/10
to hector...@googlegroups.com

Thanks. Are the changes required by developers documented somewhere?

My unit tests just exploded.

/Janne

Nate McCall

unread,
Sep 28, 2010, 3:54:33 AM9/28/10
to hector...@googlegroups.com
Lol. Mostly just package moves and some renames for abstraction (last
time we'll do this, btw).

http://github.com/rantav/hector/blob/master/CHANGELOG

... just realized I may have off-by-one'd the release number - my bad.

Janne Jalkanen

unread,
Sep 28, 2010, 4:57:00 AM9/28/10
to hector...@googlegroups.com

My problem is chiefly with exceptions - I've started to get stuff like this:
me.prettyprint.hector.api.exceptions.HNotFoundException: NotFoundException()
at me.prettyprint.cassandra.service.ExceptionsTranslatorImpl.translate(ExceptionsTranslatorImpl.java:32)
at me.prettyprint.cassandra.service.KeyspaceServiceImpl$17.execute(KeyspaceServiceImpl.java:588)
at me.prettyprint.cassandra.service.KeyspaceServiceImpl$17.execute(KeyspaceServiceImpl.java:581)
at me.prettyprint.cassandra.service.Operation.executeAndSetResult(FailoverOperator.java:384)
at me.prettyprint.cassandra.service.FailoverOperator.operateSingleIteration(FailoverOperator.java:190)
at me.prettyprint.cassandra.service.FailoverOperator.operate(FailoverOperator.java:99)
at me.prettyprint.cassandra.service.KeyspaceServiceImpl.operateWithFailover(KeyspaceServiceImpl.java:151)
at me.prettyprint.cassandra.service.KeyspaceServiceImpl.getColumn(KeyspaceServiceImpl.java:597)
at com.thinglink.site.cassandra.CassandraManager.getValue(CassandraManager.java:267)
at com.thinglink.site.cassandra.CassandraManagerTest.testRemove(CassandraManagerTest.java:56)
Caused by: NotFoundException()
at org.apache.cassandra.thrift.Cassandra$get_result.read(Cassandra.java:3639)
at org.apache.cassandra.thrift.Cassandra$Client.recv_get(Cassandra.java:344)
at org.apache.cassandra.thrift.Cassandra$Client.get(Cassandra.java:319)
at me.prettyprint.cassandra.service.KeyspaceServiceImpl$17.execute(KeyspaceServiceImpl.java:586)
I think there's a problem with the API design: HectorException (or at least the NotFoundException) should not extend RuntimeException. Since getColumn() is supposed to throw a NotFoundException (as opposed to returning null) when nothing is found, the exception becomes a part of the API contract. Hence, the exception should be checked. Now it just creeps upwards and you can't catch a programming error at compile time.

I think it would be better not to extend RuntimeException - or to be precise, create a special HectorRuntimeException for those exceptions that really need it.

/Janne

Nate McCall

unread,
Sep 28, 2010, 11:34:35 AM9/28/10
to hector...@googlegroups.com
I understand your point regarding get returning a null - but throwing
an exception on a miss is non-intuitive and an API wart of Thrift (as
opposed to returning an empty "result" of some type that we've all
grown used to with JDBC). Our purpose with v2 was to "hide" as much of
this as possible. I get the checked vs. unchecked exception stuff.
Though technically we are "abusing" runtime exceptions, I hate having
to declare a whole list of exceptions in each method - one of the
reasons I've always like the SpringFramework JDBC wrapper API (from
which we got the idea for the exception translator).

That said, perhaps returning a null from KeyspaceServiceImpl is not
appropriate at that level and we should propagate a wrapped Exception
to catch at the v2 layer in order to maintain a tighter contract with
the Thrift API.

Thoughts? Other folks?

B. Todd Burruss

unread,
Sep 28, 2010, 2:04:49 PM9/28/10
to hector-users
in the thrift API "get"is the only retrieval method that throws the
NotFoundException. all others return null or "empty" columns.

the question is when to throw an exception. throwing an exception
from a data retrieval call should mean "i never in my life expected to
not find the data i just requested, so this is a truly exceptional
event". however if you do expect to ask for data that isn't there,
then a null is much more appropriate because this is not "exceptional"
and expected.

i like returning null instead of throwing an exception, because in my
case there is nothing exceptional about the data not being there.

if you want the exception to bubble up i believe you should check for
null, then throw an exception of your choice that is meaningful to
your app.

On Sep 28, 8:34 am, Nate McCall <n...@riptano.com> wrote:
> I understand your point regarding get returning a null - but throwing
> an exception on a miss is non-intuitive and an API wart of Thrift (as
> opposed to returning an empty "result" of some type that we've all
> grown used to with JDBC). Our purpose with v2 was to "hide" as much of
> this as possible. I get the checked vs. unchecked exception stuff.
> Though technically we are "abusing" runtime exceptions, I hate having
> to declare a whole list of exceptions in each method - one of the
> reasons I've always like the SpringFramework JDBC wrapper API (from
> which we got the idea for the exception translator).
>
> That said, perhaps returning a null from KeyspaceServiceImpl is not
> appropriate at that level and we should propagate a wrapped Exception
> to catch at the v2 layer in order to maintain a tighter contract with
> the Thrift API.
>
> Thoughts? Other folks?
>

Ran Tavory

unread,
Sep 28, 2010, 3:04:33 PM9/28/10
to hector...@googlegroups.com
I agree with Nate and Todd - IMHO throwing an exception on a missing value is a bug in the thrift API design and I think it's hector's job to shield its clients from such bugs. 
In Hector all exceptions are runtime exceptions. What we want to gain by this is first simpler and shorter client code (I never appreciated java's way of dealing with checked exceptions and many other languages have chosen another path) and second the semantics of "listen, this is a low level error you *probably* don't care about and you *probably* don't know how to fix or don't have enough data to fix it, so I don't want to bother you with having to catch it". In many cases a thrift-transport exception or what have you are not the kind of errors clients are really concerned about and even if they are they probably can't or should not have to fix them. Of course with all rules there are exceptions so if you feel some particular exceptions should be checked do let us know, but my view is that in most cases the user would benefit with runtime exceptions rather than checked ones. I'm aware it's also a matter of style and that there's no "one right design that fits all" so we're always open to other suggestions. 
@Janne, from the stack trace I see that you're using the lower level API from hector. One of the main benefits of this release is a clear separation b/w the lower and the higher level APIs and I'd encourage you to have a look at the higher level before you choose to use the lower one. I'll send an email with more details to the list.

--
/Ran

Janne Jalkanen

unread,
Sep 28, 2010, 3:10:47 PM9/28/10
to hector...@googlegroups.com
> @Janne, from the stack trace I see that you're using the lower level API from hector. One of the main benefits of this release is a clear separation b/w the lower and the higher level APIs and I'd encourage you to have a look at the higher level before you choose to use the lower one. I'll send an email with more details to the list.

I'm using the lower layer simply because that's what is in production, and that's what Hector used before. I'll switch to the higher layer API once it's been vetted by enough people so that I don't get surprises. There's a cost involved in rewriting code, you know :-)

/Janne

Ran Tavory

unread,
Sep 28, 2010, 3:20:37 PM9/28/10
to hector...@googlegroups.com
fair enough :)
--
/Ran

Janne Jalkanen

unread,
Sep 28, 2010, 3:08:49 PM9/28/10
to hector...@googlegroups.com

Well, *either* you have to return a null, *or* you throw an exception. Both have their uses, for example Apache Jackrabbit uses the latter, with the notion that it clarifies code. For example

MyObject object;

try {
object = getObject("foo");
object.doSomething();
object.doSomethingElse();
} catch( NotFoundException e ) {
object = createObject("foo");
}

object.doSomethingAgain();

The point being that you _never have worry about object being null in your code_, therefore eliminating hard-to-find NPEs. Also, it eliminates the need for subroutines to do null checks; they can just propagate missing stuff as an error condition, reducing the amount of code you write. So it does have its uses, though it does mean that you have to interpret the word "exception" somewhat liberally. This same pattern is also used by e.g. OSCache. This is also the idea around returning an empty Collection when you do a get_slice or something similar: your object is never null, it's just empty.

There are examples of both ways - but I don't think throwing a RuntimeException is the best choice. Either it needs to be a regular, checked Exception, or return null. The advantage of not using a RuntimeException is that you never get surprises at upper levels. I like the fact that everything derives from a single HectorException, but I'm not sure whether a RuntimeException is the best choice here. You could still declare everything as "throws HectorException". ;-)

One possibility is to always return a Collection, but that reduces the simplicity of an API (and would incorporate one of my main annoyances of the JDBC - if I know there's exactly one value, why can't I just get it directly? :-P)

(And I don't really care for the Thrift API at all. I think it's pretty awful... I'm just rooting for consistency here :-)

/Janne

Ran Tavory

unread,
Sep 28, 2010, 5:01:28 PM9/28/10
to hector...@googlegroups.com
I agree, you need to be consistent and either result null all the times or throw and exception all the times.
IMO when reading a value from a DB it makes more sense to return a null if the value is missing.
Problem is that with the lower level API I was trying to be consistent with the thrift API. Only later did I realize it had this design problem... My plan is that once the v2 API is in good use then I'll fix this lower level API to be more consistent but I need an alternative and a good reason before I break a current functionality even if it's ill-designed. 
I agree that a runtime exception isn't a good choice here. http://github.com/rantav/hector/issues/issue/70
--
/Ran

Markus Kramer

unread,
Sep 29, 2010, 5:55:48 AM9/29/10
to hector-users
Great work!

The hector pom at
http://mvn.riptano.com/content/repositories/public/me/prettyprint/hector/0.6.0-17/hector-0.6.0-17.pom
doesn't contain the dependencies on libthrift and cassandra though.

Is there another hector artifact that we should use or are the
dependencies just missing?

Regards, Markus

Ran Tavory

unread,
Sep 29, 2010, 6:37:05 AM9/29/10
to hector...@googlegroups.com
in 0.6.0 the dependencies are inline, they were not available on any other public repo so they are in the /lib directory.
from 0.7.0 and forward they are hosted on mvn.riptano.com
--
/Ran

Nate McCall

unread,
Sep 29, 2010, 10:55:25 AM9/29/10
to hector...@googlegroups.com
I have cassandra-0.6.5 and related thrift up on the repo if you want
to use them - I just have not come back to including them in the pom
file.

I still need to tweak the pom files in the repository for dependencies
(I just did the automatic thing in nexus which lacking in
flexibility). I'll fill those in for 0.7x in the next couple of days.

Reply all
Reply to author
Forward
0 new messages