about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2008-09-03 15:12:36 -0700
committerEric Wong <normalperson@yhbt.net>2008-09-08 18:59:21 -0700
commit5939e0855ff1e84021cbfd4a72a6b6d9827a25df (patch)
treedbb3846ccd1f6d936e580a82ee26011a13c9d230
parentb0b702171b01e391d9fe29eb4374d971c2f5bc83 (diff)
downloadmogilefs-client-5939e0855ff1e84021cbfd4a72a6b6d9827a25df.tar.gz
Ref: http://rubyforge.org/tracker/index.php?func=detail&aid=15987&group_id=1513&atid=5923
> Submitted By: Matthew Willson
> Summary: Errors on subsequent requests after client times out
>   waiting for a response from tracker on a previous request (it
>   leaves the socket open)
>
> Detailed description
>
> The summary says it all really.
>
> Once in a while, the tracker will time out responding to, say, a
> create_open or a create_close command, raising one of these:
>
> MogileFS::UnreadableSocketError: 146.101.142.132:7001 never became readable
>        from /usr/lib/ruby/gems/1.8/gems/mogilefs-client-1.2.1/lib/mogilefs/backend.rb:158:in `readable?'
>        from /usr/lib/ruby/gems/1.8/gems/mogilefs-client-1.2.1/lib/mogilefs/backend.rb:122:in `do_request'
>        from /usr/lib/ruby/1.8/thread.rb:135:in `synchronize'
>        from /usr/lib/ruby/gems/1.8/gems/mogilefs-client-1.2.1/lib/mogilefs/backend.rb:108:in `do_request'
>        from /usr/lib/ruby/gems/1.8/gems/mogilefs-client-1.2.1/lib/mogilefs/backend.rb:16:in `create_open'
>        from /usr/lib/ruby/gems/1.8/gems/mogilefs-client-1.2.1/lib/mogilefs/mogilefs.rb:108:in `new_file'
>        from /usr/lib/ruby/gems/1.8/gems/mogilefs-client-1.2.1/lib/mogilefs/mogilefs.rb:163:in `store_content'
>        from ./script/../config/../config/../app/models/mogile_backed.rb:59:in `store_in_mogile'
>        from ./script/../config/../config/../app/models/image.rb:139:in `data'
>        from ./script/../config/../config/../app/models/mogile_backed.rb:59:in `store_in_mogile'
>        from (irb):15
>        from (irb):15
>
> The problem is that, if you code catches this error and carries
> on using the same client object for a subsequent request, the
> 'OK' response which we timed out waiting for, will eventually
> arrive, and sit in the socket's read buffer. It will then be
> read and treated as the response to some unconnected subsequent
> command, resulting in a variety of seemingly intermittent and
> confusing errors.
>
> I've attached a patch for this against 1.2.1, which simply
> closes the socket whenever it times out waiting for a reponse.
> The next request will then open a new socket as required.
>
> Also included a quick fix/improvement to error reporting in one
> case, which helped me to  track the problem down.
-rw-r--r--lib/mogilefs/backend.rb1
-rw-r--r--lib/mogilefs/mogilefs.rb4
2 files changed, 4 insertions, 1 deletions
diff --git a/lib/mogilefs/backend.rb b/lib/mogilefs/backend.rb
index 04708e9..88e4f2f 100644
--- a/lib/mogilefs/backend.rb
+++ b/lib/mogilefs/backend.rb
@@ -155,6 +155,7 @@ class MogileFS::Backend
     found = select [socket], nil, nil, @timeout
     if found.nil? or found.empty? then
       peer = (@socket ? "#{@socket.peeraddr[3]}:#{@socket.peeraddr[1]} " : nil)
+      socket.close  # 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! so, we close the socket if it times out like this
       raise MogileFS::UnreadableSocketError, "#{peer}never became readable"
     end
     return true
diff --git a/lib/mogilefs/mogilefs.rb b/lib/mogilefs/mogilefs.rb
index 6bcc5b4..59234b6 100644
--- a/lib/mogilefs/mogilefs.rb
+++ b/lib/mogilefs/mogilefs.rb
@@ -120,7 +120,7 @@ class MogileFS::MogileFS < MogileFS::Client
     res = @backend.create_open(:domain => @domain, :class => klass,
                                :key => key, :multi_dest => 1)
 
-    raise "#{@backend.lasterr}: #{@backend.lasterrstr}" if res.nil? # HACK
+    raise "#{@backend.lasterr}: #{@backend.lasterrstr}" if res.nil? || res == {} # HACK
 
     dests = nil
 
@@ -142,6 +142,8 @@ class MogileFS::MogileFS < MogileFS::Client
     devid, path = dest
 
     case path
+    when nil, '' then
+      raise 'Empty path for mogile upload'
     when /^http:\/\// then
       MogileFS::HTTPFile.open(self, res['fid'], path, devid, klass, key,
                               dests, bytes, &block)