# \`fdb\_future\_block\_until\_ready\` and retry logic

**URL:** <https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826>\
**Category:** Development\
**Tags:** bindings\
**Created:** [July 29, 2021, 4:11pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826 "2021-07-29T16:11:47Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![rajivr](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/rajivr/32/1100_2.png) [@rajivr](https://forums.foundationdb.org/u/rajivr)\
**Post date:** [July 29, 2021, 4:11pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/1 "2021-07-29T16:11:48Z")

</div>

I was wondering if `fdb_future_block_until_ready` implements the recommended retry logic internally?

I tried looking at the [Go API](https://github.com/apple/foundationdb/blob/6.3.13/bindings/go/src/fdb/futures.go#L200-L216), and it seems like `fdb_future_block_until_ready` might be implementing retry logic internally (as code path calls `fdb_future_get_key` immediately after `BlockUntilReady`).

In case of [Java API](https://github.com/apple/foundationdb/blob/6.3.13/bindings/java/src/main/com/apple/foundationdb/NativeFuture.java#L137), it looks likes it is not making use of `Future_blockUntilReady`.

Best,  
Rajiv

---

<div class="post-metadata">

**Author:** ![andrew.noyes](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/andrew.noyes/32/443_2.png) [@andrew.noyes](https://forums.foundationdb.org/u/andrew.noyes)\
**Post date:** [July 29, 2021, 6:50pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/2 "2021-07-29T18:50:10Z")

</div>

I’m not sure what exactly you mean by “recommended retry logic”. [fdb\_future\_block\_until\_ready](https://apple.github.io/foundationdb/api-c.html#c.fdb_future_block_until_ready) doesn’t implement any retry logic though. I think the recommended retry logic is to restart your transaction from the beginning if any operation in your transaction fails with a retriable error. The easiest way to do this is to wait on the future returned by [fdb\_transaction\_on\_error](https://apple.github.io/foundationdb/api-c.html#c.fdb_transaction_on_error), which will become ready after an appropriate backoff or fail with an error if the error is not retriable. There is also [fdb\_error\_predicate](https://apple.github.io/foundationdb/api-c.html#c.fdb_error_predicate) if you want to implement your own backoff strategy and just want to know if the error is retriable or not (this is a bit of an advanced, use-at-your-own-risk feature).

Regarding [fdb\_future\_block\_until\_ready](https://apple.github.io/foundationdb/api-c.html#c.fdb_future_block_until_ready), there are basically two phases of interacting with fdb futures - wait until the future is ready, and then inspect the future to retrieve its value or error status. [fdb\_future\_block\_until\_ready](https://apple.github.io/foundationdb/api-c.html#c.fdb_future_block_until_ready) is just a mechanism for waiting until the future is ready, blocking the current thread until the future is ready to inspect. The other option is to use [fdb\_future\_set\_callback](https://apple.github.io/foundationdb/api-c.html#fdb_future_set_callback) and register a callback that will be called some time after the future is ready - this just happens to be the method the java bindings use.

There’s a suite of functions for inspecting the results of futures, depending on the type of value the future holds. [fdb\_future\_get\_key](https://apple.github.io/foundationdb/api-c.html#fdb_future_get_key) is the mechanism for futures that hold keys. There’s more `fdb_future_get_*()` functions for other types, e.g. [fdb\_future\_get\_keyvalue\_array](https://apple.github.io/foundationdb/api-c.html#fdb_future_get_keyvalue_array) for obtaining the result of get range operations. Keep in mind that the lifetime of the underlying memory used to store future results is owned by the future itself, so many bindings copy the results into a language-native representation before destroying the future.

Anyway this is all mostly only relevant for bindings authors or people using the c api directly. Let me know if any part of this is unclear - hope it helps.

---

<div class="post-metadata">

**Author:** ![rajivr](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/rajivr/32/1100_2.png) [@rajivr](https://forums.foundationdb.org/u/rajivr)\
**Post date:** [July 30, 2021, 8:01am UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/3 "2021-07-30T08:01:47Z")

</div>

@andrew.noyes Firstly, thanks a lot for reply. I really appreciate it! 🙂

I think I now have slightly better understanding of the design of the Java and Go bindings.

At a high level it seems transaction API in [Java](https://github.com/apple/foundationdb/blob/6.3.13/bindings/java/src/main/com/apple/foundationdb/FDBDatabase.java#L53-L68) and [Go](https://github.com/apple/foundationdb/blob/6.3.13/bindings/go/src/fdb/database.go#L132-L152) operates on a _function-like_ object. FDB futures along with appropriate business logic is composed inside this function-like object.

If the evaluation of this function-like object fails with a retry-able error, then the function-like object gets re-evaluated using `fdb_transaction_on_error`. Otherwise either the success value or an error gets returned to the caller.

Would this be a fair characterization?

> [@andrew.noyes](#):
>
> Anyway this is all mostly only relevant for bindings authors or people using the c api directly. Let me know if any part of this is unclear - hope it helps.

I am currently exploring how to effectively use FDB Rust bindings along with [Tokio](https://tokio.rs/). Hence the questions relating to C APIs. Yes, your reply indeed helped a lot! Thanks again!

Best,  
Rajiv

---

<div class="post-metadata">

**Author:** ![andrew.noyes](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/andrew.noyes/32/443_2.png) [@andrew.noyes](https://forums.foundationdb.org/u/andrew.noyes)\
**Post date:** [August 2, 2021, 6:06pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/4 "2021-08-02T18:06:11Z")

</div>

> [@rajivr](#):
>
> Would this be a fair characterization?

Yes this sounds fair. The idiomatic way to execute a transaction in all bindings is to pass a callback (a callback that takes a transaction as an argument) to a function that handles tries - and you’ve linked that “retry loop” function for java and go.

> [@rajivr](#):
>
> I am currently exploring how to effectively use FDB Rust bindings along with [Tokio](https://tokio.rs/).

I have a (hobby-only) interest in this so I’m happy to help answer questions etc in my hobby time 🙂

---

<div class="post-metadata">

**Author:** ![rajivr](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/rajivr/32/1100_2.png) [@rajivr](https://forums.foundationdb.org/u/rajivr)\
**Post date:** [August 6, 2021, 6:01am UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/5 "2021-08-06T06:01:19Z")

</div>

@andrew.noyes I noticed there is a specific pattern in which interfaces `ReadTransactionContext`, `ReadTransaction`, `TransactionContext`, `Transaction`, and `Database` are organized in Java and Go bindings.

Did this organization evolve over time or was there some thought given to this design initially?

Also [here](https://gist.github.com/rajivr/bd6397a186da0ba72c39214f7a6ebfb9) is the design of the `FdbFuture` that I am currently prototyping, and its far from final! 🙂

---

<div class="post-metadata">

**Author:** ![andrew.noyes](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/andrew.noyes/32/443_2.png) [@andrew.noyes](https://forums.foundationdb.org/u/andrew.noyes)\
**Post date:** [August 6, 2021, 4:24pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/6 "2021-08-06T16:24:13Z")

</div>

> [@rajivr](#):
>
> Did this organization evolve over time or was there some thought given to this design initially?

I’m not sure I’m the best person to answer that - I think this organization predates my time with foundationdb.

> [@rajivr](#):
>
> Also [here](https://gist.github.com/rajivr/bd6397a186da0ba72c39214f7a6ebfb9) is the design of the `FdbFuture` that I am currently prototyping, and its far from final! 🙂

I think this is using some rust features I’m not very familiar with but from what I understand it looks like a reasonable way to model a blocking API for futures. A couple of thoughts:

1. There are other things you can do with futures that aren’t modeled yet, e.g. cancellation
2. I’m not sure exactly what `check` is doing, but since there are many foundationdb errors that are intended to be handled gracefully/retried, it probably shouldn’t panic. Presumably `FdbResult` is an enum that can encode an error?
3. Is the plan to copy the memory for types with memory owned by futures?

In case you didn’t see this yet there is also prior art in [https://crates.io/crates/foundationdb](https://crates.io/crates/foundationdb). Is that not usable with Tokio?

---

<div class="post-metadata">

**Author:** ![rajivr](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/rajivr/32/1100_2.png) [@rajivr](https://forums.foundationdb.org/u/rajivr)\
**Post date:** [August 7, 2021, 3:22am UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/7 "2021-08-07T03:22:50Z")

</div>

> [@andrew.noyes](#):
>
> 1. There are other things you can do with futures that aren’t modeled yet, e.g. cancellation

I’ve tried to model cancellation implicitly using Rust [drop](https://gist.github.com/rajivr/bd6397a186da0ba72c39214f7a6ebfb9#file-mod-rs-L59-L68) semantics, and used the fact that C API [`fdb_future_destroy`](https://apple.github.io/foundationdb/api-c.html#c.fdb_future_destroy), also does cancellation.

Introducing explicit cancellation would have meant that we would have to maintain cancellation state information in [`FdbFuture<T>`](https://gist.github.com/rajivr/bd6397a186da0ba72c39214f7a6ebfb9#file-mod-rs-L21-L25), and it would have also increased the surface area of the API.

I was wondering if there was a use-case where we would need access to a `FdbFuture<T>`, that has been cancelled but not destroyed?

> [@andrew.noyes](#):
>
> 1. I’m not sure exactly what `check` is doing, but since there are many foundationdb errors that are intended to be handled gracefully/retried, it probably shouldn’t panic. Presumably `FdbResult` is an enum that can encode an error?

`check` does not panic. `check` takes a `fdb_error_t` and returns a `FdbResult<T>`. It is basically a type synonym.

```auto
/// Alias for [`Result`]`<T,`[`FdbError`]`>`
///
/// [`Result`]: std::result::Result
/// [`FdbError`]: crate::FdbError
pub type FdbResult<T> = Result<T, FdbError>;

```

`check` is similar to [`eval`](https://github.com/Clikengo/foundationdb-rs/blob/0.5.0/foundationdb/src/error.rs#L17-L24), in the current FoundationDB Rust crate. I used `check` instead because it is an idiom that is covered in “Foreign Functions” chapter in [Programming Rust](https://www.oreilly.com/library/view/programming-rust-2nd/9781492052586/) book.

> [@andrew.noyes](#):
>
> 1. Is the plan to copy the memory for types with memory owned by futures?

Yes, in `FdbFuture<T>`, `T` must be an owned type (i.e, `FdbFuture<T>` owns the data that `T` _might_ contain). In Rust, we can’t explicitly set a trait bound on `T` to say that it must be an owned type, but that is the idea.

The `join` method takes `self` (instead of the usual `&self` or `&mut self`), which transfers the ownership of `FdbFuture<T>` to the `join` method. Once `join` method completes, ownership of `T` gets transferred to the caller via `FdbResult<T>` and `self: FdbFuture<T>` gets dropped, thereby destroying the FDB future.

The plan is to implement the logic for copying in the [`FdbFutureGet::get`](https://gist.github.com/rajivr/bd6397a186da0ba72c39214f7a6ebfb9#file-mod-rs-L71) trait implementations for the appropriate types.

> [@andrew.noyes](#):
>
> In case you didn’t see this yet there is also prior art in [https://crates.io/crates/foundationdb](https://crates.io/crates/foundationdb). Is that not usable with Tokio?

Yes, I’ve looked into this crate and also the awesome work done by @PierreZ[here](https://github.com/PierreZ/foundationdb-rs/tree/dev/630) in order to bring 6.3 support to this crate. This helped me a lot, in order to quickly come up to speed with my current effort.

As I studied the FoundationDB crate, I realized that there could be an impedance mismatch between how Rust Futures and FDB Futures work. This issue is explained in the section _The problem: completion, cancellation and buffer management_ in this [blog](https://without.boats/blog/io-uring/) post.

The current FoundationDB crate is trying to adapt FDB Futures to Rust Future, but I am not sure if the semantics are compatible.

In the design that I am currently exploring, rather than trying to adapt FDB Futures to Rust Future, my plan is to use Tokio’s blocking [threadpool](https://docs.rs/tokio/1.9.0/tokio/runtime/struct.Builder.html#method.max_blocking_threads) to manage FDB Futures. From what I understand, under the hood, blocking thread pool is also used by JVM and Go Runtimes.

The other design goal is that I want the Rust binding APIs to preserve the Java and Go API idioms as much as possible. That way, when I and others develop layers on the Rust, we can easily get inspiration from layers written in other languages. 🙂

---

<div class="post-metadata">

**Author:** ![andrew.noyes](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/andrew.noyes/32/443_2.png) [@andrew.noyes](https://forums.foundationdb.org/u/andrew.noyes)\
**Post date:** [August 9, 2021, 4:55pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/8 "2021-08-09T16:55:13Z")

</div>

> [@rajivr](#):
>
> Introducing explicit cancellation would have meant that we would have to maintain cancellation state information in [`FdbFuture<T>`](https://gist.github.com/rajivr/bd6397a186da0ba72c39214f7a6ebfb9#file-mod-rs-L21-L25), and it would have also increased the surface area of the API.
> 
> I was wondering if there was a use-case where we would need access to a `FdbFuture<T>` , that has been cancelled but not destroyed?

It’s probably not a very common use case, but in theory you could have several threads waiting on the same future, and if one thread cancels it the other threads should be notified of that. The c api future actually maintains cancellation state internally so you wouldn’t need to maintain it yourself.

I see you are modeling exclusive ownership of the future though so actually my example use case isn’t a concern.

---

<div class="post-metadata">

**Author:** ![rajivr](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/rajivr/32/1100_2.png) [@rajivr](https://forums.foundationdb.org/u/rajivr)\
**Post date:** [August 10, 2021, 8:32am UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/9 "2021-08-10T08:32:59Z")

</div>

@andrew.noyes Thanks a lot for all the feedback so far. 🙂

I was wondering if you could please take a look at the retry logic for [`<FdbDatabase as TransactionContext>::run`](https://gist.github.com/rajivr/954bf2ab715b3b3bfa7712138dda1948#file-database-rs-L90-L124) and [`<FdbDatabase as ReadTransactionContext>::read`](https://gist.github.com/rajivr/954bf2ab715b3b3bfa7712138dda1948#file-database-rs-L65-L88) methods and let me know if I am implementing the retry logic correctly?

Unlike Go panic or Java exceptions, in Rust `Result` type is used to signal errors. Therefore I am forcing the closure to return a `FdbResult<T>`.

As I was updating the crate documentation, I noticed in the [`Java API`](https://apple.github.io/foundationdb/javadoc/com/apple/foundationdb/Transaction.html) it says - "_Note: Client must call commit() and wait on the result on all transactions, even ones that only read…_. Would this be relevant to Rust as we don’t have garbage collector?

---

<div class="post-metadata">

**Author:** ![andrew.noyes](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/andrew.noyes/32/443_2.png) [@andrew.noyes](https://forums.foundationdb.org/u/andrew.noyes)\
**Post date:** [August 10, 2021, 3:30pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/10 "2021-08-10T15:30:06Z")

</div>

> [@rajivr](#):
>
> I was wondering if you could please take a look at the retry logic for [`<FdbDatabase as TransactionContext>::run`](https://gist.github.com/rajivr/954bf2ab715b3b3bfa7712138dda1948#file-database-rs-L90-L124) and [`<FdbDatabase as ReadTransactionContext>::read`](https://gist.github.com/rajivr/954bf2ab715b3b3bfa7712138dda1948#file-database-rs-L65-L88) methods and let me know if I am implementing the retry logic correctly?

Yup, this looks like the standard retry logic.

> [@rajivr](#):
>
> As I was updating the crate documentation, I noticed in the [`Java API`](https://apple.github.io/foundationdb/javadoc/com/apple/foundationdb/Transaction.html) it says - " _Note: Client must call commit() and wait on the result on all transactions, even ones that only read…_ . Would this be relevant to Rust as we don’t have garbage collector?

I’m not sure I fully understand the java bindings recommendation, so maybe I’m not the best person to answer. I think the concern is that read futures don’t e.g. have a reference to the transaction that keeps it alive, and if you destroy the transaction while there are outstanding read futures those can fail with “transaction\_cancelled”. Calling “commit” and waiting on the result will implicitly wait for all the read futures to complete, so it’s sufficient to avoid this problem. I don’t think there are any concerns with memory safety here. Basically if you think it’s possible that any of the read futures outlive the call to the callback passed to the retry loop, it might make sense to call commit and wait on the result.

---

<div class="post-metadata">

**Author:** ![rajivr](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/rajivr/32/1100_2.png) [@rajivr](https://forums.foundationdb.org/u/rajivr)\
**Post date:** [August 11, 2021, 2:07pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/11 "2021-08-11T14:07:25Z")

</div>

Thanks @andrew.noyes. 🙂

Regarding C APIs [`fdb_future_get_value`](https://apple.github.io/foundationdb/api-c.html#c.fdb_future_get_value) and [`fdb_transaction_get`](https://apple.github.io/foundationdb/api-c.html#c.fdb_transaction_get), could you please confirm if I am understanding the behavior of `*out_present` correctly?

1. When the key is absent, then `*out_present` is zero.

2. When the key is present, but with an empty value, then `*out_present` is non-zero, and `*out_value_length` is zero.

3. When the key is present, but with an non-empty value, then `*out_present` is non\_zero, and `*out_value_length` is non-zero, along with a valid `*out_value` (owned by the future)

---

<div class="post-metadata">

**Author:** ![andrew.noyes](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/andrew.noyes/32/443_2.png) [@andrew.noyes](https://forums.foundationdb.org/u/andrew.noyes)\
**Post date:** [August 11, 2021, 3:19pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/12 "2021-08-11T15:19:40Z")

</div>

Yup, that’s all correct

---

<div class="post-metadata">

**Author:** ![rajivr](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/rajivr/32/1100_2.png) [@rajivr](https://forums.foundationdb.org/u/rajivr)\
**Post date:** [August 16, 2021, 1:09pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/13 "2021-08-16T13:09:29Z")

</div>

Thanks @andrew.noyes. There is still some way to go, but [here](https://github.com/rajivr/fdb/blob/wip/fdb/examples/hello_world.rs) is the initial working _hello world_ implementation. 🙂

> [@rajivr](#):
>
> > [@andrew.noyes](#):
> >
> > 1. Is the plan to copy the memory for types with memory owned by futures?
> 
> `[...]`
> 
> The plan is to implement the logic for copying in the [`FdbFutureGet::get`](https://gist.github.com/rajivr/bd6397a186da0ba72c39214f7a6ebfb9#file-mod-rs-L71) trait implementations for the appropriate types.

I can now also share with you an [example](https://github.com/rajivr/fdb/blob/wip/fdb/src/future.rs#L102-L129) is an of copying memory owned by FDB Future in an implementation of `FdbFutureGet::get` trait.

Thanks again for patiently answering my questions. Please do let me know if you have any thoughts/comments.

I was also wondering if it was possible to use [error codes](https://apple.github.io/foundationdb/api-error-codes.html) between 100 thru’ 999 for the language binding layer?

---

<div class="post-metadata">

**Author:** ![andrew.noyes](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/andrew.noyes/32/443_2.png) [@andrew.noyes](https://forums.foundationdb.org/u/andrew.noyes)\
**Post date:** [August 16, 2021, 6:00pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/14 "2021-08-16T18:00:43Z")

</div>

> [@rajivr](#):
>
> I was also wondering if it was possible to use [error codes](https://apple.github.io/foundationdb/api-error-codes.html) between 100 thru’ 999 for the language binding layer?

I don’t think there’s any guarantee these won’t be used by fdb in the future - maybe @ajbeamon knows

---

<div class="post-metadata">

**Author:** ![ajbeamon](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/ajbeamon/32/13_2.png) [@ajbeamon](https://forums.foundationdb.org/u/ajbeamon)\
**Post date:** [August 16, 2021, 9:05pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/15 "2021-08-16T21:05:03Z")

</div>

> I don’t think there’s any guarantee these won’t be used by fdb in the future - maybe @ajbeamon knows

I think you’re right, we haven’t reserved any error codes for external usage as far I know.

---

<div class="post-metadata">

**Author:** ![rajivr](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/rajivr/32/1100_2.png) [@rajivr](https://forums.foundationdb.org/u/rajivr)\
**Post date:** [August 17, 2021, 3:35am UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/16 "2021-08-17T03:35:39Z")

</div>

Thanks @ajbeamon and @andrew.noyes.

There are currently two instances where I’m piggybacking on FDB error codes. One is [here](https://github.com/rajivr/fdb/blob/wip/fdb/src/database/open_database.rs#L22-L28) and the other is under development.

Once my bindings work is complete, maybe I could request for a range from upstream.

---

<div class="post-metadata">

**Author:** ![rajivr](https://sea1.discourse-cdn.com/foundationdb/user_avatar/forums.foundationdb.org/rajivr/32/1100_2.png) [@rajivr](https://forums.foundationdb.org/u/rajivr)\
**Post date:** [September 2, 2021, 1:29pm UTC](https://forums.foundationdb.org/t/fdb-future-block-until-ready-and-retry-logic/2826/17 "2021-09-02T13:29:20Z")

</div>

@andrew.noyes I just completed Rust [Iterator](https://github.com/rajivr/fdb/blob/c304e2dbbba2762fc73d5f40fbe50108119e0eea/fdb/src/range.rs#L359-L453) implementation for range reads.

This was perhaps one of most tricky API to implement thus far, and I am kind of glad it is done! 🙂

I’ve currently modeled the [tests](https://github.com/rajivr/fdb/blob/c304e2dbbba2762fc73d5f40fbe50108119e0eea/fdb/tests/range_query_test.rs) based on [RangeQueryTest.java](https://github.com/apple/foundationdb/blob/master/bindings/java/src/junit/com/apple/foundationdb/RangeQueryTest.java).

I could not find additional unit tests for range reads in other bindings. I was wondering if there are additional tests somewhere else that I can potentially steal ideas from? I also checked Go bindings for tests.
