about summary refs log tree commit homepage
path: root/lib/mogilefs/backend.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mogilefs/backend.rb')
-rw-r--r--lib/mogilefs/backend.rb48
1 files changed, 30 insertions, 18 deletions
diff --git a/lib/mogilefs/backend.rb b/lib/mogilefs/backend.rb
index 0076611..7e984e5 100644
--- a/lib/mogilefs/backend.rb
+++ b/lib/mogilefs/backend.rb
@@ -12,7 +12,15 @@ class MogileFS::Backend
   def self.add_command(*names)
     names.each do |name|
       define_method name do |*args|
-        do_request name, args.first || {}
+        do_request(name, args[0] || {}, false)
+      end
+    end
+  end
+
+  def self.add_idempotent_command(*names)
+    names.each do |name|
+      define_method name do |*args|
+        do_request(name, args[0] || {}, true)
       end
     end
   end
@@ -80,21 +88,21 @@ class MogileFS::Backend
 
   add_command :create_open
   add_command :create_close
-  add_command :get_paths
+  add_idempotent_command :get_paths
   add_command :delete
-  add_command :sleep
+  add_idempotent_command :sleep
   add_command :rename
-  add_command :list_keys
-  add_command :file_info
-  add_command :file_debug
+  add_idempotent_command :list_keys
+  add_idempotent_command :file_info
+  add_idempotent_command :file_debug
 
   # MogileFS::Backend commands
 
-  add_command :get_hosts
-  add_command :get_devices
-  add_command :list_fids
-  add_command :stats
-  add_command :get_domains
+  add_idempotent_command :get_hosts
+  add_idempotent_command :get_devices
+  add_idempotent_command :list_fids
+  add_idempotent_command :stats
+  add_idempotent_command :get_domains
   add_command :create_domain
   add_command :delete_domain
   add_command :create_class
@@ -155,7 +163,7 @@ class MogileFS::Backend
   ##
   # Performs the +cmd+ request with +args+.
 
-  def do_request(cmd, args)
+  def do_request(cmd, args, idempotent = false)
     response = nil
     request = make_request cmd, args
     @mutex.synchronize do
@@ -170,13 +178,17 @@ class MogileFS::Backend
           retry
         end
 
-        response = io.timed_gets(@timeout) and return parse_response(response)
-      ensure
+        line = io.timed_gets(@timeout) and return parse_response(line)
+
+        idempotent or
+          raise EOFError, "end of file reached after: #{request.inspect}"
+      rescue
         # we DO NOT want the response we timed out waiting for, to crop up later
-        # on, on the same socket, intersperesed with a subsequent request!
-        # we close the socket if it times out like this
-        response or shutdown_unlocked
-      end
+        # on, on the same socket, intersperesed with a subsequent request!  we
+        # close the socket if there's any error.
+        shutdown_unlocked
+        idempotent or raise
+      end while idempotent
     end # @mutex.synchronize
   end