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="] # ビンゴ!