Asynchronous IO
Cassandra’s native binary protocol supports request pipelining. Essentially, this lets a single connection to be used for several simultaneous and independent request/response exchanges. Additionally, Ruby Driver doesn’t use any blocking apis internally and runs all requests in the background reactor thread.
For consistency of API, all asynchronous methods end with _async
(e.g. Session#execute_async) and return a Future object.
Methods like Session#prepare, Session#execute and Session#close are thin wrappers around Session#prepare_async, Session#execute_async and Session#close_async accordingly. These wrapper methods simply call their asynchronous counter part and block waiting for resulting future to be resolved.
A Cassandra::Future
can be used to:
- block application thread until execution has completed
- register a listener to be notified when a result is available.
When describing different asynchronous method results, we will use a Cassandra::Future<Type>
notation to signal the type of the result of the future. For example, Cassandra::Future<Cassandra::Result>
is a future that returns an instance of Cassandra::Result
when calling its #get
method.
Example: getting a result
future = session.execute_async(statement)
result = future.get # will block and raise error or return result
Whenever a Future is resolved using its Cassandra::Future#get
method, it will block until it has a value. Once a value is available, it will be returned. In case of an error, an exception will be raised.
Example: registering a listener
future = session.execute_async(statement)
# register success listener
future.on_success do |rows|
rows.each do |row|
puts "#{row["artist"]}: #{row["title"]} / #{row["album"]}"
end
end