hermann 0.20.1-java → 0.20.2-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 023ddf7f24fc065abbf63cf567200781f4f57689
4
- data.tar.gz: 19a5ba3a7bbde50e1dbcde96d5da7d380fba989f
3
+ metadata.gz: 8c9f75e450674ab97eae2977213013ec3c22f9e6
4
+ data.tar.gz: 4a3fb3da2b3c6776172d9b550bfcfedaa7da9066
5
5
  SHA512:
6
- metadata.gz: f96fc2c6a866c4e6fdb5b7e28f5bcc16354011ec350be4b9481e5895cba5e0899a56bd31d917f100b164333cf351560f144d290f6fbe86fc2a1b21f248a061f4
7
- data.tar.gz: 5ee23b2de80fea374fbf896238c0c1e92bfda576faa9e2f9175b7d6d6c59a6c44a20775431187fa82158cc9dd8f9962c5851d69af70d29bfd29b8333865a93b4
6
+ metadata.gz: 3a0003509edf79b5c388d6fe22c496124613a008dc055e2889fcda5d439b825f0a65e22f860d0598597d1e999745f98df6659638cf6e27ec8b3c284ae3258a3b
7
+ data.tar.gz: ba0fd53110ede6966aa1a3fb460a520c4299e20bebd784f9d92cc868001f24cdbaee53b206061743fcfff528ec92dad4e86d8288999db16f36b1b01ab49ce06b
@@ -21,11 +21,9 @@ module Hermann
21
21
  #
22
22
  # @params [String] comma separated zookeeper list
23
23
  #
24
- # @params [Hash] options for consumer
24
+ # @params [Hash] options for Consumer
25
25
  # @option opts [String] :brokers (for MRI) Comma separated list of brokers
26
- # @option opts [String] :partition (for MRI) The kafka partition
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
- require 'zk'
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
- ZK.open(zookeepers, {:timeout => timeout}) do |zk|
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 << format_broker_from_znode(node)
96
+ brokers << node
53
97
  end
54
- brokers.compact
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
- # Formats the node data into string
70
- #
71
- # @param [String] node data
72
- #
73
- # @return [String] formatted node data or empty string if error
74
- def format_broker_from_znode(znode)
75
- hash = JSON.parse(znode)
76
- host = hash['host']
77
- port = hash['port']
78
- host && port ? "#{host}:#{port}" : nil
79
- rescue JSON::ParserError
80
- nil
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
@@ -1,6 +1,7 @@
1
1
  require 'hermann'
2
2
  require 'concurrent'
3
3
  require 'json'
4
+ require 'hermann/errors'
4
5
 
5
6
  module Hermann
6
7
  module Provider
@@ -12,11 +12,18 @@ module Hermann
12
12
  NUM_THREADS = 1
13
13
 
14
14
  #default zookeeper connection options
15
- DEFAULTS = {
16
- 'zookeeper.session.timeout.ms' => '400',
17
- 'zookeeper.sync.time.ms' => '200',
18
- 'auto.commit.interval.ms' => '1000'
19
- }.freeze
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] :sleep_time Time to sleep between consume retries, defaults to 1sec
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 = create_config(zookeepers, groupId)
34
- @consumer = ConsumerUtil::Consumer.createJavaConsumerConnector(config)
35
- @topic = topic
36
- @sleep_time = opts.delete(:sleep_time) || 1
37
- @do_retry = opts.delete(:do_retry) || true
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 Exception => e
67
- puts "#{self.class.name}#consume exception: #{e.class.name}"
68
- puts "Msg: #{e.message}"
69
- puts e.backtrace.join("\n")
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 = DEFAULTS.merge(config).merge(opts)
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
@@ -1,3 +1,3 @@
1
1
  module Hermann
2
- VERSION = '0.20.1'
2
+ VERSION = '0.20.2'
3
3
  end
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.1
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: 2014-11-13 00:00:00.000000000 Z
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.2.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