CassandraObject::Base.connectionの構造をしらべる

タイムアウトするまでの時間を指定したくなった。でもどこで設定していいのかわからない。

Rubyのクラスの構造を逆ツリーで出力するスクリプトを以前書いたので、それを使って調べてみる。
http://gist.github.com/11849

$ irb -rubygems
# クラス構造を調べるメソッドをModuleに追加しちゃう
class Module
  def tree_ancestors
    puts_tree_acestors(0, [self])
  end
  
  protected
  def puts_tree_acestors(indent, displayed_modules)
    puts "%s[%s] %s" % ['  ' * indent, (self.is_a?(Class) ? 'C' : 'M'), self.name]
    nested_included_modules = included_modules.map{|mod| mod.included_modules}.uniq.flatten # - displayed_modules
    my_included_modules = included_modules - nested_included_modules
    my_included_modules -= superclass.included_modules if respond_to?(:superclass) and superclass
    displayed_modules += nested_included_modules
    my_included_modules.each do |mod|
      mod.puts_tree_acestors(indent + 1, displayed_modules)
    end
    if respond_to?(:superclass) and superclass
      superclass.puts_tree_acestors(indent + 1, displayed_modules)
    end
  end
end
#=> nil


require 'cassandra_object'
#=> true

CassandraObject::Base.establish_connection("CassandraObject")
#=> #<Cassandra:2169883280, @keyspace="CassandraObject", @schema={}, @servers=["127.0.0.1:9160"]>

conn = CassandraObject::Base.connection
#=> #<Cassandra:2169883280, @keyspace="CassandraObject", @schema={}, @servers=["127.0.0.1:9160"]>

# 継承ツリーとincludeしているモジュールを調べて困ったらその辺のソースコードを読むつもり
conn.class.tree_ancestors
[C] Cassandra
  [M] Cassandra::Helpers
  [M] Cassandra::Protocol
  [M] Cassandra::Columns
  [C] Object
    [M] JSON::Ext::Generator::GeneratorMethods::Object
    [M] Wirble::Shortcuts
    [M] PP::ObjectMixin
    [M] Kernel
#=> nil

conn.instance_variables
#=> ["@servers", "@keyspace", "@thrift_client_class", "@sub_column_name_class", "@is_super", "@thrift_client_options", "@auto_discover_nodes", "@column_name_class"]

# それっぽいインスタンス変数はない。。。

conn.methods.sort - Object.methods
#=> ["all_nodes", "batch", "calling_method", "check_keyspace", "clear_column_family!", "clear_keyspace!", "client", "compact_mutations!", "count_columns", "count_range", "disable_node_auto_discovery!", "disconnect!", "exists?", "extract_and_validate_params", "get", "get_columns", "get_range", "insert", "keyspace", "keyspaces", "multi_count_columns", "multi_get", "multi_get_columns", "new_client", "reconnect!", "remove", "s_map", "schema", "servers", "thrift_client_class", "thrift_client_options"]

# タイムアウト関係はないけど、clientというメソッドを発見。よりプリミティブな予感

c1 = conn.client
NoMethodError: protected method 'client' called for #<Cassandra:0x102ab9520>
	from (irb):48
	from :0
# protectedなので、sendで取得
c1 = conn.send(:client)
#=> ThriftClientCassandraThrift::Cassandra::Client current_server127.0.0.1:9160

c1.class.tree_ancestors
[C] ThriftClient
  [M] AbstractThriftClient::TimingOutThriftClient
  [M] AbstractThriftClient::RetryingThriftClient
  [C] AbstractThriftClient
    [C] Object
      [M] JSON::Ext::Generator::GeneratorMethods::Object
      [M] Wirble::Shortcuts
      [M] PP::ObjectMixin
      [M] Kernel
#=> nil


c1.instance_variables
#=> ["@request_count", "@connection", "@client_class", "@retries", "@last_rebuild", "@client_methods", "@options", "@has_timeouts", "@retry_period", "@live_server_list", "@current_server", "@max_requests", "@client", "@server_list"]

# またタイムアウト関係はないけど、@clientを発見

c1.methods.sort - Object.methods
#=> ["batch_insert", "batch_mutate", "client", "client_class", "client_methods", "connect!", "current_server", "describe_cluster_name", "describe_keyspace", "describe_keyspaces", "describe_ring", "describe_splits", "describe_version", "disconnect!", "get", "get_count", "get_range_slice", "get_range_slices", "get_slice", "get_string_list_property", "get_string_property", "insert", "login", "multiget", "multiget_slice", "options", "remove", "server_list"]


c2 = c1.client
#=> #<CassandraThrift::Cassandra::Client:0x102a7f910 @seqid=0, @oprot=#<Thrift::BinaryProtocol:0x102a7f988 @strict_read=true, @trans=#<Thrift::BufferedTransport:0x102a7fa00 @index=130, @rbuf="...", @wbuf="", @transport=#<Thrift::Socket:0x102a7fa28 @desc="127.0.0.1:9160", @timeout=1, @port=9160, @handle=#<Socket:0x102a7f438>, host"127.0.0.1", strict_writetrue, iprot#<Thrift::BinaryProtocol:0x102a7f988 @strict_read=true, @trans=#<Thrift::BufferedTransport:0x102a7fa00 @index=130, @rbuf="...", @wbuf="", @transport=#<Thrift::Socket:0x102a7fa28 @desc="127.0.0.1:9160", @timeout=1, @port=9160, @handle=#<Socket:0x102a7f438>, host"127.0.0.1", strict_writetrue

c2.class.tree_ancestors
[C] CassandraThrift::Cassandra::Client
  [M] Thrift::Client
  [C] Object
    [M] JSON::Ext::Generator::GeneratorMethods::Object
    [M] Wirble::Shortcuts
    [M] PP::ObjectMixin
    [M] Kernel
#=> nil


c2.instance_variables
#=> ["@seqid", "@oprot", "@iprot"]

c2.methods.sort - Object.methods
#=> ["batch_insert", "batch_mutate", "describe_cluster_name", "describe_keyspace", "describe_keyspaces", "describe_ring", "describe_splits", "describe_version", "get", "get_count", "get_range_slice", "get_range_slices", "get_slice", "get_string_list_property", "get_string_property", "handle_exception", "insert", "login", "multiget", "multiget_slice", "receive_message", "recv_batch_insert", "recv_batch_mutate", "recv_describe_cluster_name", "recv_describe_keyspace", "recv_describe_keyspaces", "recv_describe_ring", "recv_describe_splits", "recv_describe_version", "recv_get", "recv_get_count", "recv_get_range_slice", "recv_get_range_slices", "recv_get_slice", "recv_get_string_list_property", "recv_get_string_property", "recv_insert", "recv_login", "recv_multiget", "recv_multiget_slice", "recv_remove", "remove", "send_batch_insert", "send_batch_mutate", "send_describe_cluster_name", "send_describe_keyspace", "send_describe_keyspaces", "send_describe_ring", "send_describe_splits", "send_describe_version", "send_get", "send_get_count", "send_get_range_slice", "send_get_range_slices", "send_get_slice", "send_get_string_list_property", "send_get_string_property", "send_insert", "send_login", "send_message", "send_multiget", "send_multiget_slice", "send_remove", "timeout", "timeout="]

# メソッドがいっぱいあるので、seletで絞る。

c2.methods.select{|m| /time/ =~ m}
#=> ["timeout", "timeout="]

# ビンゴ!