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 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