hermann 0.24.0.0-java → 0.24.1.0-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/ext/hermann/extconf.rb +1 -0
- data/ext/hermann/hermann_lib.c +195 -25
- data/ext/hermann/hermann_lib.h +7 -0
- data/lib/hermann/discovery/metadata.rb +77 -0
- data/lib/hermann/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36258654c7dab0d22f5605f7570e9af0bc1d413f
|
4
|
+
data.tar.gz: 6a76a7fe69d25b7ca81b729ead0bb443fbb89e64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e12d640758271fbc235823e3cb1990c63fc6140160e79ca3b40204ffc3a696a57b92bd4ccc09150b692532ea427147d4ee84c41ba8d5a0939657ba82bb51061
|
7
|
+
data.tar.gz: c9dd57c7ffac7ed14b29b0c76bb2dc048226c381608c772bdef86c653e18ff12b0563268c789929d9964acd339ae66d03afe041fd6ce71869d209487cf63049e
|
data/ext/hermann/extconf.rb
CHANGED
@@ -147,6 +147,7 @@ $LOCAL_LIBS << File.join(librdkafka.path, 'lib', 'librdkafka.a')
|
|
147
147
|
|
148
148
|
have_header('ruby/thread.h')
|
149
149
|
have_header('ruby/intern.h')
|
150
|
+
have_header('ruby/version.h')
|
150
151
|
have_func('rb_thread_blocking_region')
|
151
152
|
have_func('rb_thread_call_without_gvl')
|
152
153
|
|
data/ext/hermann/hermann_lib.c
CHANGED
@@ -33,6 +33,9 @@
|
|
33
33
|
|
34
34
|
#include "hermann_lib.h"
|
35
35
|
|
36
|
+
#ifdef HAVE_RUBY_VERSION_H
|
37
|
+
#include <ruby/version.h>
|
38
|
+
#endif
|
36
39
|
|
37
40
|
/* how long to let librdkafka block on the socket before returning back to the interpreter.
|
38
41
|
* essentially defines how long we wait before consumer_consume_stop_callback() can fire */
|
@@ -120,7 +123,7 @@ static void msg_delivered(rd_kafka_t *rk,
|
|
120
123
|
/* call back into our Hermann::Result if it exists, discarding the
|
121
124
|
* return value
|
122
125
|
*/
|
123
|
-
if (NULL != push_ctx->result) {
|
126
|
+
if (NULL != (void *)push_ctx->result) {
|
124
127
|
rb_funcall(push_ctx->result,
|
125
128
|
hermann_result_fulfill_method,
|
126
129
|
2,
|
@@ -153,12 +156,15 @@ static int32_t producer_partitioner_callback(const rd_kafka_topic_t *rkt,
|
|
153
156
|
void *msg_opaque) {
|
154
157
|
/* Pick a random partition */
|
155
158
|
int retry = 0;
|
159
|
+
int32_t partition = RD_KAFKA_PARTITION_UA;
|
160
|
+
|
156
161
|
for (; retry < partition_cnt; retry++) {
|
157
|
-
|
162
|
+
partition = rand() % partition_cnt;
|
158
163
|
if (rd_kafka_topic_partition_available(rkt, partition)) {
|
159
164
|
break; /* this one will do */
|
160
165
|
}
|
161
166
|
}
|
167
|
+
return partition;
|
162
168
|
}
|
163
169
|
|
164
170
|
/**
|
@@ -259,6 +265,7 @@ static void msg_consume(rd_kafka_message_t *rkmessage, HermannInstanceConfig *cf
|
|
259
265
|
// Yield the data to the Consumer's block
|
260
266
|
if (rb_block_given_p()) {
|
261
267
|
VALUE value = rb_str_new((char *)rkmessage->payload, rkmessage->len);
|
268
|
+
rd_kafka_message_destroy(rkmessage);
|
262
269
|
rb_yield(value);
|
263
270
|
}
|
264
271
|
else {
|
@@ -388,15 +395,19 @@ static void *consumer_recv_msg(void *ptr)
|
|
388
395
|
* after every message, to see if the ruby interpreter wants us to exit the
|
389
396
|
* loop.
|
390
397
|
*
|
391
|
-
* @param
|
398
|
+
* @param self The consumer instance
|
392
399
|
*/
|
393
400
|
|
394
|
-
static
|
401
|
+
static VALUE consumer_consume_loop(VALUE self) {
|
402
|
+
HermannInstanceConfig* consumerConfig;
|
395
403
|
rd_kafka_message_t *msg;
|
404
|
+
|
405
|
+
Data_Get_Struct(self, HermannInstanceConfig, consumerConfig);
|
406
|
+
|
396
407
|
TRACER("\n");
|
397
408
|
|
398
409
|
while (consumerConfig->run) {
|
399
|
-
#
|
410
|
+
#if HAVE_RB_THREAD_BLOCKING_REGION && RUBY_API_VERSION_MAJOR < 2
|
400
411
|
msg = (rd_kafka_message_t *) rb_thread_blocking_region((rb_blocking_function_t *) consumer_recv_msg,
|
401
412
|
consumerConfig,
|
402
413
|
consumer_consume_stop_callback,
|
@@ -412,9 +423,24 @@ static void consumer_consume_loop(HermannInstanceConfig* consumerConfig) {
|
|
412
423
|
|
413
424
|
if ( msg ) {
|
414
425
|
msg_consume(msg, consumerConfig);
|
415
|
-
rd_kafka_message_destroy(msg);
|
416
426
|
}
|
417
427
|
}
|
428
|
+
|
429
|
+
return Qnil;
|
430
|
+
}
|
431
|
+
|
432
|
+
|
433
|
+
/**
|
434
|
+
* consumer_consume_loop_stop
|
435
|
+
*
|
436
|
+
* called when we're done with the .consume() loop. lets rdkafa cleanup some internal structures
|
437
|
+
*/
|
438
|
+
static VALUE consumer_consume_loop_stop(VALUE self) {
|
439
|
+
HermannInstanceConfig* consumerConfig;
|
440
|
+
Data_Get_Struct(self, HermannInstanceConfig, consumerConfig);
|
441
|
+
|
442
|
+
rd_kafka_consume_stop(consumerConfig->rkt, consumerConfig->partition);
|
443
|
+
return Qnil;
|
418
444
|
}
|
419
445
|
|
420
446
|
/**
|
@@ -446,17 +472,12 @@ static VALUE consumer_consume(VALUE self, VALUE topic) {
|
|
446
472
|
if (rd_kafka_consume_start(consumerConfig->rkt, consumerConfig->partition, consumerConfig->start_offset) == -1) {
|
447
473
|
fprintf(stderr, "%% Failed to start consuming: %s\n",
|
448
474
|
rd_kafka_err2str(rd_kafka_errno2err(errno)));
|
449
|
-
rb_raise(rb_eRuntimeError,
|
475
|
+
rb_raise(rb_eRuntimeError, "%s",
|
450
476
|
rd_kafka_err2str(rd_kafka_errno2err(errno)));
|
451
477
|
return Qnil;
|
452
478
|
}
|
453
479
|
|
454
|
-
|
455
|
-
|
456
|
-
/* Stop consuming */
|
457
|
-
rd_kafka_consume_stop(consumerConfig->rkt, consumerConfig->partition);
|
458
|
-
|
459
|
-
return Qnil;
|
480
|
+
return rb_ensure(consumer_consume_loop, self, consumer_consume_loop_stop, self);
|
460
481
|
}
|
461
482
|
|
462
483
|
|
@@ -575,7 +596,7 @@ static VALUE producer_push_single(VALUE self, VALUE message, VALUE topic, VALUE
|
|
575
596
|
Data_Get_Struct(self, HermannInstanceConfig, producerConfig);
|
576
597
|
|
577
598
|
delivery_ctx->producer = producerConfig;
|
578
|
-
delivery_ctx->result = NULL;
|
599
|
+
delivery_ctx->result = (VALUE) NULL;
|
579
600
|
|
580
601
|
TRACER("producerConfig: %p\n", producerConfig);
|
581
602
|
|
@@ -666,19 +687,56 @@ static VALUE producer_tick(VALUE self, VALUE timeout) {
|
|
666
687
|
events = rd_kafka_poll(conf->rk, timeout_ms);
|
667
688
|
|
668
689
|
if (conf->isErrored) {
|
669
|
-
rb_raise(rb_eStandardError, conf->error);
|
690
|
+
rb_raise(rb_eStandardError, "%s", conf->error);
|
670
691
|
}
|
671
692
|
|
672
693
|
return rb_int_new(events);
|
673
694
|
}
|
674
695
|
|
696
|
+
/*
|
697
|
+
* producer_metadata_request_nogvl
|
698
|
+
*
|
699
|
+
* call rd_kafka_metadata without the GVL held. Note that rd_kafka_metadata is not interruptible,
|
700
|
+
* so in case of interrupt the thread will not respond until timeout_ms is reached.
|
701
|
+
*
|
702
|
+
* rd_kafka_metadata will fill in the ctx->data pointer on success
|
703
|
+
*
|
704
|
+
* @param ptr void* the hermann_metadata_ctx_t
|
705
|
+
*/
|
706
|
+
|
707
|
+
static void *producer_metadata_request_nogvl(void *ptr)
|
708
|
+
{
|
709
|
+
hermann_metadata_ctx_t *ctx = (hermann_metadata_ctx_t*)ptr;
|
710
|
+
|
711
|
+
return (void *) rd_kafka_metadata(ctx->rk,
|
712
|
+
ctx->topic ? 0 : 1,
|
713
|
+
ctx->topic,
|
714
|
+
(const struct rd_kafka_metadata **) &(ctx->data),
|
715
|
+
ctx->timeout_ms);
|
716
|
+
}
|
717
|
+
|
718
|
+
|
719
|
+
static int producer_metadata_request(hermann_metadata_ctx_t *ctx)
|
720
|
+
{
|
721
|
+
int err;
|
722
|
+
|
723
|
+
#if HAVE_RB_THREAD_BLOCKING_REGION && RUBY_API_VERSION_MAJOR < 2
|
724
|
+
err = (int) rb_thread_blocking_region((rb_blocking_function_t *) producer_metadata_request_nogvl, ctx,
|
725
|
+
NULL, NULL);
|
726
|
+
#elif HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
727
|
+
err = (int) rb_thread_call_without_gvl(producer_metadata_request_nogvl, ctx, NULL, NULL);
|
728
|
+
#else
|
729
|
+
err = (int) producer_metadata_request_nogvl(ctx);
|
730
|
+
#endif
|
731
|
+
|
732
|
+
return err;
|
733
|
+
}
|
675
734
|
|
676
735
|
static VALUE producer_connect(VALUE self, VALUE timeout) {
|
677
736
|
HermannInstanceConfig *producerConfig;
|
678
737
|
rd_kafka_resp_err_t err;
|
679
738
|
VALUE result = Qfalse;
|
680
|
-
|
681
|
-
struct rd_kafka_metadata *data = NULL;
|
739
|
+
hermann_metadata_ctx_t md_context;
|
682
740
|
|
683
741
|
Data_Get_Struct(self, HermannInstanceConfig, producerConfig);
|
684
742
|
|
@@ -686,17 +744,19 @@ static VALUE producer_connect(VALUE self, VALUE timeout) {
|
|
686
744
|
producer_init_kafka(self, producerConfig);
|
687
745
|
}
|
688
746
|
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
747
|
+
md_context.rk = producerConfig->rk;
|
748
|
+
md_context.topic = NULL;
|
749
|
+
md_context.data = NULL;
|
750
|
+
md_context.timeout_ms = rb_num2int(timeout);
|
751
|
+
|
752
|
+
err = producer_metadata_request(&md_context);
|
753
|
+
|
694
754
|
TRACER("err: %s (%i)\n", rd_kafka_err2str(err), err);
|
695
755
|
|
696
756
|
if (RD_KAFKA_RESP_ERR_NO_ERROR == err) {
|
697
757
|
TRACER("brokers: %i, topics: %i\n",
|
698
|
-
data->broker_cnt,
|
699
|
-
data->topic_cnt);
|
758
|
+
md_context.data->broker_cnt,
|
759
|
+
md_context.data->topic_cnt);
|
700
760
|
producerConfig->isConnected = 1;
|
701
761
|
result = Qtrue;
|
702
762
|
}
|
@@ -704,11 +764,118 @@ static VALUE producer_connect(VALUE self, VALUE timeout) {
|
|
704
764
|
producerConfig->isErrored = err;
|
705
765
|
}
|
706
766
|
|
707
|
-
|
767
|
+
if ( md_context.data )
|
768
|
+
rd_kafka_metadata_destroy(md_context.data);
|
708
769
|
|
709
770
|
return result;
|
710
771
|
}
|
711
772
|
|
773
|
+
/*
|
774
|
+
* producer_metadata_make_hash
|
775
|
+
*
|
776
|
+
* transform the rd_kafka_metadata structure into a ruby hash. eg:
|
777
|
+
* { :brokers => [ {:id=>0, :host=>"172.20.10.3", :port=>9092} ],
|
778
|
+
* :topics => { "maxwell" => [ {:id=>0, :leader_id=>0, :replica_ids=>[0], :isr_ids=>[0]}]} }
|
779
|
+
*
|
780
|
+
* @param data struct rd_kafka_metadata* data returned from rd_kafka_metadata
|
781
|
+
*/
|
782
|
+
|
783
|
+
static VALUE producer_metadata_make_hash(struct rd_kafka_metadata *data)
|
784
|
+
{
|
785
|
+
int i, j, k;
|
786
|
+
VALUE broker_hash, topic_hash, partition_ary, partition_hash, partition_replica_ary, partition_isr_ary;
|
787
|
+
VALUE hash = rb_hash_new();
|
788
|
+
VALUE brokers = rb_ary_new2(data->broker_cnt);
|
789
|
+
VALUE topics = rb_hash_new();
|
790
|
+
|
791
|
+
for ( i = 0; i < data->broker_cnt; i++ ) {
|
792
|
+
broker_hash = rb_hash_new();
|
793
|
+
rb_hash_aset(broker_hash, ID2SYM(rb_intern("id")), INT2FIX(data->brokers[i].id));
|
794
|
+
rb_hash_aset(broker_hash, ID2SYM(rb_intern("host")), rb_str_new2(data->brokers[i].host));
|
795
|
+
rb_hash_aset(broker_hash, ID2SYM(rb_intern("port")), INT2FIX(data->brokers[i].port));
|
796
|
+
rb_ary_push(brokers, broker_hash);
|
797
|
+
}
|
798
|
+
|
799
|
+
for ( i = 0; i < data->topic_cnt; i++ ) {
|
800
|
+
partition_ary = rb_ary_new2(data->topics[i].partition_cnt);
|
801
|
+
|
802
|
+
for ( j = 0 ; j < data->topics[i].partition_cnt ; j++ ) {
|
803
|
+
VALUE partition_hash = rb_hash_new();
|
804
|
+
rd_kafka_metadata_partition_t *partition = &(data->topics[i].partitions[j]);
|
805
|
+
|
806
|
+
/* id => 1, leader_id => 0 */
|
807
|
+
rb_hash_aset(partition_hash, ID2SYM(rb_intern("id")), INT2FIX(partition->id));
|
808
|
+
rb_hash_aset(partition_hash, ID2SYM(rb_intern("leader_id")), INT2FIX(partition->leader));
|
809
|
+
|
810
|
+
/* replica_ids => [1, 0] */
|
811
|
+
partition_replica_ary = rb_ary_new2(partition->replica_cnt);
|
812
|
+
for ( k = 0 ; k < partition->replica_cnt ; k++ ) {
|
813
|
+
rb_ary_push(partition_replica_ary, INT2FIX(partition->replicas[k]));
|
814
|
+
}
|
815
|
+
rb_hash_aset(partition_hash, ID2SYM(rb_intern("replica_ids")), partition_replica_ary);
|
816
|
+
|
817
|
+
/* isr_ids => [1, 0] */
|
818
|
+
partition_isr_ary = rb_ary_new2(partition->isr_cnt);
|
819
|
+
for ( k = 0 ; k < partition->isr_cnt ; k++ ) {
|
820
|
+
rb_ary_push(partition_isr_ary, INT2FIX(partition->isrs[k]));
|
821
|
+
}
|
822
|
+
rb_hash_aset(partition_hash, ID2SYM(rb_intern("isr_ids")), partition_isr_ary);
|
823
|
+
|
824
|
+
rb_ary_push(partition_ary, partition_hash);
|
825
|
+
}
|
826
|
+
|
827
|
+
rb_hash_aset(topics, rb_str_new2(data->topics[i].topic), partition_ary);
|
828
|
+
}
|
829
|
+
|
830
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("brokers")), brokers);
|
831
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("topics")), topics);
|
832
|
+
return hash;
|
833
|
+
}
|
834
|
+
|
835
|
+
/*
|
836
|
+
* producer_metadata
|
837
|
+
*
|
838
|
+
* make a metadata request to the kafka server, returning a hash
|
839
|
+
* containing a list of brokers and topics.
|
840
|
+
*
|
841
|
+
* @param data struct rd_kafka_metadata* data returned from rd_kafka_metadata
|
842
|
+
*/
|
843
|
+
|
844
|
+
static VALUE producer_metadata(VALUE self, VALUE topicStr, VALUE timeout) {
|
845
|
+
HermannInstanceConfig *producerConfig;
|
846
|
+
rd_kafka_resp_err_t err;
|
847
|
+
hermann_metadata_ctx_t md_context;
|
848
|
+
VALUE result;
|
849
|
+
|
850
|
+
Data_Get_Struct(self, HermannInstanceConfig, producerConfig);
|
851
|
+
|
852
|
+
if (!producerConfig->isInitialized) {
|
853
|
+
producer_init_kafka(self, producerConfig);
|
854
|
+
}
|
855
|
+
|
856
|
+
md_context.rk = producerConfig->rk;
|
857
|
+
md_context.timeout_ms = rb_num2int(timeout);
|
858
|
+
|
859
|
+
if ( !NIL_P(topicStr) ) {
|
860
|
+
Check_Type(topicStr, T_STRING);
|
861
|
+
md_context.topic = rd_kafka_topic_new(producerConfig->rk, StringValuePtr(topicStr), NULL);
|
862
|
+
} else {
|
863
|
+
md_context.topic = NULL;
|
864
|
+
}
|
865
|
+
|
866
|
+
err = producer_metadata_request(&md_context);
|
867
|
+
|
868
|
+
if ( err != RD_KAFKA_RESP_ERR_NO_ERROR ) {
|
869
|
+
// annoyingly, this is always a timeout error -- the rest rdkafka just jams onto STDERR
|
870
|
+
rb_raise( rb_eRuntimeError, "%s", rd_kafka_err2str(err) );
|
871
|
+
} else {
|
872
|
+
result = producer_metadata_make_hash(md_context.data);
|
873
|
+
rd_kafka_metadata_destroy(md_context.data);
|
874
|
+
return result;
|
875
|
+
}
|
876
|
+
|
877
|
+
}
|
878
|
+
|
712
879
|
static VALUE producer_is_connected(VALUE self) {
|
713
880
|
HermannInstanceConfig *producerConfig;
|
714
881
|
|
@@ -1076,4 +1243,7 @@ void Init_hermann_lib() {
|
|
1076
1243
|
|
1077
1244
|
/* Producer.connect */
|
1078
1245
|
rb_define_method(c_producer, "connect", producer_connect, 1);
|
1246
|
+
|
1247
|
+
/* Producer.metadata */
|
1248
|
+
rb_define_method(c_producer, "metadata", producer_metadata, 2);
|
1079
1249
|
}
|
data/ext/hermann/hermann_lib.h
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'hermann_lib'
|
2
|
+
require 'hermann/consumer'
|
3
|
+
|
4
|
+
module Hermann
|
5
|
+
module Discovery
|
6
|
+
class Metadata
|
7
|
+
Broker = Struct.new(:id, :host, :port) do
|
8
|
+
def to_s
|
9
|
+
"#{host}:#{port}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
Topic = Struct.new(:name, :partitions)
|
13
|
+
|
14
|
+
Partition = Struct.new(:id, :leader, :replicas, :insync_replicas, :topic_name) do
|
15
|
+
def consumer(offset=:end)
|
16
|
+
Hermann::Consumer.new(topic_name, brokers: ([leader] + replicas).join(','), partition: id, offset: offset)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
DEFAULT_TIMEOUT_MS = 2_000
|
21
|
+
def initialize(brokers, options = {})
|
22
|
+
raise "this is an MRI api only!" if Hermann.jruby?
|
23
|
+
@internal = Hermann::Lib::Producer.new(brokers)
|
24
|
+
@timeout = options[:timeout] || DEFAULT_TIMEOUT_MS
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# @internal.metadata returns:
|
29
|
+
# {:brokers => [{:id=>3, :host=>"kafka3.alpha4.sac1.zdsys.com", :port=>9092}],
|
30
|
+
# :topics => {"testtopic"=>[{:id=>0, :leader_id=>3, :replica_ids=>[3, 1], :isr_ids=>[3, 1]}}}
|
31
|
+
#
|
32
|
+
def brokers
|
33
|
+
brokers_from_metadata(@internal.metadata(nil, @timeout))
|
34
|
+
end
|
35
|
+
|
36
|
+
def topic(t)
|
37
|
+
get_topics(t)[t]
|
38
|
+
end
|
39
|
+
|
40
|
+
def topics
|
41
|
+
get_topics
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def get_topics(filter_topics = nil)
|
47
|
+
md = @internal.metadata(filter_topics, @timeout)
|
48
|
+
|
49
|
+
broker_hash = brokers_from_metadata(md).inject({}) do |h, broker|
|
50
|
+
h[broker.id] = broker
|
51
|
+
h
|
52
|
+
end
|
53
|
+
|
54
|
+
md[:topics].inject({}) do |topic_hash, arr|
|
55
|
+
topic_name, raw_partitions = *arr
|
56
|
+
partitions = raw_partitions.map do |p|
|
57
|
+
leader = broker_hash[p[:leader_id]]
|
58
|
+
all_replicas = p[:replica_ids].map { |i| broker_hash[i] }
|
59
|
+
isr_replicas = p[:isr_ids].map { |i| broker_hash[i] }
|
60
|
+
Partition.new(p[:id], leader, all_replicas, isr_replicas, topic_name)
|
61
|
+
end
|
62
|
+
|
63
|
+
topic_hash[topic_name] = Topic.new(topic_name, partitions)
|
64
|
+
topic_hash
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def brokers_from_metadata(md)
|
70
|
+
md[:brokers].map do |h|
|
71
|
+
Broker.new(h[:id], h[:host], h[:port])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/hermann/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hermann
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.24.
|
4
|
+
version: 0.24.1.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- R. Tyler Croy
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-06-
|
13
|
+
date: 2015-06-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -60,12 +60,12 @@ dependencies:
|
|
60
60
|
requirements:
|
61
61
|
- - ~>
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: 0.1.
|
63
|
+
version: 0.1.10
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.1.
|
68
|
+
version: 0.1.10
|
69
69
|
prerelease: false
|
70
70
|
type: :runtime
|
71
71
|
description: Ruby gem for talking to Kafka
|
@@ -83,6 +83,7 @@ files:
|
|
83
83
|
- ext/hermann/hermann_lib.h
|
84
84
|
- lib/hermann.rb
|
85
85
|
- lib/hermann/consumer.rb
|
86
|
+
- lib/hermann/discovery/metadata.rb
|
86
87
|
- lib/hermann/discovery/zookeeper.rb
|
87
88
|
- lib/hermann/errors.rb
|
88
89
|
- lib/hermann/java.rb
|
@@ -112,10 +113,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
113
|
- !ruby/object:Gem::Version
|
113
114
|
version: '0'
|
114
115
|
requirements:
|
115
|
-
- jar org.apache.kafka:kafka_2.10, ~>0.8.1.1
|
116
|
+
- jar org.apache.kafka:kafka_2.10, ~>0.8.1.1
|
116
117
|
- jar log4j:log4j, ~>1.2.16
|
117
118
|
rubyforge_project:
|
118
|
-
rubygems_version: 2.4.
|
119
|
+
rubygems_version: 2.4.8
|
119
120
|
signing_key:
|
120
121
|
specification_version: 3
|
121
122
|
summary: A Kafka consumer/producer gem supporting both MRI and JRuby
|