riemann-client 1.0.0 → 1.0.1
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +13 -0
- data/.rubocop.yml +18 -0
- data/CHANGELOG.md +10 -2
- data/Gemfile +2 -0
- data/README.markdown +19 -10
- data/Rakefile +4 -1
- data/lib/riemann/attribute.rb +2 -0
- data/lib/riemann/auto_state.rb +9 -3
- data/lib/riemann/client/ssl_socket.rb +22 -21
- data/lib/riemann/client/tcp.rb +38 -38
- data/lib/riemann/client/tcp_socket.rb +66 -51
- data/lib/riemann/client/udp.rb +8 -4
- data/lib/riemann/client.rb +78 -79
- data/lib/riemann/event.rb +45 -51
- data/lib/riemann/message.rb +2 -0
- data/lib/riemann/metric_thread.rb +59 -54
- data/lib/riemann/query.rb +4 -2
- data/lib/riemann/state.rb +8 -8
- data/lib/riemann/version.rb +3 -1
- data/lib/riemann.rb +2 -3
- data/riemann-client.gemspec +9 -5
- data/spec/client.rb +113 -113
- metadata +23 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 395c52ac148f9988953268a74e1e747c415e3b80c75e7e0cfef536d7f44a2d36
|
4
|
+
data.tar.gz: 81051904aef015898e9abde73a6bdf2cde446cec0ed8712b0a2cd569d1a62f50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d016e54a3881d70914163c88506da3936f47c6c3390f092eb1a2a179c1cd1034984337d81ecbbefdcef01019efa168f8d93662918c67125f31245cffa471b1f5
|
7
|
+
data.tar.gz: 330ea26290403c97dd44ac1b0d04b72ea9bebd27a147f00c0135ce9d46a09c01c4f8271daaa3c118a2feeebb84603d6dde77066ee5a994e6c7c32e8e2eb1c89a
|
data/.github/workflows/ci.yml
CHANGED
@@ -10,11 +10,24 @@ on:
|
|
10
10
|
- main
|
11
11
|
|
12
12
|
jobs:
|
13
|
+
lint:
|
14
|
+
runs-on: ubuntu-latest
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- name: Setup ruby
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: '2.7'
|
21
|
+
bundler-cache: true
|
22
|
+
- name: Run rubocop
|
23
|
+
run: bundle exec rubocop
|
13
24
|
test:
|
25
|
+
needs: lint
|
14
26
|
runs-on: ubuntu-latest
|
15
27
|
strategy:
|
16
28
|
matrix:
|
17
29
|
ruby-version:
|
30
|
+
- 2.6
|
18
31
|
- 2.7
|
19
32
|
- 3.0
|
20
33
|
- 3.1
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
Metrics/AbcSize:
|
3
|
+
Enabled: false
|
4
|
+
Metrics/BlockLength:
|
5
|
+
Enabled: false
|
6
|
+
Metrics/ClassLength:
|
7
|
+
Enabled: false
|
8
|
+
Metrics/CyclomaticComplexity:
|
9
|
+
Enabled: false
|
10
|
+
Metrics/MethodLength:
|
11
|
+
Enabled: false
|
12
|
+
Metrics/PerceivedComplexity:
|
13
|
+
Enabled: false
|
14
|
+
Naming/VariableNumber:
|
15
|
+
AllowedIdentifiers:
|
16
|
+
- TLSv1_2
|
17
|
+
Style/Documentation:
|
18
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## [1.0.
|
3
|
+
## [1.0.1](https://github.com/riemann/riemann-ruby-client/tree/1.0.1) (2022-06-25)
|
4
4
|
|
5
|
-
[Full Changelog](https://github.com/riemann/riemann-ruby-client/compare/0.
|
5
|
+
[Full Changelog](https://github.com/riemann/riemann-ruby-client/compare/v1.0.0...1.0.1)
|
6
|
+
|
7
|
+
**Merged pull requests:**
|
8
|
+
|
9
|
+
- Setup Rubocop and lower required Ruby version [\#37](https://github.com/riemann/riemann-ruby-client/pull/37) ([smortex](https://github.com/smortex))
|
10
|
+
|
11
|
+
## [v1.0.0](https://github.com/riemann/riemann-ruby-client/tree/v1.0.0) (2022-06-16)
|
12
|
+
|
13
|
+
[Full Changelog](https://github.com/riemann/riemann-ruby-client/compare/0.2.6...v1.0.0)
|
6
14
|
|
7
15
|
**Implemented enhancements:**
|
8
16
|
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -1,12 +1,16 @@
|
|
1
|
-
|
2
|
-
==========
|
1
|
+
# Riemann Ruby Client
|
3
2
|
|
4
|
-
|
3
|
+
[](https://github.com/riemann/riemann-ruby-client/actions/workflows/ci.yml)
|
5
4
|
|
6
|
-
|
7
|
-
===
|
5
|
+
## Installing
|
8
6
|
|
9
|
-
```
|
7
|
+
```shell
|
8
|
+
gem install riemann-client
|
9
|
+
```
|
10
|
+
|
11
|
+
## Use
|
12
|
+
|
13
|
+
```ruby
|
10
14
|
require 'riemann/client'
|
11
15
|
|
12
16
|
# Create a client. Host, port and timeout are optional.
|
@@ -38,8 +42,8 @@ c['host =~ "%.dc1" and (state = "critical" or state = "warning")']
|
|
38
42
|
|
39
43
|
```
|
40
44
|
|
41
|
-
Transports
|
42
|
-
|
45
|
+
## Transports
|
46
|
+
|
43
47
|
|
44
48
|
Riemann::Client sends small events over UDP by default, and uses TCP for
|
45
49
|
queries and large events. UDP sends are essentially "shouting into the void".
|
@@ -54,8 +58,7 @@ c.tcp["true"] # => [#<Event ... >, ...]
|
|
54
58
|
c.udp["true"] # => raise Riemann::Client::Unsupported
|
55
59
|
```
|
56
60
|
|
57
|
-
Client state management
|
58
|
-
=======================
|
61
|
+
## Client state management
|
59
62
|
|
60
63
|
Riemann::Client provides some classes to make managing state updates easier.
|
61
64
|
|
@@ -64,3 +67,9 @@ be used to flush an accumulated value to ustate at regular intervals.
|
|
64
67
|
|
65
68
|
Riemann::AutoState bundles a state and a client together. Any changes to the
|
66
69
|
AutoState automatically send the new state to the client.
|
70
|
+
|
71
|
+
## License
|
72
|
+
|
73
|
+
The MIT License
|
74
|
+
|
75
|
+
Copyright (c) 2011-2022 Kyle Kingsbury
|
data/Rakefile
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'riemann'
|
2
4
|
|
3
|
-
require
|
5
|
+
require 'bundler/gem_tasks'
|
4
6
|
|
5
7
|
require 'github_changelog_generator/task'
|
6
8
|
|
7
9
|
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
8
10
|
config.user = 'riemann'
|
9
11
|
config.project = 'riemann-ruby-client'
|
12
|
+
config.exclude_labels = ['skip-changelog']
|
10
13
|
config.future_release = Riemann::VERSION
|
11
14
|
config.add_issues_wo_labels = false
|
12
15
|
end
|
data/lib/riemann/attribute.rb
CHANGED
data/lib/riemann/auto_state.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Riemann
|
2
4
|
class AutoState
|
3
5
|
# Binds together a state hash and a Client. Any change made here
|
@@ -40,7 +42,7 @@ module Riemann
|
|
40
42
|
# @state.state = 'heavy lifting b'
|
41
43
|
# ...
|
42
44
|
# end
|
43
|
-
|
45
|
+
|
44
46
|
def initialize(client = Client.new, state = {})
|
45
47
|
@client = client
|
46
48
|
@state = state
|
@@ -95,7 +97,11 @@ module Riemann
|
|
95
97
|
def once(opts)
|
96
98
|
o = @state.merge opts
|
97
99
|
o[:time] = Time.now.to_i
|
98
|
-
o[:tags] =
|
100
|
+
o[:tags] = begin
|
101
|
+
(o[:tags] | ['once'])
|
102
|
+
rescue StandardError
|
103
|
+
['once']
|
104
|
+
end
|
99
105
|
@client << o
|
100
106
|
end
|
101
107
|
|
@@ -111,7 +117,7 @@ module Riemann
|
|
111
117
|
def service=(service)
|
112
118
|
@state[:service] = service
|
113
119
|
flush
|
114
|
-
end
|
120
|
+
end
|
115
121
|
|
116
122
|
def service
|
117
123
|
@state[:service]
|
@@ -1,11 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'openssl'
|
2
4
|
require_relative 'tcp_socket'
|
3
5
|
|
4
6
|
module Riemann
|
5
7
|
class Client
|
6
|
-
|
8
|
+
# Socket: A specialized socket that has been configure
|
7
9
|
class SSLSocket < TcpSocket
|
8
|
-
|
9
10
|
def initialize(options = {})
|
10
11
|
super(options)
|
11
12
|
@key_file = options[:key_file]
|
@@ -16,11 +17,11 @@ module Riemann
|
|
16
17
|
|
17
18
|
def ssl_context
|
18
19
|
@ssl_context ||= OpenSSL::SSL::SSLContext.new.tap do |ctx|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
ctx.key = OpenSSL::PKey::RSA.new(File.read(@key_file))
|
21
|
+
ctx.cert = OpenSSL::X509::Certificate.new(File.read(@cert_file))
|
22
|
+
ctx.ca_file = @ca_file if @ca_file
|
23
|
+
ctx.ssl_version = :TLSv1_2
|
24
|
+
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER if @ssl_verify
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
@@ -30,7 +31,7 @@ module Riemann
|
|
30
31
|
#
|
31
32
|
# Return the ::Socket when it is connected, or raise an Error if no
|
32
33
|
# connection was possible.
|
33
|
-
def connect_nonblock(
|
34
|
+
def connect_nonblock(addr, timeout)
|
34
35
|
sock = super(addr, timeout)
|
35
36
|
ssl_socket = OpenSSL::SSL::SSLSocket.new(sock, ssl_context)
|
36
37
|
ssl_socket.sync = true
|
@@ -38,17 +39,17 @@ module Riemann
|
|
38
39
|
begin
|
39
40
|
ssl_socket.connect_nonblock
|
40
41
|
rescue IO::WaitReadable
|
41
|
-
|
42
|
-
retry
|
43
|
-
else
|
42
|
+
unless IO.select([ssl_socket], nil, nil, timeout)
|
44
43
|
raise Timeout, "Could not read from #{host}:#{port} in #{timeout} seconds"
|
45
44
|
end
|
45
|
+
|
46
|
+
retry
|
46
47
|
rescue IO::WaitWritable
|
47
|
-
|
48
|
-
retry
|
49
|
-
else
|
48
|
+
unless IO.select(nil, [ssl_socket], nil, timeout)
|
50
49
|
raise Timeout, "Could not write to #{host}:#{port} in #{timeout} seconds"
|
51
50
|
end
|
51
|
+
|
52
|
+
retry
|
52
53
|
end
|
53
54
|
ssl_socket
|
54
55
|
end
|
@@ -60,13 +61,13 @@ module Riemann
|
|
60
61
|
#
|
61
62
|
# Returns the bytes read
|
62
63
|
def readpartial(maxlen, outbuf = nil)
|
63
|
-
|
64
|
+
super(maxlen, outbuf)
|
64
65
|
rescue OpenSSL::SSL::SSLErrorWaitReadable
|
65
|
-
|
66
|
-
retry
|
67
|
-
else
|
66
|
+
unless wait_readable(read_timeout)
|
68
67
|
raise Timeout, "Could not read from #{host}:#{port} in #{read_timeout} seconds"
|
69
68
|
end
|
69
|
+
|
70
|
+
retry
|
70
71
|
end
|
71
72
|
|
72
73
|
# Internal: Write the given data to the socket
|
@@ -80,11 +81,11 @@ module Riemann
|
|
80
81
|
def write(buf)
|
81
82
|
super(buf)
|
82
83
|
rescue OpenSSL::SSL::SSLErrorWaitWritable
|
83
|
-
|
84
|
-
retry
|
85
|
-
else
|
84
|
+
unless wait_writable(write_timeout)
|
86
85
|
raise Timeout, "Could not write to #{host}:#{port} in #{write_timeout} seconds"
|
87
86
|
end
|
87
|
+
|
88
|
+
retry
|
88
89
|
end
|
89
90
|
end
|
90
91
|
end
|
data/lib/riemann/client/tcp.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'monitor'
|
2
4
|
require 'riemann/client/tcp_socket'
|
3
5
|
require 'riemann/client/ssl_socket'
|
@@ -5,12 +7,12 @@ require 'riemann/client/ssl_socket'
|
|
5
7
|
module Riemann
|
6
8
|
class Client
|
7
9
|
class TCP < Client
|
8
|
-
attr_accessor :host, :port
|
10
|
+
attr_accessor :host, :port
|
9
11
|
|
10
12
|
# Public: Set a socket factory -- an object responding
|
11
13
|
# to #call(options) that returns a Socket object
|
12
|
-
|
13
|
-
|
14
|
+
class << self
|
15
|
+
attr_writer :socket_factory
|
14
16
|
end
|
15
17
|
|
16
18
|
# Public: Return a socket factory
|
@@ -24,16 +26,14 @@ module Riemann
|
|
24
26
|
}
|
25
27
|
end
|
26
28
|
|
27
|
-
def initialize(options = {})
|
29
|
+
def initialize(options = {}) # rubocop:disable Lint/MissingSuper
|
28
30
|
@options = options
|
29
31
|
@locket = Monitor.new
|
30
32
|
end
|
31
33
|
|
32
34
|
def socket
|
33
35
|
@locket.synchronize do
|
34
|
-
if @pid && @pid != Process.pid
|
35
|
-
close
|
36
|
-
end
|
36
|
+
close if @pid && @pid != Process.pid
|
37
37
|
|
38
38
|
return @socket if connected?
|
39
39
|
|
@@ -58,32 +58,32 @@ module Riemann
|
|
58
58
|
end
|
59
59
|
|
60
60
|
# Read a message from a stream
|
61
|
-
def read_message(
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
str = s.read length
|
66
|
-
message = Riemann::Message.decode str
|
67
|
-
rescue => e
|
68
|
-
puts "Message was #{str.inspect}"
|
69
|
-
raise
|
70
|
-
end
|
61
|
+
def read_message(socket)
|
62
|
+
unless (buffer = socket.read(4)) && (buffer.size == 4)
|
63
|
+
raise InvalidResponse, 'unexpected EOF'
|
64
|
+
end
|
71
65
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
66
|
+
length = buffer.unpack1('N')
|
67
|
+
begin
|
68
|
+
str = socket.read length
|
69
|
+
message = Riemann::Message.decode str
|
70
|
+
rescue StandardError
|
71
|
+
puts "Message was #{str.inspect}"
|
72
|
+
raise
|
73
|
+
end
|
76
74
|
|
77
|
-
|
78
|
-
|
79
|
-
raise
|
75
|
+
unless message.ok
|
76
|
+
puts 'Failed'
|
77
|
+
raise ServerError, message.error
|
80
78
|
end
|
79
|
+
|
80
|
+
message
|
81
81
|
end
|
82
82
|
|
83
83
|
def send_recv(message)
|
84
|
-
with_connection do |
|
85
|
-
|
86
|
-
read_message(
|
84
|
+
with_connection do |socket|
|
85
|
+
socket.write(message.encode_with_length)
|
86
|
+
read_message(socket)
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -94,17 +94,17 @@ module Riemann
|
|
94
94
|
tries = 0
|
95
95
|
|
96
96
|
@locket.synchronize do
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
97
|
+
tries += 1
|
98
|
+
yield(socket)
|
99
|
+
rescue IOError, Errno::EPIPE, Errno::ECONNREFUSED, InvalidResponse, Timeout::Error,
|
100
|
+
Riemann::Client::TcpSocket::Error
|
101
|
+
close
|
102
|
+
raise if tries > 3
|
103
|
+
|
104
|
+
retry
|
105
|
+
rescue StandardError
|
106
|
+
close
|
107
|
+
raise
|
108
108
|
end
|
109
109
|
end
|
110
110
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'socket'
|
2
4
|
require 'fcntl'
|
3
5
|
|
4
6
|
module Riemann
|
5
7
|
class Client
|
6
|
-
|
8
|
+
# Socket: A specialized socket that has been configure
|
7
9
|
class TcpSocket
|
8
10
|
class Error < Riemann::Client::Error; end
|
9
11
|
class Timeout < Error; end
|
@@ -68,7 +70,6 @@ module Riemann
|
|
68
70
|
# connection dead and notifying the application layer.
|
69
71
|
attr_reader :keepalive_count
|
70
72
|
|
71
|
-
|
72
73
|
# Internal: Create and connect to the given location.
|
73
74
|
#
|
74
75
|
# options, same as Constructor
|
@@ -77,11 +78,11 @@ module Riemann
|
|
77
78
|
def self.connect(options = {})
|
78
79
|
s = new(options)
|
79
80
|
s.connect
|
80
|
-
|
81
|
+
s
|
81
82
|
end
|
82
83
|
|
83
84
|
# Internal: Creates a new KJess::Socket
|
84
|
-
def initialize(
|
85
|
+
def initialize(options = {})
|
85
86
|
@host = options[:host]
|
86
87
|
@port = options[:port]
|
87
88
|
|
@@ -113,7 +114,7 @@ module Riemann
|
|
113
114
|
# Returns a new ::Socket instance for
|
114
115
|
|
115
116
|
def socket_factory(type)
|
116
|
-
|
117
|
+
sock = ::Socket.new(type, ::Socket::SOCK_STREAM, 0)
|
117
118
|
|
118
119
|
# close file descriptors if we exec
|
119
120
|
if Fcntl.constants.include?(:F_SETFD) && Fcntl.constants.include?(:FD_CLOEXEC)
|
@@ -122,14 +123,14 @@ module Riemann
|
|
122
123
|
# Disable Nagle's algorithm
|
123
124
|
sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
|
124
125
|
|
125
|
-
if using_keepalive?
|
126
|
-
sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE
|
127
|
-
sock.setsockopt(::Socket::SOL_TCP, ::Socket::TCP_KEEPIDLE
|
126
|
+
if using_keepalive?
|
127
|
+
sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE, true)
|
128
|
+
sock.setsockopt(::Socket::SOL_TCP, ::Socket::TCP_KEEPIDLE, keepalive_idle)
|
128
129
|
sock.setsockopt(::Socket::SOL_TCP, ::Socket::TCP_KEEPINTVL, keepalive_interval)
|
129
|
-
sock.setsockopt(::Socket::SOL_TCP, ::Socket::TCP_KEEPCNT
|
130
|
+
sock.setsockopt(::Socket::SOL_TCP, ::Socket::TCP_KEEPCNT, keepalive_count)
|
130
131
|
end
|
131
132
|
|
132
|
-
|
133
|
+
sock
|
133
134
|
end
|
134
135
|
|
135
136
|
# Internal: Return the connected raw Socket.
|
@@ -139,7 +140,8 @@ module Riemann
|
|
139
140
|
# Returns a ::Socket
|
140
141
|
def socket
|
141
142
|
return @socket unless closed?
|
142
|
-
|
143
|
+
|
144
|
+
@socket ||= connect
|
143
145
|
end
|
144
146
|
|
145
147
|
# Internal: Closes the internal ::Socket
|
@@ -154,7 +156,8 @@ module Riemann
|
|
154
156
|
def closed?
|
155
157
|
return true if @socket.nil?
|
156
158
|
return true if @socket.closed?
|
157
|
-
|
159
|
+
|
160
|
+
false
|
158
161
|
end
|
159
162
|
|
160
163
|
# Internal:
|
@@ -169,16 +172,16 @@ module Riemann
|
|
169
172
|
deadline = Time.now.to_f + connect_timeout
|
170
173
|
|
171
174
|
# Lookup destination address, we only want TCP.
|
172
|
-
addrs = ::Socket.getaddrinfo(host, port, nil, ::Socket::SOCK_STREAM
|
175
|
+
addrs = ::Socket.getaddrinfo(host, port, nil, ::Socket::SOCK_STREAM)
|
173
176
|
errors = []
|
174
|
-
conn_error =
|
177
|
+
conn_error = -> { raise errors.first }
|
175
178
|
sock = nil
|
176
179
|
|
177
180
|
# Sort it so we get AF_INET, IPv4
|
178
|
-
addrs.sort.find(
|
179
|
-
sock = connect_or_error(
|
181
|
+
addrs.sort.find(conn_error) do |addr|
|
182
|
+
sock = connect_or_error(addr, deadline, errors)
|
180
183
|
end
|
181
|
-
|
184
|
+
sock
|
182
185
|
end
|
183
186
|
|
184
187
|
# Internal: Connect to the destination or raise an error.
|
@@ -195,13 +198,14 @@ module Riemann
|
|
195
198
|
# Should the connection fail, append the exception to the errors array and
|
196
199
|
# return false.
|
197
200
|
#
|
198
|
-
def connect_or_error(
|
201
|
+
def connect_or_error(addr, deadline, errors)
|
199
202
|
timeout = deadline - Time.now.to_f
|
200
203
|
raise Timeout, "Could not connect to #{host}:#{port}" if timeout <= 0
|
201
|
-
|
204
|
+
|
205
|
+
connect_nonblock(addr, timeout)
|
202
206
|
rescue Error => e
|
203
207
|
errors << e
|
204
|
-
|
208
|
+
false
|
205
209
|
end
|
206
210
|
|
207
211
|
# Internal: Connect to the give address within the timeout.
|
@@ -210,36 +214,47 @@ module Riemann
|
|
210
214
|
#
|
211
215
|
# Return the ::Socket when it is connected, or raise an Error if no
|
212
216
|
# connection was possible.
|
213
|
-
def connect_nonblock(
|
217
|
+
def connect_nonblock(addr, timeout)
|
214
218
|
sockaddr = ::Socket.pack_sockaddr_in(addr[1], addr[3])
|
215
|
-
sock =
|
216
|
-
sock.connect_nonblock(
|
217
|
-
|
219
|
+
sock = socket_factory(addr[4])
|
220
|
+
sock.connect_nonblock(sockaddr)
|
221
|
+
sock
|
218
222
|
rescue Errno::EINPROGRESS
|
219
223
|
if IO.select(nil, [sock], nil, timeout).nil?
|
220
|
-
|
224
|
+
begin
|
225
|
+
sock.close
|
226
|
+
rescue StandardError
|
227
|
+
nil
|
228
|
+
end
|
221
229
|
raise Timeout, "Could not connect to #{host}:#{port} within #{timeout} seconds"
|
222
230
|
end
|
223
|
-
|
224
|
-
rescue =>
|
225
|
-
|
226
|
-
|
231
|
+
connect_nonblock_finalize(sock, sockaddr)
|
232
|
+
rescue StandardError => e
|
233
|
+
begin
|
234
|
+
sock.close
|
235
|
+
rescue StandardError
|
236
|
+
nil
|
237
|
+
end
|
238
|
+
raise Error, "Could not connect to #{host}:#{port}: #{e.class}: #{e.message}", e.backtrace
|
227
239
|
end
|
228
240
|
|
229
|
-
|
230
241
|
# Internal: Make sure that a non-blocking connect has truely connected.
|
231
242
|
#
|
232
243
|
# Ensure that the given socket is actually connected to the given adddress.
|
233
244
|
#
|
234
245
|
# Returning the socket if it is and raising an Error if it isn't.
|
235
|
-
def connect_nonblock_finalize(
|
236
|
-
sock.connect_nonblock(
|
237
|
-
|
246
|
+
def connect_nonblock_finalize(sock, sockaddr)
|
247
|
+
sock.connect_nonblock(sockaddr)
|
248
|
+
sock
|
238
249
|
rescue Errno::EISCONN
|
239
|
-
|
240
|
-
rescue =>
|
241
|
-
|
242
|
-
|
250
|
+
sock
|
251
|
+
rescue StandardError => e
|
252
|
+
begin
|
253
|
+
sock.close
|
254
|
+
rescue StandardError
|
255
|
+
nil
|
256
|
+
end
|
257
|
+
raise Error, "Could not connect to #{host}:#{port}: #{e.class}: #{e.message}", e.backtrace
|
243
258
|
end
|
244
259
|
|
245
260
|
# Internal: say if we are using TCP Keep Alive or not
|
@@ -255,12 +270,12 @@ module Riemann
|
|
255
270
|
# Returns true or false
|
256
271
|
def using_keepalive?
|
257
272
|
using = false
|
258
|
-
if keepalive_active?
|
259
|
-
using = [
|
273
|
+
if keepalive_active?
|
274
|
+
using = %i[SOL_SOCKET SO_KEEPALIVE SOL_TCP TCP_KEEPIDLE TCP_KEEPINTVL TCP_KEEPCNT].all? do |c|
|
260
275
|
::Socket.const_defined? c
|
261
276
|
end
|
262
277
|
end
|
263
|
-
|
278
|
+
using
|
264
279
|
end
|
265
280
|
|
266
281
|
# Reads length bytes from the socket
|
@@ -274,18 +289,18 @@ module Riemann
|
|
274
289
|
outbuf.replace('')
|
275
290
|
buf = outbuf
|
276
291
|
else
|
277
|
-
buf =
|
292
|
+
buf = String.new
|
278
293
|
end
|
279
294
|
|
280
295
|
while buf.length < length
|
281
|
-
unless rb = readpartial(length - buf.length)
|
296
|
+
unless (rb = readpartial(length - buf.length))
|
282
297
|
break
|
283
298
|
end
|
284
299
|
|
285
300
|
buf << rb
|
286
301
|
end
|
287
302
|
|
288
|
-
|
303
|
+
buf
|
289
304
|
end
|
290
305
|
|
291
306
|
# Internal: Read up to a maxlen of data from the socket and store it in outbuf
|
@@ -295,13 +310,13 @@ module Riemann
|
|
295
310
|
#
|
296
311
|
# Returns the bytes read
|
297
312
|
def readpartial(maxlen, outbuf = nil)
|
298
|
-
|
313
|
+
socket.read_nonblock(maxlen, outbuf)
|
299
314
|
rescue Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNRESET
|
300
|
-
|
301
|
-
retry
|
302
|
-
else
|
315
|
+
unless wait_readable(read_timeout)
|
303
316
|
raise Timeout, "Could not read from #{host}:#{port} in #{read_timeout} seconds"
|
304
317
|
end
|
318
|
+
|
319
|
+
retry
|
305
320
|
end
|
306
321
|
|
307
322
|
# Internal: Write the given data to the socket
|
@@ -313,16 +328,16 @@ module Riemann
|
|
313
328
|
#
|
314
329
|
# returns nothing
|
315
330
|
def write(buf)
|
316
|
-
until buf.nil?
|
331
|
+
until buf.nil? || buf.length.zero?
|
317
332
|
written = socket.write_nonblock(buf)
|
318
333
|
buf = buf[written, buf.length]
|
319
334
|
end
|
320
335
|
rescue Errno::EWOULDBLOCK, Errno::EINTR, Errno::EAGAIN, Errno::ECONNRESET
|
321
|
-
|
322
|
-
retry
|
323
|
-
else
|
336
|
+
unless wait_writable(write_timeout)
|
324
337
|
raise Timeout, "Could not write to #{host}:#{port} in #{write_timeout} seconds"
|
325
338
|
end
|
339
|
+
|
340
|
+
retry
|
326
341
|
end
|
327
342
|
|
328
343
|
def wait_writable(timeout = nil)
|