protobuf-nats 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -0
- data/lib/protobuf/nats.rb +2 -1
- data/lib/protobuf/nats/client.rb +74 -42
- data/lib/protobuf/nats/server.rb +6 -1
- data/lib/protobuf/nats/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df808ca99a789024cfe3ab03071d1acafeef32a5
|
4
|
+
data.tar.gz: 6ba58e9150dd5b575a3b2b44e1f6ff06ff151681
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 648a3e8de0b1ca89864eaef8b5076d25eb74508920c31d04883b1766bf09d6237aac15b3b55ba3b5e126d51ebc063468ebbdb92278a33ac8dd953e9c85e7b1ba
|
7
|
+
data.tar.gz: f4dba8e3b094b0e2f19a89d436ed209f792cd3696d07d6c6c931352202aceec5961980be83e45708d2a39c3d091e99754b3179f3776d0934464de44933c64627
|
data/README.md
CHANGED
@@ -38,6 +38,11 @@ used to allow JVM based servers to warm-up slowly to prevent jolts in runtime pe
|
|
38
38
|
|
39
39
|
`PB_NATS_CLIENT_ACK_TIMEOUT` - Seconds to wait for an ACK from the rpc server (default: 5 seconds).
|
40
40
|
|
41
|
+
`PB_NATS_CLIENT_NACK_BACKOFF_INTERVALS` - Array of milliseconds to wait between NACK retries (default: "0,1,3,5,10").
|
42
|
+
|
43
|
+
`PB_NATS_CLIENT_NACK_BACKOFF_SPLAY_LIMIT` - Milliseconds to add to the NACK backoff timeout to avoid bursting retries
|
44
|
+
(default: 10 milliseconds).
|
45
|
+
|
41
46
|
`PB_NATS_CLIENT_RESPONSE_TIMEOUT` - Seconds to wait for a non-ACK response from the rpc server (default: 60 seconds).
|
42
47
|
|
43
48
|
`PB_NATS_CLIENT_RECONNECT_DELAY` - If we detect a reconnect delay, we will wait this many seconds (default: the ACK timeout).
|
data/lib/protobuf/nats.rb
CHANGED
data/lib/protobuf/nats/client.rb
CHANGED
@@ -29,6 +29,30 @@ module Protobuf
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
def nack_backoff_intervals
|
33
|
+
@nack_backoff_intervals ||= if ::ENV.key?("PB_NATS_CLIENT_NACK_BACKOFF_INTERVALS")
|
34
|
+
::ENV["PB_NATS_CLIENT_NACK_BACKOFF_INTERVALS"].split(",").map(&:to_i)
|
35
|
+
else
|
36
|
+
[0, 1, 3, 5, 10]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def nack_backoff_splay
|
41
|
+
@nack_backoff_splay ||= if nack_backoff_splay_limit > 0
|
42
|
+
rand(nack_backoff_splay_limit)
|
43
|
+
else
|
44
|
+
0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def nack_backoff_splay_limit
|
49
|
+
@nack_backoff_splay_limit ||= if ::ENV.key?("PB_NATS_CLIENT_NACK_BACKOFF_SPLAY_LIMIT")
|
50
|
+
::ENV["PB_NATS_CLIENT_NACK_BACKOFF_SPLAY_LIMIT"].to_i
|
51
|
+
else
|
52
|
+
10
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
32
56
|
def reconnect_delay
|
33
57
|
@reconnect_delay ||= if ::ENV.key?("PB_NATS_CLIENT_RECONNECT_DELAY")
|
34
58
|
::ENV["PB_NATS_CLIENT_RECONNECT_DELAY"].to_i
|
@@ -47,11 +71,28 @@ module Protobuf
|
|
47
71
|
|
48
72
|
def send_request
|
49
73
|
retries ||= 3
|
74
|
+
nack_retry ||= 0
|
75
|
+
|
76
|
+
loop do
|
77
|
+
setup_connection
|
78
|
+
request_options = {:timeout => response_timeout, :ack_timeout => ack_timeout}
|
79
|
+
@response_data = nats_request_with_two_responses(cached_subscription_key, @request_data, request_options)
|
80
|
+
case @response_data
|
81
|
+
when :ack_timeout
|
82
|
+
next if (retries -= 1) > 0
|
83
|
+
raise ::NATS::IO::Timeout
|
84
|
+
when :nack
|
85
|
+
interval = nack_backoff_intervals[nack_retry]
|
86
|
+
nack_retry += 1
|
87
|
+
raise ::NATS::IO::Timeout if interval.nil?
|
88
|
+
sleep((interval + nack_backoff_splay)/1000.0)
|
89
|
+
next
|
90
|
+
end
|
91
|
+
break
|
92
|
+
end
|
50
93
|
|
51
|
-
setup_connection
|
52
|
-
request_options = {:timeout => response_timeout, :ack_timeout => ack_timeout}
|
53
|
-
@response_data = nats_request_with_two_responses(cached_subscription_key, @request_data, request_options)
|
54
94
|
parse_response
|
95
|
+
|
55
96
|
rescue ::Protobuf::Nats::Errors::IOException => error
|
56
97
|
::Protobuf::Nats.log_error(error)
|
57
98
|
|
@@ -59,10 +100,6 @@ module Protobuf
|
|
59
100
|
logger.warn "An IOException was raised. We are going to sleep for #{delay} seconds."
|
60
101
|
sleep delay
|
61
102
|
|
62
|
-
retry if (retries -= 1) > 0
|
63
|
-
raise
|
64
|
-
rescue ::NATS::IO::Timeout
|
65
|
-
# Nats response timeout.
|
66
103
|
retry if (retries -= 1) > 0
|
67
104
|
raise
|
68
105
|
end
|
@@ -100,24 +137,19 @@ module Protobuf
|
|
100
137
|
|
101
138
|
# Wait for reply
|
102
139
|
first_message = nats.next_message(sub, ack_timeout)
|
103
|
-
|
140
|
+
return :ack_timeout if first_message.nil?
|
141
|
+
return :nack if first_message.data == ::Protobuf::Nats::Messages::NACK
|
142
|
+
|
104
143
|
second_message = nats.next_message(sub, timeout)
|
105
|
-
fail
|
144
|
+
fail(::NATS::IO::Timeout, subject) if second_message.nil?
|
106
145
|
|
107
146
|
# Check messages
|
108
|
-
response =
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
else response = first_message.data
|
113
|
-
end
|
114
|
-
case second_message.data
|
115
|
-
when ::Protobuf::Nats::Messages::ACK then has_ack = true
|
116
|
-
else response = second_message.data
|
117
|
-
end
|
147
|
+
response = case ::Protobuf::Nats::Messages::ACK
|
148
|
+
when first_message.data then second_message.data
|
149
|
+
when second_message.data then first_message.data
|
150
|
+
end
|
118
151
|
|
119
|
-
|
120
|
-
fail(::NATS::IO::Timeout, subject) unless success
|
152
|
+
fail(::NATS::IO::Timeout, subject) unless response
|
121
153
|
|
122
154
|
response
|
123
155
|
ensure
|
@@ -131,19 +163,16 @@ module Protobuf
|
|
131
163
|
nats = Protobuf::Nats.client_nats_connection
|
132
164
|
inbox = nats.new_inbox
|
133
165
|
lock = ::Monitor.new
|
134
|
-
|
135
|
-
|
166
|
+
received = lock.new_cond
|
167
|
+
messages = []
|
168
|
+
first_message = nil
|
169
|
+
second_message = nil
|
136
170
|
response = nil
|
171
|
+
|
137
172
|
sid = nats.subscribe(inbox, :max => 2) do |message, _, _|
|
138
173
|
lock.synchronize do
|
139
|
-
|
140
|
-
|
141
|
-
ack_condition.signal
|
142
|
-
next
|
143
|
-
else
|
144
|
-
response = message
|
145
|
-
pb_response_condition.signal
|
146
|
-
end
|
174
|
+
messages << message
|
175
|
+
received.signal
|
147
176
|
end
|
148
177
|
end
|
149
178
|
|
@@ -153,28 +182,31 @@ module Protobuf
|
|
153
182
|
|
154
183
|
# Wait for the ACK from the server
|
155
184
|
ack_timeout = opts[:ack_timeout] || 5
|
156
|
-
|
185
|
+
received.wait(ack_timeout) if messages.empty?
|
186
|
+
first_message = messages.shift
|
187
|
+
|
188
|
+
return :ack_timeout if first_message.nil?
|
189
|
+
return :nack if first_message == ::Protobuf::Nats::Messages::NACK
|
157
190
|
|
158
191
|
# Wait for the protobuf response
|
159
192
|
timeout = opts[:timeout] || 60
|
160
|
-
|
193
|
+
received.wait(timeout) if messages.empty?
|
194
|
+
second_message = messages.shift
|
161
195
|
end
|
162
196
|
|
197
|
+
response = case ::Protobuf::Nats::Messages::ACK
|
198
|
+
when first_message then second_message
|
199
|
+
when second_message then first_message
|
200
|
+
end
|
201
|
+
|
202
|
+
fail(::NATS::IO::Timeout, subject) unless response
|
203
|
+
|
163
204
|
response
|
164
205
|
ensure
|
165
206
|
# Ensure we don't leave a subscription sitting around.
|
166
207
|
nats.unsubscribe(sid) if response.nil?
|
167
208
|
end
|
168
209
|
|
169
|
-
# This is a copy of #with_nats_timeout
|
170
|
-
def with_timeout(timeout)
|
171
|
-
start_time = ::NATS::MonotonicTime.now
|
172
|
-
yield
|
173
|
-
end_time = ::NATS::MonotonicTime.now
|
174
|
-
duration = end_time - start_time
|
175
|
-
raise ::NATS::IO::Timeout.new("nats: timeout") if duration > timeout
|
176
|
-
end
|
177
|
-
|
178
210
|
end
|
179
211
|
|
180
212
|
end
|
data/lib/protobuf/nats/server.rb
CHANGED
@@ -55,7 +55,12 @@ module Protobuf
|
|
55
55
|
end
|
56
56
|
|
57
57
|
# Publish an ACK to signal the server has picked up the work.
|
58
|
-
|
58
|
+
if was_enqueued
|
59
|
+
nats.publish(reply_id, ::Protobuf::Nats::Messages::ACK)
|
60
|
+
else
|
61
|
+
# TODO: Uncomment once we can roll out NACK messages without a 60 second timeout
|
62
|
+
# nats.publish(reply_id, ::Protobuf::Nats::Messages::NACK)
|
63
|
+
end
|
59
64
|
|
60
65
|
was_enqueued
|
61
66
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protobuf-nats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Dewitt
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: protobuf
|