hermann 0.20.1-java → 0.20.2-java
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/lib/hermann/consumer.rb +2 -4
- data/lib/hermann/discovery/zookeeper.rb +91 -23
- data/lib/hermann/provider/java_producer.rb +1 -0
- data/lib/hermann/provider/java_simple_consumer.rb +37 -18
- data/lib/hermann/version.rb +1 -1
- metadata +5 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c9f75e450674ab97eae2977213013ec3c22f9e6
|
4
|
+
data.tar.gz: 4a3fb3da2b3c6776172d9b550bfcfedaa7da9066
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a0003509edf79b5c388d6fe22c496124613a008dc055e2889fcda5d439b825f0a65e22f860d0598597d1e999745f98df6659638cf6e27ec8b3c284ae3258a3b
|
7
|
+
data.tar.gz: ba0fd53110ede6966aa1a3fb460a520c4299e20bebd784f9d92cc868001f24cdbaee53b206061743fcfff528ec92dad4e86d8288999db16f36b1b01ab49ce06b
|
data/lib/hermann/consumer.rb
CHANGED
@@ -21,11 +21,9 @@ module Hermann
|
|
21
21
|
#
|
22
22
|
# @params [String] comma separated zookeeper list
|
23
23
|
#
|
24
|
-
# @params [Hash] options for
|
24
|
+
# @params [Hash] options for Consumer
|
25
25
|
# @option opts [String] :brokers (for MRI) Comma separated list of brokers
|
26
|
-
# @option opts [
|
27
|
-
# @option opts [Fixnum] :sleep_time (Jruby) Time to sleep between consume retries, defaults to 1sec
|
28
|
-
# @option opts [Boolean] :do_retry (Jruby) Retry consume attempts if exceptions are thrown, defaults to true
|
26
|
+
# @option opts [Integer] :partition (for MRI) The kafka partition
|
29
27
|
def initialize(topic, groupId, zookeepers, opts={})
|
30
28
|
@topic = topic
|
31
29
|
@brokers = brokers
|
@@ -1,21 +1,30 @@
|
|
1
1
|
require 'hermann'
|
2
|
-
|
2
|
+
|
3
|
+
if RUBY_PLATFORM == 'java'
|
4
|
+
require 'java'
|
5
|
+
end
|
6
|
+
|
3
7
|
require 'json'
|
4
8
|
require 'hermann/errors'
|
5
9
|
|
6
10
|
module Hermann
|
7
11
|
module Discovery
|
8
|
-
|
9
|
-
|
10
12
|
# Communicates with Zookeeper to discover kafka broker ids
|
11
13
|
#
|
12
14
|
class Zookeeper
|
13
|
-
attr_reader :zookeepers
|
15
|
+
attr_reader :zookeepers, :impl
|
14
16
|
|
15
17
|
BROKERS_PATH = "/brokers/ids".freeze
|
16
|
-
|
17
18
|
def initialize(zookeepers)
|
18
19
|
@zookeepers = zookeepers
|
20
|
+
@impl = nil
|
21
|
+
if CuratorImpl.usable?
|
22
|
+
@impl = CuratorImpl.new(zookeepers)
|
23
|
+
elsif ZkGemImpl.usable?
|
24
|
+
@impl = ZkGemImpl.new(zookeepers)
|
25
|
+
else
|
26
|
+
raise Hermann::Errors::GeneralError, "Could not find a usable Zookeeper implementation, please make sure either the `zk` gem is installed or Curator is on the classpath"
|
27
|
+
end
|
19
28
|
end
|
20
29
|
|
21
30
|
# Gets comma separated string of brokers
|
@@ -27,10 +36,8 @@ module Hermann
|
|
27
36
|
# @return [Array] List of brokers from ZK
|
28
37
|
# @raises [NoBrokersError] if could not discover brokers thru zookeeper
|
29
38
|
def get_brokers(timeout=0)
|
30
|
-
brokers =
|
31
|
-
|
32
|
-
brokers = fetch_brokers(zk)
|
33
|
-
end
|
39
|
+
brokers = impl.brokers(timeout).map { |b| format_broker_from_znode(b) }
|
40
|
+
|
34
41
|
if brokers.empty?
|
35
42
|
raise Hermann::Errors::NoBrokersError
|
36
43
|
end
|
@@ -39,6 +46,43 @@ module Hermann
|
|
39
46
|
|
40
47
|
private
|
41
48
|
|
49
|
+
# Formats the node data into string
|
50
|
+
#
|
51
|
+
# @param [String] node data
|
52
|
+
#
|
53
|
+
# @return [String] formatted node data or empty string if error
|
54
|
+
def format_broker_from_znode(znode)
|
55
|
+
hash = JSON.parse(znode)
|
56
|
+
host = hash['host']
|
57
|
+
port = hash['port']
|
58
|
+
host && port ? "#{host}:#{port}" : nil
|
59
|
+
rescue JSON::ParserError
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
63
|
+
# The ZkGemImpl class is an implementation of simple broker discovery
|
64
|
+
# using the `zk` gem if it is available
|
65
|
+
class ZkGemImpl
|
66
|
+
def self.usable?
|
67
|
+
begin
|
68
|
+
require 'zk'
|
69
|
+
return true
|
70
|
+
rescue LoadError
|
71
|
+
return false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize(zks)
|
76
|
+
@zookeepers = zks
|
77
|
+
end
|
78
|
+
|
79
|
+
def brokers(timeout=0)
|
80
|
+
ZK.open(@zookeepers, {:timeout => timeout}) do |zk|
|
81
|
+
return fetch_brokers(zk)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
42
86
|
# Gets an Array of broker strings
|
43
87
|
#
|
44
88
|
# @param [ZK::Client] zookeeper client
|
@@ -49,9 +93,9 @@ module Hermann
|
|
49
93
|
zk.children(BROKERS_PATH).each do |id|
|
50
94
|
node = fetch_znode(zk, id)
|
51
95
|
next if node.nil? # whatever error could happen from ZK#get
|
52
|
-
brokers <<
|
96
|
+
brokers << node
|
53
97
|
end
|
54
|
-
brokers
|
98
|
+
return brokers
|
55
99
|
end
|
56
100
|
|
57
101
|
# Gets node from zookeeper
|
@@ -65,20 +109,44 @@ module Hermann
|
|
65
109
|
rescue ZK::Exceptions::NoNode
|
66
110
|
nil
|
67
111
|
end
|
112
|
+
end
|
68
113
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
114
|
+
# The CuratorImpl is an implementation of simple broker discovery using
|
115
|
+
# Apache Curator libraries, if they are made available on the classpath
|
116
|
+
# for the process running Hermann::Discovery::Zookeeper.
|
117
|
+
#
|
118
|
+
# For a number of reasons this is preferred over the `zk` gem, namely
|
119
|
+
# being a much more simple and mature Zookeeper client interface
|
120
|
+
class CuratorImpl
|
121
|
+
def self.usable?
|
122
|
+
begin
|
123
|
+
Java::OrgApacheCuratorFramework::CuratorFrameworkFactory
|
124
|
+
return true
|
125
|
+
rescue NameError
|
126
|
+
return false
|
127
|
+
end
|
81
128
|
end
|
129
|
+
|
130
|
+
def initialize(zks)
|
131
|
+
retry_policy = Java::OrgApacheCuratorRetry::ExponentialBackoffRetry.new(1000, 3)
|
132
|
+
@curator = Java::OrgApacheCuratorFramework::CuratorFrameworkFactory.newClient(zks, retry_policy)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Timeout is discarded, only later versions of Curator support
|
136
|
+
# blockUntilConnected which would take the timeout variable
|
137
|
+
def brokers(timeout=0)
|
138
|
+
unless @curator.started?
|
139
|
+
@curator.start
|
140
|
+
end
|
141
|
+
|
142
|
+
brokers = []
|
143
|
+
@curator.children.for_path(BROKERS_PATH).each do |id|
|
144
|
+
path = "#{BROKERS_PATH}/#{id}"
|
145
|
+
brokers << @curator.data.for_path(path).to_s
|
146
|
+
end
|
147
|
+
return brokers
|
148
|
+
end
|
149
|
+
end
|
82
150
|
end
|
83
151
|
end
|
84
152
|
end
|
@@ -12,11 +12,18 @@ module Hermann
|
|
12
12
|
NUM_THREADS = 1
|
13
13
|
|
14
14
|
#default zookeeper connection options
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
DEFAULTS_HERMANN_OPTS = {
|
16
|
+
'zookeeper.session.timeout.ms' => '400',
|
17
|
+
'zookeeper.sync.time.ms' => '200',
|
18
|
+
'auto.commit.interval.ms' => '1000'
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
DEFAULT_CONSUMER_OPTIONS = {
|
22
|
+
:do_retry => true,
|
23
|
+
:max_retries => 3,
|
24
|
+
:backoff_time_sec => 1,
|
25
|
+
:logger => nil
|
26
|
+
}.freeze
|
20
27
|
|
21
28
|
# Instantiate JavaSimpleConsumer
|
22
29
|
#
|
@@ -27,14 +34,20 @@ module Hermann
|
|
27
34
|
# @params [String] Kafka topic
|
28
35
|
#
|
29
36
|
# @params [Hash] kafka options for consumer
|
30
|
-
# @option opts [Fixnum]
|
37
|
+
# @option opts [Fixnum] :backoff_time_sec Time to sleep between consume retries, defaults to 1sec
|
31
38
|
# @option opts [Boolean] :do_retry Retry consume attempts if exceptions are thrown, defaults to true
|
39
|
+
# @option opts [Fixnum] :max_retries Number of max_retries to retry #consume when it throws an exception
|
40
|
+
# @option opts [Logger] :logger Pass in a Logger
|
32
41
|
def initialize(zookeepers, groupId, topic, opts={})
|
33
|
-
config
|
34
|
-
@consumer
|
35
|
-
@topic
|
36
|
-
|
37
|
-
|
42
|
+
config = create_config(zookeepers, groupId)
|
43
|
+
@consumer = ConsumerUtil::Consumer.createJavaConsumerConnector(config)
|
44
|
+
@topic = topic
|
45
|
+
|
46
|
+
options = DEFAULT_CONSUMER_OPTIONS.merge(opts)
|
47
|
+
@backoff_time_sec = options[:backoff_time_sec]
|
48
|
+
@do_retry = options[:do_retry]
|
49
|
+
@max_retries = options[:max_retries]
|
50
|
+
@logger = options[:logger]
|
38
51
|
end
|
39
52
|
|
40
53
|
# Shuts down the various threads created by createMessageStreams
|
@@ -63,14 +76,13 @@ module Hermann
|
|
63
76
|
message = it.next.message
|
64
77
|
yield String.from_java_bytes(message)
|
65
78
|
end
|
66
|
-
rescue
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
if retry?
|
71
|
-
sleep @sleep_time
|
79
|
+
rescue => e
|
80
|
+
if retry? && @max_retries > 0
|
81
|
+
sleep @backoff_time_sec
|
82
|
+
@max_retries -= 1
|
72
83
|
retry
|
73
84
|
else
|
85
|
+
log_exception(e)
|
74
86
|
raise e
|
75
87
|
end
|
76
88
|
end
|
@@ -81,6 +93,13 @@ module Hermann
|
|
81
93
|
@do_retry
|
82
94
|
end
|
83
95
|
|
96
|
+
def log_exception(e)
|
97
|
+
return unless @logger
|
98
|
+
@logger.error("#{self.class.name}#consume exception: #{e.class.name}")
|
99
|
+
@logger.error("Msg: #{e.message}")
|
100
|
+
@logger.error(e.backtrace.join("\n"))
|
101
|
+
end
|
102
|
+
|
84
103
|
# Gets the message stream of the topic. Creates message streams for
|
85
104
|
# a topic and the number of threads requested. In this case the default
|
86
105
|
# number of threads is NUM_THREADS.
|
@@ -106,7 +125,7 @@ module Hermann
|
|
106
125
|
# @raises [RuntimeError] if options does not contain key value strings
|
107
126
|
def create_config(zookeepers, groupId, opts={})
|
108
127
|
config = connect_opts(zookeepers, groupId)
|
109
|
-
options =
|
128
|
+
options = DEFAULTS_HERMANN_OPTS.merge(config).merge(opts)
|
110
129
|
properties = Hermann.package_properties(options)
|
111
130
|
ConsumerUtil::ConsumerConfig.new(properties)
|
112
131
|
end
|
data/lib/hermann/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hermann
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.20.
|
4
|
+
version: 0.20.2
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- R. Tyler Croy
|
8
|
+
- James Way
|
8
9
|
- Stan Campbell
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date:
|
13
|
+
date: 2015-02-23 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -25,20 +26,6 @@ dependencies:
|
|
25
26
|
- - ~>
|
26
27
|
- !ruby/object:Gem::Version
|
27
28
|
version: 0.7.0
|
28
|
-
- !ruby/object:Gem::Dependency
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ~>
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 1.9.4
|
34
|
-
name: zk
|
35
|
-
prerelease: false
|
36
|
-
type: :runtime
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - ~>
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
version: 1.9.4
|
42
29
|
- !ruby/object:Gem::Dependency
|
43
30
|
requirement: !ruby/object:Gem::Requirement
|
44
31
|
requirements:
|
@@ -67,37 +54,10 @@ dependencies:
|
|
67
54
|
- - ~>
|
68
55
|
- !ruby/object:Gem::Version
|
69
56
|
version: 0.1.2
|
70
|
-
- !ruby/object:Gem::Dependency
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ~>
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 3.1.1.0
|
76
|
-
name: ruby-maven
|
77
|
-
prerelease: false
|
78
|
-
type: :development
|
79
|
-
version_requirements: !ruby/object:Gem::Requirement
|
80
|
-
requirements:
|
81
|
-
- - ~>
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version: 3.1.1.0
|
84
|
-
- !ruby/object:Gem::Dependency
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - '>='
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
name: rake
|
91
|
-
prerelease: false
|
92
|
-
type: :development
|
93
|
-
version_requirements: !ruby/object:Gem::Requirement
|
94
|
-
requirements:
|
95
|
-
- - '>='
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: '0'
|
98
57
|
description: Ruby gem for talking to Kafka
|
99
58
|
email:
|
100
59
|
- rtyler.croy@lookout.com
|
60
|
+
- james.way@lookout.com
|
101
61
|
- stan.campbell3@gmail.com
|
102
62
|
executables: []
|
103
63
|
extensions: []
|
@@ -147,7 +107,7 @@ requirements:
|
|
147
107
|
- jar log4j:log4j, 1.2.17
|
148
108
|
- jar com.101tec:zkclient, 0.3
|
149
109
|
rubyforge_project:
|
150
|
-
rubygems_version: 2.
|
110
|
+
rubygems_version: 2.4.5
|
151
111
|
signing_key:
|
152
112
|
specification_version: 3
|
153
113
|
summary: A Kafka consumer/producer gem supporting both MRI and JRuby
|