From 1a5b3487e5a38a4897a6461b3907cd6bde501e0c Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 8 Nov 2011 02:45:40 +0000 Subject: add support for the file_debug command This was added in MogileFS 2.45 --- lib/mogilefs/backend.rb | 1 + lib/mogilefs/mogilefs.rb | 49 +++++++++++++++++++++++++++++++++++---- test/test_mogilefs_integration.rb | 40 ++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 5 deletions(-) diff --git a/lib/mogilefs/backend.rb b/lib/mogilefs/backend.rb index 7b52939..5403c13 100644 --- a/lib/mogilefs/backend.rb +++ b/lib/mogilefs/backend.rb @@ -86,6 +86,7 @@ class MogileFS::Backend add_command :rename add_command :list_keys add_command :file_info + add_command :file_debug # MogileFS::Backend commands diff --git a/lib/mogilefs/mogilefs.rb b/lib/mogilefs/mogilefs.rb index ef01f5b..bbf8740 100644 --- a/lib/mogilefs/mogilefs.rb +++ b/lib/mogilefs/mogilefs.rb @@ -219,12 +219,13 @@ class MogileFS::MogileFS < MogileFS::Client [ keys, res['next_after'] ] end - # Used to return metadata about a file. Returns the domain, class, expected - # length, devcount, etc. Optionally device ids (not paths) can be returned as - # well if :devices is specified. + # Return metadata about a file as a hash. + # Returns the domain, class, expected length, devcount, etc. + # Optionally device ids (not paths) can be returned as + # well if :devices is specified and +true+. # - # Should be used for informational purposes, and not usually for dynamically - # serving files. + # This should only be used for informational purposes, and not usually + # for dynamically serving files. def file_info(key, args = nil) opts = { :domain => @domain, :key => key } args and devices = args[:devices] and opts[:devices] = devices ? 1 : 0 @@ -233,4 +234,42 @@ class MogileFS::MogileFS < MogileFS::Client devids = rv["devids"] and rv["devids"] = devids.split(/,/).map! { |x| x.to_i } rv end + + # Given an Integer +fid+ or String +key+ and domain, thorougly search + # the database for all occurences of a particular fid. + # + # Use this sparingly, this command hits the master database numerous + # times and is very expensive. This is not for production use, only + # troubleshooting and debugging. + # + # Searches for fid=666: + # + # client.file_debug(666) + # + # Search for key=foo using the default domain for this object: + # + # client.file_debug("foo") + # + # Search for key=foo in domain="bar": + # + # client.file_debug(:key => "foo", :domain => "bar") + # + def file_debug(args) + case args + when Integer then args = { "fid" => args } + when String then args = { "key" => args } + end + opts = { :domain => args[:domain] || @domain }.merge!(args) + + rv = @backend.file_debug(opts) + rv.each do |k,v| + case k + when /_(?:classid|devcount|dmid|fid|length| + nexttry|fromdevid|failcount|flags|devid|type)\z/x + rv[k] = v.to_i + when /devids\z/ + rv[k] = v.split(/,/).map! { |x| x.to_i } + end + end + end end diff --git a/test/test_mogilefs_integration.rb b/test/test_mogilefs_integration.rb index cf8d178..f5915bd 100644 --- a/test/test_mogilefs_integration.rb +++ b/test/test_mogilefs_integration.rb @@ -79,4 +79,44 @@ class TestMogileFSIntegration < TestMogIntegration devids.each { |devid| assert_kind_of Integer, devid } assert_equal res["devcount"], devids.size end + + def test_file_debug + assert_equal 3, @client.store_content("file_debug", "default", "BUG") + a = @client.file_debug("file_debug") + b = @client.file_debug(:key => "file_debug") + fid = @client.file_info("file_debug")["fid"] + c = @client.file_debug(fid) + d = @client.file_debug(:fid => fid) + + [ a, b, c, d ].each do |res| + assert_equal fid, res["fid_fid"] + assert_equal 0, res["fid_classid"] + assert_equal "file_debug", res["fid_dkey"] + assert_equal 3, res["fid_length"] + assert_kind_of Array, res["devids"] + assert_kind_of Integer, res["devids"][0] + res["devids"].each do |devid| + uri = URI.parse(res["devpath_#{devid}"]) + assert_equal "http", uri.scheme + end + assert_equal "default", res["fid_class"] + end + @client.delete("file_debug") + rv = @client.file_debug(fid) + assert rv.keys.grep(/\Afid_/).empty?, rv.inspect + end + + def test_file_debug_in_progress + rv = @client.new_file("file_debug_in_progress") do |http_file| + http_file << "ZZZZ" + dests = http_file.instance_variable_get(:@dests) + dests[0][1] =~ %r{/(\d+)\.fid\z} + fid = $1.to_i + rv = @client.file_debug(fid) + devids = dests.map { |x| x[0].to_i }.sort + assert_equal devids, rv["tempfile_devids"].sort + assert_equal "file_debug_in_progress", rv["tempfile_dkey"] + end + assert_equal 4, rv + end end -- cgit v1.2.3-24-ge0c7