zerg_support 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v0.1.5. A second take on the SocketFactory issues.
2
+
1
3
  v0.1.4. SocketFactory issues: no lingering, proper closing.
2
4
 
3
5
  v0.1.3. Anti-zombie protection in spawn.
@@ -101,7 +101,6 @@ module SocketFactory
101
101
  else
102
102
  # No lingering sockets.
103
103
  socket.setsockopt Socket::SOL_SOCKET, Socket::SO_LINGER, [1, 0].pack('ii')
104
- sugar_socket_close socket
105
104
  end
106
105
  end
107
106
 
@@ -114,6 +113,7 @@ module SocketFactory
114
113
  sock, addr = super
115
114
  Zerg::Support::SocketFactory.set_options sock,
116
115
  @zerg_support_factory_options
116
+ Zerg::Support::SocketFactory.sugar_socket_close sock
117
117
  return sock, addr
118
118
  end
119
119
  end
@@ -126,13 +126,16 @@ module SocketFactory
126
126
  end
127
127
  end
128
128
 
129
- # Sugar-coat the socket's close() call with the proper way to close a socket.
129
+ # Sugar-coat the socket's close() call with a better way to close a socket.
130
130
  def self.sugar_socket_close(socket)
131
131
  def socket.close
132
- shutdown rescue nil
133
- recv 1 rescue nil
132
+ begin
133
+ shutdown Socket::SHUT_WR
134
+ loop { break if recv(65536).empty? }
135
+ rescue SystemCallError
136
+ end
134
137
  super
135
- end
138
+ end
136
139
  end
137
140
 
138
141
  # Binds a socket to an address based on the options.
@@ -181,7 +184,10 @@ module SocketFactory
181
184
  addr_infos.each do |addr_info|
182
185
  socket = new_outbound_socket_with_addr_info addr_info
183
186
  set_options socket, options
184
- return socket if connect_with_addr_info socket, addr_info
187
+ if connect_with_addr_info socket, addr_info
188
+ sugar_socket_close socket
189
+ return socket
190
+ end
185
191
  socket.close rescue nil
186
192
  end
187
193
  nil
@@ -24,8 +24,13 @@ module ProtocolAdapter
24
24
  define_method :"recv_#{object_name}" do
25
25
  @zerg_protocol_adapter_state ||= state_class.new self
26
26
  while @zerg_protocol_adapter_state.recv_object_buffer.empty?
27
- data = recv 65536
28
- return nil if data.length == 0 # Other side closed socket.
27
+ begin
28
+ data = recv 65536
29
+ rescue SystemCallError # The other side closed the socket forcibly.
30
+ break
31
+ end
32
+ break if data.empty? # The other side closed the socket.
33
+
29
34
  @zerg_protocol_adapter_state.received_bytes data
30
35
  end
31
36
  @zerg_protocol_adapter_state.recv_object_buffer.shift
@@ -55,7 +55,7 @@ class SocketFactoryTest < Test::Unit::TestCase
55
55
 
56
56
  def _test_connection(server_options, client_options = nil)
57
57
  client_options ||= server_options
58
- test_port = 31996
58
+ test_port = 31993
59
59
 
60
60
  cli_gold = { :request_type => 1, :request_name => "moo",
61
61
  :blob => 'abc' * 43000 }
@@ -65,7 +65,7 @@ class SocketFactoryTest < Test::Unit::TestCase
65
65
 
66
66
  # Server thread.
67
67
  server = SF.socket({:in_addr => ":#{test_port}"}.merge server_options)
68
- Thread.new do
68
+ server_thread = Thread.new do
69
69
  server.listen
70
70
  serv_client, client_addrinfo = server.accept
71
71
  serv_client.extend OPAdapter
@@ -81,6 +81,7 @@ class SocketFactoryTest < Test::Unit::TestCase
81
81
  client.send_object cli_gold
82
82
  srv_hash = client.recv_object
83
83
  client.close
84
+ server_thread.join
84
85
  server.close
85
86
 
86
87
  # Checks
@@ -89,8 +90,9 @@ class SocketFactoryTest < Test::Unit::TestCase
89
90
  end
90
91
 
91
92
  def test_connection
92
- _test_connection({:no_delay => true})
93
93
  _test_connection({:reuse_addr => true})
94
+ Kernel.sleep 1.1 # Wait for the lingering socket to flush.
95
+ _test_connection({:reuse_addr => true, :no_delay => true})
94
96
 
95
97
  # TODO(costan): fix UDP at some point
96
98
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{zerg_support}
5
- s.version = "0.1.4"
5
+ s.version = "0.1.5"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Victor Costan"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zerg_support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Costan