Skip to content

Commit a666f84

Browse files
TylerBrockBrandon Black
authored andcommitted
RUBY-550 socket util module and refactoring
1 parent 04fbff3 commit a666f84

File tree

12 files changed

+65
-52
lines changed

12 files changed

+65
-52
lines changed

lib/mongo.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ module Constants
4545
require 'mongo/util/pool_manager'
4646
require 'mongo/util/sharding_pool_manager'
4747
require 'mongo/util/server_version'
48+
require 'mongo/util/socket_util'
4849
require 'mongo/util/ssl_socket'
4950
require 'mongo/util/tcp_socket'
5051
require 'mongo/util/unix_socket'

lib/mongo/cursor.rb

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ def initialize(collection, opts={})
5050
@options = 0
5151

5252
# Use this socket for the query
53-
@socket = opts[:socket]
54-
@socket_provided = !!@socket
53+
@socket = opts[:socket]
54+
@pool = nil
5555

5656
@closed = false
5757
@query_run = false
@@ -324,7 +324,16 @@ def close
324324
message.put_int(1)
325325
message.put_long(@cursor_id)
326326
log(:debug, "Cursor#close #{@cursor_id}")
327-
@connection.send_message(Mongo::Constants::OP_KILL_CURSORS, message, :socket => @socket)
327+
begin
328+
socket = @pool.checkout
329+
@connection.send_message(
330+
Mongo::Constants::OP_KILL_CURSORS,
331+
message,
332+
:socket => socket
333+
)
334+
ensure
335+
socket.checkin
336+
end
328337
end
329338
@cursor_id = 0
330339
@closed = true
@@ -461,22 +470,23 @@ def send_initial_query
461470
instrument(:find, instrument_payload) do
462471
begin
463472
message = construct_query_message
464-
@socket ||= checkout_socket_from_connection
473+
socket = @socket || checkout_socket_from_connection
465474
results, @n_received, @cursor_id = @connection.receive_message(
466-
Mongo::Constants::OP_QUERY, message, nil, @socket, @command,
475+
Mongo::Constants::OP_QUERY, message, nil, socket, @command,
467476
nil, @options & OP_QUERY_EXHAUST != 0)
468477
rescue ConnectionFailure => ex
478+
socket.close if socket
469479
@connection.refresh
470480
if tries < 3 && !@socket && (!@command || Mongo::Support::secondary_ok?(@selector))
471481
tries += 1
472482
retry
473483
else
474-
raise
484+
raise ex
475485
end
476486
rescue OperationFailure, OperationTimeout => ex
477487
raise ex
478488
ensure
479-
@socket.pool.checkin(@socket) if @socket && @socket.pool && !@socket_provided
489+
socket.checkin unless @socket || socket.nil?
480490
end
481491
@returned += @n_received
482492
@cache += results
@@ -506,13 +516,13 @@ def send_get_more
506516
message.put_long(@cursor_id)
507517
log(:debug, "cursor.refresh() for cursor #{@cursor_id}") if @logger
508518

509-
@socket.pool.checkout if @socket.pool
519+
socket = checkout_socket_from_connection
510520

511521
begin
512522
results, @n_received, @cursor_id = @connection.receive_message(
513-
Mongo::Constants::OP_GET_MORE, message, nil, @socket, @command, nil)
523+
Mongo::Constants::OP_GET_MORE, message, nil, socket, @command, nil)
514524
ensure
515-
@socket.pool.checkin(@socket) if @socket.pool
525+
socket.checkin
516526
end
517527

518528
@returned += @n_received
@@ -523,14 +533,16 @@ def send_get_more
523533
def checkout_socket_from_connection
524534
begin
525535
if @command && !Mongo::Support::secondary_ok?(@selector)
526-
@connection.checkout_reader(:primary)
536+
socket = @connection.checkout_reader(:primary)
527537
else
528-
@connection.checkout_reader(@read, @tag_sets, @acceptable_latency)
538+
socket = @connection.checkout_reader(@read, @tag_sets, @acceptable_latency)
529539
end
530540
rescue SystemStackError, NoMemoryError, SystemCallError => ex
531541
@connection.close
532542
raise ex
533543
end
544+
@pool = socket.pool
545+
socket
534546
end
535547

536548
def checkin_socket(sock)

lib/mongo/db.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def authenticate(username, password, save_auth=true)
109109
socket = @connection.checkout_reader(:primary_preferred)
110110
issue_authentication(username, password, save_auth, :socket => socket)
111111
ensure
112-
socket.pool.checkin(socket) if socket
112+
socket.checkin if socket
113113
end
114114

115115
@connection.authenticate_pools

lib/mongo/mongo_client.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ def checkout_writer
537537
# Note: this is overridden in MongoReplicaSetClient.
538538
def checkin(socket)
539539
if @primary_pool && socket && socket.pool
540-
socket.pool.checkin(socket)
540+
socket.checkin
541541
end
542542
end
543543

lib/mongo/mongo_replica_set_client.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ def checkout_writer
352352
# Checkin a socket used for reading.
353353
def checkin(socket)
354354
if socket && socket.pool
355-
socket.pool.checkin(socket)
355+
socket.checkin
356356
end
357357
sync_refresh
358358
end

lib/mongo/networking.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def send_message(operation, message, opts={})
3939
raise ex
4040
ensure
4141
if sock
42-
sock.pool.checkin(sock)
42+
sock.checkin
4343
end
4444
end
4545
end
@@ -116,6 +116,7 @@ def receive_message(operation, message, log_message=nil, socket=nil, command=fal
116116
send_message_on_socket(packed_message, socket)
117117
result = receive(socket, request_id, exhaust)
118118
rescue ConnectionFailure => ex
119+
socket.close
119120
checkin(socket)
120121
raise ex
121122
rescue SystemStackError, NoMemoryError, SystemCallError => ex

lib/mongo/util/socket_util.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module SocketUtil
2+
3+
attr_accessor :pool, :pid
4+
5+
def checkout
6+
@pool.checkout if @pool
7+
end
8+
9+
def checkin
10+
@pool.checkin(self) if @pool
11+
end
12+
13+
def close
14+
@socket.close unless closed?
15+
end
16+
17+
def closed?
18+
@socket.closed?
19+
end
20+
end

lib/mongo/util/ssl_socket.rb

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,44 @@ module Mongo
88
# a TCP connection over SSL and then provides an basic interface
99
# mirroring Ruby's TCPSocket, vis., TCPSocket#send and TCPSocket#read.
1010
class SSLSocket
11-
12-
attr_accessor :pool, :pid
11+
include SocketUtil
1312

1413
def initialize(host, port, op_timeout=nil, connect_timeout=nil)
1514
@op_timeout = op_timeout
1615
@connect_timeout = connect_timeout
1716
@pid = Process.pid
1817

19-
@socket = ::TCPSocket.new(host, port)
20-
@socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
18+
@tcp_socket = ::TCPSocket.new(host, port)
19+
@tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
2120

22-
@ssl = OpenSSL::SSL::SSLSocket.new(@socket)
23-
@ssl.sync_close = true
21+
@socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket)
22+
@socket.sync_close = true
2423

2524
connect
2625
end
2726

2827
def connect
2928
if @connect_timeout
3029
Timeout::timeout(@connect_timeout, ConnectionTimeoutError) do
31-
@ssl.connect
30+
@socket.connect
3231
end
3332
else
34-
@ssl.connect
33+
@socket.connect
3534
end
3635
end
3736

3837
def send(data)
39-
@ssl.syswrite(data)
38+
@socket.syswrite(data)
4039
end
4140

4241
def read(length, buffer)
4342
if @op_timeout
4443
Timeout::timeout(@op_timeout, OperationTimeout) do
45-
@ssl.sysread(length, buffer)
44+
@socket.sysread(length, buffer)
4645
end
4746
else
48-
@ssl.sysread(length, buffer)
47+
@socket.sysread(length, buffer)
4948
end
5049
end
51-
52-
def close
53-
@ssl.close
54-
end
55-
56-
def closed?
57-
@ssl.closed?
58-
end
5950
end
6051
end

lib/mongo/util/tcp_socket.rb

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module Mongo
88
# sans Timeout::timeout
99
#
1010
class TCPSocket
11-
attr_accessor :pool, :pid
11+
include SocketUtil
1212

1313
def initialize(host, port, op_timeout=nil, connect_timeout=nil)
1414
@op_timeout = op_timeout
@@ -58,13 +58,5 @@ def read(maxlen, buffer)
5858
raise ConnectionFailure, ex
5959
end
6060
end
61-
62-
def close
63-
@socket.close
64-
end
65-
66-
def closed?
67-
@socket.closed?
68-
end
6961
end
7062
end

test/functional/cursor_test.rb

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,18 @@ def setup
1616
@@coll_full_name = "#{MONGO_TEST_DB}.test"
1717
end
1818

19-
def test_alive_and_cursor_socket_affinity
19+
def test_alive
2020
batch = []
2121
5000.times do |n|
2222
batch << {:a => n}
2323
end
2424

2525
@@coll.insert(batch)
2626
cursor = @@coll.find
27-
assert !cursor.instance_variable_get(:@socket)
2827
assert !cursor.alive?
2928
cursor.next
30-
socket = cursor.instance_variable_get(:@socket)
31-
assert socket
3229
assert cursor.alive?
33-
200.times { cursor.next }
34-
assert_equal socket, cursor.instance_variable_get(:@socket)
3530
cursor.close
36-
assert_equal socket, cursor.instance_variable_get(:@socket)
3731
assert !cursor.alive?
3832
@@coll.remove
3933
end

0 commit comments

Comments
 (0)