krakow 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +16 -0
- data/CONTRIBUTING.md +25 -0
- data/LICENSE +13 -0
- data/README.md +62 -9
- data/krakow.gemspec +3 -1
- data/lib/krakow/command/cls.rb +3 -4
- data/lib/krakow/command/fin.rb +13 -4
- data/lib/krakow/command/identify.rb +22 -9
- data/lib/krakow/command/mpub.rb +14 -4
- data/lib/krakow/command/nop.rb +3 -4
- data/lib/krakow/command/pub.rb +15 -5
- data/lib/krakow/command/rdy.rb +13 -4
- data/lib/krakow/command/req.rb +14 -4
- data/lib/krakow/command/sub.rb +14 -4
- data/lib/krakow/command/touch.rb +13 -4
- data/lib/krakow/command.rb +25 -3
- data/lib/krakow/connection.rb +286 -60
- data/lib/krakow/connection_features/deflate.rb +26 -1
- data/lib/krakow/connection_features/snappy_frames.rb +34 -3
- data/lib/krakow/connection_features/ssl.rb +43 -1
- data/lib/krakow/connection_features.rb +1 -0
- data/lib/krakow/consumer.rb +162 -49
- data/lib/krakow/discovery.rb +17 -6
- data/lib/krakow/distribution/default.rb +61 -33
- data/lib/krakow/distribution.rb +107 -57
- data/lib/krakow/exceptions.rb +14 -0
- data/lib/krakow/frame_type/error.rb +13 -7
- data/lib/krakow/frame_type/message.rb +47 -4
- data/lib/krakow/frame_type/response.rb +14 -4
- data/lib/krakow/frame_type.rb +20 -8
- data/lib/krakow/producer/http.rb +95 -6
- data/lib/krakow/producer.rb +60 -17
- data/lib/krakow/utils/lazy.rb +99 -40
- data/lib/krakow/utils/logging.rb +11 -0
- data/lib/krakow/utils.rb +3 -0
- data/lib/krakow/version.rb +3 -1
- data/lib/krakow.rb +1 -0
- metadata +11 -11
- data/Gemfile +0 -5
- data/Gemfile.lock +0 -34
- data/test/spec.rb +0 -81
- data/test/specs/consumer.rb +0 -49
- data/test/specs/http_producer.rb +0 -123
- data/test/specs/producer.rb +0 -20
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
## v0.3.0
|
2
|
+
* Include jitter to discovery interval lookups
|
3
|
+
* Typecast to String on PUB and MPUB
|
4
|
+
* Update exception types used for not implemented methods
|
5
|
+
* Add #confirm, #requeue, and #touch helpers to FrameType::Message instances
|
6
|
+
* Update Utils::Lazy implementation to be faster and clearer
|
7
|
+
* Add #safe_socket method on Connection to add stability
|
8
|
+
* Rebuild connections on error to prevent consumer teardown
|
9
|
+
* Reference connections without requirement of connection instance being alive
|
10
|
+
* Use #read over #recv on underlying socket to ensure proper number of bytes (thanks @thomas-holmes)
|
11
|
+
* Expand spec testing
|
12
|
+
|
13
|
+
A big thanks to @bschwartz for a large contribution in this changeset
|
14
|
+
including expanded spec coverage, message proxy helper methods, and
|
15
|
+
isolation of instability around Connection interactions.
|
16
|
+
|
1
17
|
## v0.2.2
|
2
18
|
* Fix `nsqlookupd` attribute in `Consumer` and `Discovery`
|
3
19
|
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
## Branches
|
4
|
+
|
5
|
+
### `master` branch
|
6
|
+
|
7
|
+
The master branch is the current stable released version.
|
8
|
+
|
9
|
+
### `develop` branch
|
10
|
+
|
11
|
+
The develop branch is the current edge of development.
|
12
|
+
|
13
|
+
## Pull requests
|
14
|
+
|
15
|
+
* https://github.com/chrisroberts/krakow/pulls
|
16
|
+
|
17
|
+
Please base all pull requests of the `develop` branch. Merges to
|
18
|
+
`master` only occur through the `develop` branch. Pull requests
|
19
|
+
based on `master` will likely be cherry picked.
|
20
|
+
|
21
|
+
## Issues
|
22
|
+
|
23
|
+
Need to report an issue? Use the github issues:
|
24
|
+
|
25
|
+
* https://github.com/chrisroberts/krakow/issues
|
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2014 Chris Roberts
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
CHANGED
@@ -86,7 +86,8 @@ Krakow::Utils::Logging.level = :warn # :debug / :info / :warn / :error / :fatal
|
|
86
86
|
|
87
87
|
### Why is it forcing something called an "unready state"?
|
88
88
|
|
89
|
-
Because forcing starvation is mean.
|
89
|
+
Because forcing starvation is mean. We don't want to be mean, so we'll ensure we
|
90
|
+
are consuming from all registered connections.
|
90
91
|
|
91
92
|
### I just want to connect to a producer, not a lookup service
|
92
93
|
|
@@ -133,8 +134,10 @@ consumer = Krakow::Consumer.new(
|
|
133
134
|
:nsqlookupd => 'http://HOST:PORT',
|
134
135
|
:topic => 'target',
|
135
136
|
:channel => 'ship',
|
136
|
-
:
|
137
|
-
:
|
137
|
+
:connection_options => {
|
138
|
+
:features => {
|
139
|
+
:tls_v1 => true
|
140
|
+
}
|
138
141
|
}
|
139
142
|
)
|
140
143
|
```
|
@@ -148,8 +151,10 @@ consumer = Krakow::Consumer.new(
|
|
148
151
|
:nsqlookupd => 'http://HOST:PORT',
|
149
152
|
:topic => 'target',
|
150
153
|
:channel => 'ship',
|
151
|
-
:
|
152
|
-
:
|
154
|
+
:connection_options => {
|
155
|
+
:features => {
|
156
|
+
:snappy => true
|
157
|
+
}
|
153
158
|
}
|
154
159
|
)
|
155
160
|
```
|
@@ -163,23 +168,71 @@ consumer = Krakow::Consumer.new(
|
|
163
168
|
:nsqlookupd => 'http://HOST:PORT',
|
164
169
|
:topic => 'target',
|
165
170
|
:channel => 'ship',
|
166
|
-
:
|
167
|
-
:
|
171
|
+
:connection_options => {
|
172
|
+
:features => {
|
173
|
+
:deflate => true
|
174
|
+
}
|
168
175
|
}
|
169
176
|
)
|
170
177
|
```
|
171
178
|
|
179
|
+
### I want to use TLS based authentication!
|
180
|
+
|
181
|
+
OK!
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
consumer = Krakow::Consumer.new(
|
185
|
+
:nsqlookupd => 'http://HOST:PORT',
|
186
|
+
:topic => 'target',
|
187
|
+
:channel => 'ship',
|
188
|
+
:connection_options => {
|
189
|
+
:features => {
|
190
|
+
:tls_v1 => true
|
191
|
+
},
|
192
|
+
:config => {
|
193
|
+
:ssl_context => {
|
194
|
+
:certificate => '/path/to/cert',
|
195
|
+
:key => '/path/to/key'
|
196
|
+
}
|
197
|
+
}
|
198
|
+
}
|
199
|
+
)
|
200
|
+
```
|
201
|
+
|
202
|
+
### Running the tests
|
203
|
+
|
204
|
+
Run them all!
|
205
|
+
|
206
|
+
```
|
207
|
+
bundle exec ruby test/run.rb
|
208
|
+
```
|
209
|
+
|
210
|
+
Or, run part of them:
|
211
|
+
|
212
|
+
```
|
213
|
+
bundle exec ruby test/specs/consumer_spec.rb
|
214
|
+
```
|
215
|
+
|
172
216
|
### It doesn't work
|
173
217
|
|
174
|
-
Create an issue on the github repository
|
218
|
+
Create an issue on the github repository
|
219
|
+
* https://github.com/chrisroberts/krakow/issues
|
175
220
|
|
176
221
|
### It doesn't do `x`
|
177
222
|
|
178
|
-
Create an issue, or even better, send a PR.
|
223
|
+
Create an issue, or even better, send a PR.
|
224
|
+
* https://github.com/chrisroberts/krakow/pulls
|
179
225
|
|
180
226
|
# Info
|
181
227
|
* Repo: https://github.com/chrisroberts/krakow
|
228
|
+
* Docs: http://code.chrisroberts.org/krakow
|
182
229
|
* IRC: Freenode @ spox
|
183
230
|
|
184
231
|
[1]: http://bitly.github.io/nsq/ "NSQ: a realtime distributed messaging platform"
|
185
232
|
[2]: http://celluloid.io "Celluloid: Actor-based concurrent object framework for Ruby"
|
233
|
+
|
234
|
+
# Contributors
|
235
|
+
|
236
|
+
* Brendan Schwartz (@bschwartz)
|
237
|
+
* Thomas Holmes (@thomas-holmes)
|
238
|
+
* Jeremy Hinegardner (@copiousfreetime)
|
data/krakow.gemspec
CHANGED
@@ -8,11 +8,13 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.email = 'code@chrisroberts.org'
|
9
9
|
s.homepage = 'http://github.com/chrisroberts/krakow'
|
10
10
|
s.description = 'NSQ ruby library'
|
11
|
+
s.license = 'Apache 2.0'
|
11
12
|
s.require_path = 'lib'
|
12
13
|
s.add_dependency 'celluloid-io'
|
13
14
|
s.add_dependency 'http'
|
14
15
|
s.add_dependency 'multi_json'
|
15
16
|
s.add_dependency 'snappy'
|
16
17
|
s.add_dependency 'digest-crc'
|
17
|
-
s.files = Dir['
|
18
|
+
s.files = Dir['lib/**/*'] + %w(krakow.gemspec README.md CHANGELOG.md CONTRIBUTING.md LICENSE)
|
19
|
+
s.extra_rdoc_files = %w(CHANGELOG.md CONTRIBUTING.md LICENSE)
|
18
20
|
end
|
data/lib/krakow/command/cls.rb
CHANGED
data/lib/krakow/command/fin.rb
CHANGED
@@ -1,11 +1,20 @@
|
|
1
|
+
require 'krakow'
|
2
|
+
|
1
3
|
module Krakow
|
2
4
|
class Command
|
5
|
+
# Finish a message
|
3
6
|
class Fin < Command
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
# @!group Attributes
|
9
|
+
|
10
|
+
# @!macro [attach] attribute
|
11
|
+
# @!method $1
|
12
|
+
# @return [$2] the $1 $0
|
13
|
+
# @!method $1?
|
14
|
+
# @return [TrueClass, FalseClass] truthiness of the $1 $0
|
15
|
+
attribute :message_id, String, :required => true
|
16
|
+
|
17
|
+
# @!endgroup
|
9
18
|
|
10
19
|
def to_line
|
11
20
|
"#{name} #{message_id}\n"
|
@@ -1,18 +1,31 @@
|
|
1
1
|
require 'multi_json'
|
2
|
+
require 'krakow'
|
2
3
|
|
3
4
|
module Krakow
|
4
5
|
class Command
|
6
|
+
# Update client metadata on server / negotiate features
|
5
7
|
class Identify < Command
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
# @!group Attributes
|
10
|
+
|
11
|
+
# @!macro [attach] attribute
|
12
|
+
# @!method $1
|
13
|
+
# @return [$2] the $1 $0
|
14
|
+
# @!method $1?
|
15
|
+
# @return [TrueClass, FalseClass] truthiness of the $1 $0
|
16
|
+
attribute :short_id, [String, Numeric], :required => true
|
17
|
+
attribute :long_id, [String, Numeric], :required => true
|
18
|
+
attribute :feature_negotiation, [TrueClass, FalseClass]
|
19
|
+
attribute :heartbeat_interval, Numeric
|
20
|
+
attribute :output_buffer_size, Integer
|
21
|
+
attribute :output_buffer_timeout, Integer
|
22
|
+
attribute :tls_v1, [TrueClass, FalseClass]
|
23
|
+
attribute :snappy, [TrueClass, FalseClass]
|
24
|
+
attribute :deflate, [TrueClass, FalseClass]
|
25
|
+
attribute :deflate_level, Integer
|
26
|
+
attribute :sample_rate, Integer
|
27
|
+
|
28
|
+
# @!endgroup
|
16
29
|
|
17
30
|
def to_line
|
18
31
|
filtered = Hash[*
|
data/lib/krakow/command/mpub.rb
CHANGED
@@ -1,14 +1,24 @@
|
|
1
|
+
require 'krakow'
|
2
|
+
|
1
3
|
module Krakow
|
2
4
|
class Command
|
5
|
+
# Publish multiple messages
|
3
6
|
class Mpub < Command
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
# @!group Attributes
|
9
|
+
|
10
|
+
# @!macro [attach] attribute
|
11
|
+
# @!method $1
|
12
|
+
# @return [$2] the $1 $0
|
13
|
+
# @!method $1?
|
14
|
+
# @return [TrueClass, FalseClass] truthiness of the $1 $0
|
15
|
+
attribute :topic_name, String, :required => true
|
16
|
+
attribute :messages, Array, :required => true
|
9
17
|
|
18
|
+
# @!endgroup
|
10
19
|
def to_line
|
11
20
|
formatted_messages = messages.map do |message|
|
21
|
+
message = message.to_s
|
12
22
|
[message.length, message].pack('l>a*')
|
13
23
|
end.join
|
14
24
|
[name, ' ', topic_name, "\n", formatted_messages.length, messages.size, formatted_messages].pack('a*a*a*a*l>l>a*')
|
data/lib/krakow/command/nop.rb
CHANGED
data/lib/krakow/command/pub.rb
CHANGED
@@ -1,15 +1,25 @@
|
|
1
|
+
require 'krakow'
|
1
2
|
|
2
3
|
module Krakow
|
3
4
|
class Command
|
5
|
+
# Publish single message
|
4
6
|
class Pub < Command
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
# @!group Attributes
|
9
|
+
|
10
|
+
# @!macro [attach] attribute
|
11
|
+
# @!method $1
|
12
|
+
# @return [$2] the $1 $0
|
13
|
+
# @!method $1?
|
14
|
+
# @return [TrueClass, FalseClass] truthiness of the $1 $0
|
15
|
+
attribute :topic_name, String, :required => true
|
16
|
+
attribute :message, Object, :required => true
|
17
|
+
|
18
|
+
# @!endgroup
|
10
19
|
|
11
20
|
def to_line
|
12
|
-
|
21
|
+
msg = message.to_s
|
22
|
+
[name, ' ', topic_name, "\n", msg.length, msg].pack('a*a*a*a*l>a*')
|
13
23
|
end
|
14
24
|
|
15
25
|
class << self
|
data/lib/krakow/command/rdy.rb
CHANGED
@@ -1,11 +1,20 @@
|
|
1
|
+
require 'krakow'
|
2
|
+
|
1
3
|
module Krakow
|
2
4
|
class Command
|
5
|
+
# Update RDY state
|
3
6
|
class Rdy < Command
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
# @!group Attributes
|
9
|
+
|
10
|
+
# @!macro [attach] attribute
|
11
|
+
# @!method $1
|
12
|
+
# @return [$2] the $1 $0
|
13
|
+
# @!method $1?
|
14
|
+
# @return [TrueClass, FalseClass] truthiness of the $1 $0
|
15
|
+
attribute :count, Integer, :required => true
|
16
|
+
|
17
|
+
# @!endgroup
|
9
18
|
|
10
19
|
def to_line
|
11
20
|
"#{name} #{count}\n"
|
data/lib/krakow/command/req.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
1
|
+
require 'krakow'
|
2
|
+
|
1
3
|
module Krakow
|
2
4
|
class Command
|
5
|
+
# Re-queue a message
|
3
6
|
class Req < Command
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
# @!group Attributes
|
9
|
+
|
10
|
+
# @!macro [attach] attribute
|
11
|
+
# @!method $1
|
12
|
+
# @return [$2] the $1 $0
|
13
|
+
# @!method $1?
|
14
|
+
# @return [TrueClass, FalseClass] truthiness of the $1 $0
|
15
|
+
attribute :message_id, String, :required => true
|
16
|
+
attribute :timeout, Integer, :required => true
|
17
|
+
|
18
|
+
# @!endgroup
|
9
19
|
|
10
20
|
def to_line
|
11
21
|
"#{name} #{message_id} #{self.timeout}\n"
|
data/lib/krakow/command/sub.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
1
|
+
require 'krakow'
|
2
|
+
|
1
3
|
module Krakow
|
2
4
|
class Command
|
5
|
+
# Subscribe to topic/channel
|
3
6
|
class Sub < Command
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
# @!group Attributes
|
9
|
+
|
10
|
+
# @!macro [attach] attribute
|
11
|
+
# @!method $1
|
12
|
+
# @return [$2] the $1 $0
|
13
|
+
# @!method $1?
|
14
|
+
# @return [TrueClass, FalseClass] truthiness of the $1 $0
|
15
|
+
attribute :topic_name, String, :required => true
|
16
|
+
attribute :channel_name, String, :required => true
|
17
|
+
|
18
|
+
# @!endgroup
|
9
19
|
|
10
20
|
def to_line
|
11
21
|
"#{name} #{topic_name} #{channel_name}\n"
|
data/lib/krakow/command/touch.rb
CHANGED
@@ -1,11 +1,20 @@
|
|
1
|
+
require 'krakow'
|
2
|
+
|
1
3
|
module Krakow
|
2
4
|
class Command
|
5
|
+
# Reset timeout for in-flight message
|
3
6
|
class Touch < Command
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
# @!group Attributes
|
9
|
+
|
10
|
+
# @!macro [attach] attribute
|
11
|
+
# @!method $1
|
12
|
+
# @return [$2] the $1 $0
|
13
|
+
# @!method $1?
|
14
|
+
# @return [TrueClass, FalseClass] truthiness of the $1 $0
|
15
|
+
attribute :message_id, String, :required => true
|
16
|
+
|
17
|
+
# @!endgroup
|
9
18
|
|
10
19
|
def to_line
|
11
20
|
"#{name} #{message_id}\n"
|
data/lib/krakow/command.rb
CHANGED
@@ -1,20 +1,33 @@
|
|
1
|
+
require 'krakow'
|
2
|
+
|
1
3
|
module Krakow
|
4
|
+
# Messages for sending to remote server
|
2
5
|
class Command
|
3
6
|
|
4
7
|
include Utils::Lazy
|
8
|
+
# @!parse include Utils::Lazy::InstanceMethods
|
9
|
+
# @!parse extend Utils::Lazy::ClassMethods
|
5
10
|
|
6
11
|
class << self
|
7
12
|
|
13
|
+
# Allowed OK return values
|
14
|
+
#
|
15
|
+
# @return [Array<String>]
|
8
16
|
def ok
|
9
17
|
[]
|
10
18
|
end
|
11
19
|
|
20
|
+
# Allowed ERROR return values
|
21
|
+
#
|
22
|
+
# @return [Array<String>]
|
12
23
|
def error
|
13
24
|
[]
|
14
25
|
end
|
15
26
|
|
16
|
-
#
|
17
|
-
#
|
27
|
+
# Response type expected
|
28
|
+
#
|
29
|
+
# @param message [Krakow::Message] message to check
|
30
|
+
# @return [Symbol] response expected (:none, :error_only, :required)
|
18
31
|
def response_for(message)
|
19
32
|
if(message.class.ok.empty?)
|
20
33
|
if(message.class.error.empty?)
|
@@ -29,23 +42,32 @@ module Krakow
|
|
29
42
|
|
30
43
|
end
|
31
44
|
|
45
|
+
# @return [Krakow::FrameType] response to command
|
32
46
|
attr_accessor :response
|
33
47
|
|
34
|
-
#
|
48
|
+
# @return [String] name of command
|
35
49
|
def name
|
36
50
|
self.class.name.split('::').last.upcase
|
37
51
|
end
|
38
52
|
|
39
53
|
# Convert to line output
|
54
|
+
#
|
55
|
+
# @return [String] socket ready string
|
40
56
|
def to_line(*args)
|
41
57
|
raise NotImplementedError.new 'No line conversion method defined!'
|
42
58
|
end
|
43
59
|
|
60
|
+
# Is response OK
|
61
|
+
#
|
62
|
+
# @return [TrueClass, FalseClass]
|
44
63
|
def ok?(response)
|
45
64
|
response = response.content if response.is_a?(FrameType)
|
46
65
|
self.class.ok.include?(response)
|
47
66
|
end
|
48
67
|
|
68
|
+
# Is response ERROR
|
69
|
+
#
|
70
|
+
# @return [TrueClass, FalseClass]
|
49
71
|
def error?(response)
|
50
72
|
response = response.content if response.is_a?(FrameType)
|
51
73
|
self.class.error.include?(response)
|