Skip to content

Commit 6eca5a3

Browse files
committed
Add IPv6 support to the UDP sender
And set the socket host and port at init time so that it does not have to make a DNS call for every send.
1 parent 759772b commit 6eca5a3

File tree

2 files changed

+59
-21
lines changed

2 files changed

+59
-21
lines changed

lib/gelf/transport/udp.rb

+38-17
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,61 @@
11
module GELF
22
module Transport
33
class UDP
4-
attr_accessor :addresses
4+
attr_reader :addresses
55

6-
def initialize(addresses)
7-
@addresses = addresses
6+
def initialize(initial_addresses)
7+
self.addresses = initial_addresses
88
end
99

10+
def addresses=(new_addresses)
11+
@addresses = new_addresses
12+
reset_sockets
13+
end
14+
1015
def send_datagrams(datagrams)
11-
socket = get_socket
12-
idx = get_address_index
13-
14-
host, port = @addresses[idx]
15-
set_address_index((idx + 1) % @addresses.length)
16+
sock = socket
1617
datagrams.each do |datagram|
17-
socket.send(datagram, 0, host, port)
18+
sock.send(datagram, 0)
1819
end
1920
end
2021

2122
def close
22-
socket = get_socket
23-
socket.close if socket
23+
reset_sockets
2424
end
2525

2626
private
2727

28-
def get_socket
29-
Thread.current[:gelf_udp_socket] ||= UDPSocket.open
28+
def socket
29+
idx = socket_index
30+
sock = sockets[idx]
31+
set_socket_index((idx + 1) % @addresses.length)
32+
sock
3033
end
3134

32-
def get_address_index
33-
Thread.current[:gelf_udp_address_idx] ||= 0
35+
def sockets
36+
Thread.current[:gelf_udp_sockets] ||= configure_sockets
3437
end
3538

36-
def set_address_index(value)
37-
Thread.current[:gelf_udp_address_idx] = value
39+
def reset_sockets
40+
return unless Thread.current.key?(:gelf_udp_sockets)
41+
Thread.current[:gelf_udp_sockets].each(&:close)
42+
Thread.current[:gelf_udp_sockets] = nil
43+
end
44+
45+
def socket_index
46+
Thread.current[:gelf_udp_socket_idx] ||= 0
47+
end
48+
49+
def set_socket_index(value)
50+
Thread.current[:gelf_udp_socket_idx] = value
51+
end
52+
53+
def configure_sockets
54+
@addresses.map do |host, port|
55+
UDPSocket.new(Addrinfo.ip(host).afamily).tap do |socket|
56+
socket.connect(host, port)
57+
end
58+
end
3859
end
3960
end
4061
end

test/test_ruby_sender.rb

+21-4
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,35 @@ class TestRubyUdpSender < Test::Unit::TestCase
99
@datagrams2 = %w(e1 e2 e3)
1010
end
1111

12+
context "setup_sockets" do
13+
setup do
14+
@sender.send_datagrams(%w(a1))
15+
@sender.send_datagrams(%w(b1))
16+
end
17+
18+
before_should "be configured with a socket for each address" do
19+
UDPSocket.any_instance.expects(:connect).with do |host,port|
20+
host == 'localhost' && port == 12201
21+
end
22+
UDPSocket.any_instance.expects(:connect).with do |host,port|
23+
host == 'localhost' && port == 12202
24+
end
25+
UDPSocket.any_instance.expects(:send).times(2).returns(nil)
26+
end
27+
end
28+
1229
context "send_datagrams" do
1330
setup do
1431
@sender.send_datagrams(@datagrams1)
1532
@sender.send_datagrams(@datagrams2)
1633
end
1734

1835
before_should "be called 3 times with 1st and 2nd address" do
19-
UDPSocket.any_instance.expects(:send).times(3).with do |datagram, _, host, port|
20-
datagram.start_with?('d') && host == 'localhost' && port == 12201
36+
UDPSocket.any_instance.expects(:send).times(3).with do |datagram,_|
37+
datagram.start_with?('d')
2138
end
22-
UDPSocket.any_instance.expects(:send).times(3).with do |datagram, _, host, port|
23-
datagram.start_with?('e') && host == 'localhost' && port == 12202
39+
UDPSocket.any_instance.expects(:send).times(3).with do |datagram,_|
40+
datagram.start_with?('e')
2441
end
2542
end
2643
end

0 commit comments

Comments
 (0)