[Groonga-commit] droonga/droonga-engine at 101ac77 [master] Prevent to send same chunk twice

Back to archive index

YUKI Hiroshi null+****@clear*****
Wed Apr 29 00:24:37 JST 2015


YUKI Hiroshi	2015-04-29 00:24:37 +0900 (Wed, 29 Apr 2015)

  New Revision: 101ac772646008d91028543ceedc0a18b1f20ffc
  https://github.com/droonga/droonga-engine/commit/101ac772646008d91028543ceedc0a18b1f20ffc

  Message:
    Prevent to send same chunk twice

  Modified files:
    lib/droonga/buffered_tcp_socket.rb

  Modified: lib/droonga/buffered_tcp_socket.rb (+27 -0)
===================================================================
--- lib/droonga/buffered_tcp_socket.rb    2015-04-28 23:47:57 +0900 (52d5594)
+++ lib/droonga/buffered_tcp_socket.rb    2015-04-29 00:24:37 +0900 (c10bd69)
@@ -24,6 +24,9 @@ module Droonga
   class BufferedTCPSocket < Coolio::TCPSocket
     include Loggable
 
+    class AlreadyInWritingByOthers < StandardError
+    end
+
     def initialize(socket, data_directory)
       super(socket)
       @data_directory = data_directory
@@ -47,6 +50,7 @@ module Droonga
       until @_write_buffer.empty?
         chunk = @_write_buffer.shift
         begin
+          chunk.writing
           logger.trace("Sending...", :data => chunk.data)
           written_size = @_io.write_nonblock(chunk.data)
           if written_size == chunk.data.bytesize
@@ -60,14 +64,18 @@ module Droonga
             @_write_buffer.unshift(chunk)
             break
           end
+        rescue AlreadyInWritingByOthers
+          logger.trace("Chunk is already in sending by another process.")
         rescue Errno::EINTR
           @_write_buffer.unshift(chunk)
+          chunk.failed
           logger.trace("Failed to send chunk. Retry later.",
                        :chunk => chunk,
                        :errpr => "Errno::EINTR")
           return
         rescue SystemCallError, IOError, SocketError => exception
           @_write_buffer.unshift(chunk)
+          chunk.failed
           logger.trace("Failed to send chunk. Retry later.",
                        :chunk => chunk,
                        :exception => exception)
@@ -121,6 +129,7 @@ module Droonga
 
     class Chunk
       SUFFIX = ".chunk"
+      WRITING_SUFFIX = ".writing"
 
       class << self
         def load(path)
@@ -152,6 +161,20 @@ module Droonga
         end
       end
 
+      def writing
+        raise AlreadyInWritingByOthers.new if writing?
+        FileUtils.mv(path.to_s, writing_path.to_s)
+      end
+
+      def writing?
+        not path.exist?
+      end
+
+      def failed
+        return unless writing?
+        FileUtils.mv(writing_path.to_s, path.to_s)
+      end
+
       def written
         FileUtils.rm_f(path.to_s)
       end
@@ -168,6 +191,10 @@ module Droonga
         @path ||= create_chunk_file_path
       end
 
+      def writing_path
+        @writing_path ||= Pathname("#{path.to_s}#{WRITING_SUFFIX}")
+      end
+
       def create_chunk_file_path
         basename = Timestamp.stringify(@time_stamp)
         if @uniqueness
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index