pulsar_sdk 0.8.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +51 -0
- data/Gemfile +6 -0
- data/LICENSE +201 -0
- data/README.md +107 -0
- data/Rakefile +2 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/protobuf/pulsar_api.pb.rb +710 -0
- data/lib/protobuf/pulsar_api.proto +934 -0
- data/lib/protobuf/validate.rb +41 -0
- data/lib/pulsar_admin.rb +14 -0
- data/lib/pulsar_admin/api.rb +215 -0
- data/lib/pulsar_sdk.rb +55 -0
- data/lib/pulsar_sdk/client.rb +13 -0
- data/lib/pulsar_sdk/client/connection.rb +371 -0
- data/lib/pulsar_sdk/client/connection_pool.rb +79 -0
- data/lib/pulsar_sdk/client/rpc.rb +67 -0
- data/lib/pulsar_sdk/consumer.rb +13 -0
- data/lib/pulsar_sdk/consumer/base.rb +148 -0
- data/lib/pulsar_sdk/consumer/manager.rb +127 -0
- data/lib/pulsar_sdk/consumer/message_tracker.rb +86 -0
- data/lib/pulsar_sdk/options.rb +6 -0
- data/lib/pulsar_sdk/options/base.rb +10 -0
- data/lib/pulsar_sdk/options/connection.rb +51 -0
- data/lib/pulsar_sdk/options/consumer.rb +34 -0
- data/lib/pulsar_sdk/options/producer.rb +14 -0
- data/lib/pulsar_sdk/options/reader.rb +7 -0
- data/lib/pulsar_sdk/options/tls.rb +8 -0
- data/lib/pulsar_sdk/producer.rb +14 -0
- data/lib/pulsar_sdk/producer/base.rb +154 -0
- data/lib/pulsar_sdk/producer/manager.rb +67 -0
- data/lib/pulsar_sdk/producer/message.rb +47 -0
- data/lib/pulsar_sdk/producer/router.rb +100 -0
- data/lib/pulsar_sdk/protocol.rb +8 -0
- data/lib/pulsar_sdk/protocol/frame.rb +53 -0
- data/lib/pulsar_sdk/protocol/lookup.rb +55 -0
- data/lib/pulsar_sdk/protocol/message.rb +55 -0
- data/lib/pulsar_sdk/protocol/namespace.rb +22 -0
- data/lib/pulsar_sdk/protocol/partitioned.rb +54 -0
- data/lib/pulsar_sdk/protocol/reader.rb +67 -0
- data/lib/pulsar_sdk/protocol/structure.rb +93 -0
- data/lib/pulsar_sdk/protocol/topic.rb +74 -0
- data/lib/pulsar_sdk/tweaks.rb +10 -0
- data/lib/pulsar_sdk/tweaks/assign_attributes.rb +30 -0
- data/lib/pulsar_sdk/tweaks/base_command.rb +66 -0
- data/lib/pulsar_sdk/tweaks/binary_heap.rb +133 -0
- data/lib/pulsar_sdk/tweaks/clean_inspect.rb +15 -0
- data/lib/pulsar_sdk/tweaks/time_at_microsecond.rb +27 -0
- data/lib/pulsar_sdk/tweaks/timeout_queue.rb +52 -0
- data/lib/pulsar_sdk/tweaks/wait_map.rb +81 -0
- data/lib/pulsar_sdk/version.rb +3 -0
- data/pulsar_sdk.gemspec +31 -0
- metadata +151 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
module PulsarSdk
|
2
|
+
module Client
|
3
|
+
class ConnectionPool
|
4
|
+
prepend ::PulsarSdk::Tweaks::CleanInspect
|
5
|
+
|
6
|
+
def initialize(opts)
|
7
|
+
raise "opts expected a PulsarSdk::Options::Connection got #{opts.class}" unless opts.is_a?(PulsarSdk::Options::Connection)
|
8
|
+
|
9
|
+
@mutex = Mutex.new
|
10
|
+
@pool = ::PulsarSdk::Tweaks::WaitMap.new
|
11
|
+
|
12
|
+
@options = opts
|
13
|
+
@keepalive = opts.keepalive
|
14
|
+
@connection_timeout = opts.connection_timeout
|
15
|
+
|
16
|
+
@authentication = opts.auth_provider
|
17
|
+
@tls_options = opts.tls_options
|
18
|
+
|
19
|
+
instance_variables.each do |x|
|
20
|
+
remove_instance_variable(x) if instance_variable_get(x).nil?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def fetch(logical_addr, physical_addr)
|
25
|
+
id = (logical_addr || physical_addr).to_s
|
26
|
+
raise 'logical_addr and physical_addr both empty!' if id.empty?
|
27
|
+
|
28
|
+
conn = nil
|
29
|
+
@mutex.synchronize do
|
30
|
+
conn = @pool.find(id)
|
31
|
+
|
32
|
+
if conn.nil? || conn.closed?
|
33
|
+
# REMOVE closed conncetion from pool
|
34
|
+
@pool.delete(id, 0.01) unless conn.nil?
|
35
|
+
|
36
|
+
opts = @options.dup
|
37
|
+
opts.assign_attributes(
|
38
|
+
logical_addr: logical_addr,
|
39
|
+
physical_addr: physical_addr
|
40
|
+
)
|
41
|
+
|
42
|
+
conn = @pool.add(id, ::PulsarSdk::Client::Connection.establish(opts))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
conn
|
47
|
+
end
|
48
|
+
|
49
|
+
def run_checker
|
50
|
+
Thread.new do
|
51
|
+
loop do
|
52
|
+
begin
|
53
|
+
@pool.each do |_k, v|
|
54
|
+
last_ping_at, last_received_at = v.active_status
|
55
|
+
|
56
|
+
case
|
57
|
+
when last_ping_at - last_received_at >= @keepalive * 2
|
58
|
+
v.close
|
59
|
+
when last_ping_at - last_received_at > @keepalive
|
60
|
+
v.ping
|
61
|
+
end
|
62
|
+
end
|
63
|
+
rescue => exp
|
64
|
+
PulsarSdk.logger.error(exp)
|
65
|
+
end
|
66
|
+
|
67
|
+
sleep(1)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def close
|
73
|
+
@pool.clear do |_, v|
|
74
|
+
v.close
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module PulsarSdk
|
2
|
+
module Client
|
3
|
+
class Rpc
|
4
|
+
prepend ::PulsarSdk::Tweaks::CleanInspect
|
5
|
+
|
6
|
+
def initialize(opts)
|
7
|
+
raise "opts expected a PulsarSdk::Options::Connection got #{opts.class}" unless opts.is_a?(PulsarSdk::Options::Connection)
|
8
|
+
|
9
|
+
@opts = opts
|
10
|
+
|
11
|
+
@cnx = ::PulsarSdk::Client::ConnectionPool.new(opts).tap {|x| x.run_checker}
|
12
|
+
|
13
|
+
@producer_id = 0
|
14
|
+
@consumer_id = 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def connection(logical_addr = nil, physical_addr = nil)
|
18
|
+
logical_addr ||= @opts.logical_addr
|
19
|
+
@cnx.fetch(logical_addr, physical_addr)
|
20
|
+
end
|
21
|
+
|
22
|
+
def lookup(topic)
|
23
|
+
@lookup_service ||= ::PulsarSdk::Protocol::Lookup.new(self, @opts.logical_addr)
|
24
|
+
@lookup_service.lookup(topic)
|
25
|
+
end
|
26
|
+
|
27
|
+
def namespace_topics(namespace)
|
28
|
+
@namespace_service ||= ::PulsarSdk::Protocol::Namespace.new(self)
|
29
|
+
@namespace_service.topics(namespace)
|
30
|
+
end
|
31
|
+
|
32
|
+
def partition_topics(topic)
|
33
|
+
::PulsarSdk::Protocol::Partitioned.new(self, topic)&.partitions || []
|
34
|
+
end
|
35
|
+
|
36
|
+
def request(physical_addr, logical_addr, cmd)
|
37
|
+
connection(physical_addr, logical_addr).request(cmd, nil, true)
|
38
|
+
end
|
39
|
+
|
40
|
+
def request_any_broker(cmd)
|
41
|
+
connection.request(cmd)
|
42
|
+
end
|
43
|
+
|
44
|
+
def close
|
45
|
+
@cnx.close
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_producer(opts)
|
49
|
+
raise "opts expected a PulsarSdk::Options::Producer got #{opts.class}" unless opts.is_a?(PulsarSdk::Options::Producer)
|
50
|
+
# FIXME check if connection ready
|
51
|
+
::PulsarSdk::Producer.create(self, opts)
|
52
|
+
end
|
53
|
+
|
54
|
+
def subscribe(opts)
|
55
|
+
raise "opts expected a PulsarSdk::Options::Consumer got #{opts.class}" unless opts.is_a?(PulsarSdk::Options::Consumer)
|
56
|
+
# FIXME check if connection ready
|
57
|
+
consumer = ::PulsarSdk::Consumer.create(self, opts)
|
58
|
+
|
59
|
+
consumer
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_reader(opts = {})
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'pulsar_sdk/consumer/base'
|
2
|
+
require 'pulsar_sdk/consumer/message_tracker'
|
3
|
+
require 'pulsar_sdk/consumer/manager'
|
4
|
+
|
5
|
+
module PulsarSdk
|
6
|
+
module Consumer
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def create(client, opts)
|
10
|
+
PulsarSdk::Consumer::Manager.new(client, opts)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
module PulsarSdk
|
2
|
+
module Consumer
|
3
|
+
class Base
|
4
|
+
attr_reader :consumer_id, :topic
|
5
|
+
|
6
|
+
def initialize(client, message_tracker, opts)
|
7
|
+
@opts = opts
|
8
|
+
@topic = @opts.topic
|
9
|
+
@message_tracker = message_tracker
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
def grab_cnx
|
14
|
+
@prefetch = @opts.prefetch
|
15
|
+
@fetched = 0
|
16
|
+
@capacity = 0
|
17
|
+
|
18
|
+
@conn = @client.connection(*@client.lookup(@topic))
|
19
|
+
@established = true
|
20
|
+
|
21
|
+
@seq_generator = SeqGenerator.new(@conn.seq_generator)
|
22
|
+
|
23
|
+
@consumer_id = @seq_generator.new_consumer_id
|
24
|
+
@consumer_name = @opts.name
|
25
|
+
@subscription_name = @opts.subscription_name
|
26
|
+
|
27
|
+
result = init_consumer
|
28
|
+
@consumer_name = result.consumerName unless result.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
def increase_fetched(n = 1)
|
32
|
+
@fetched += n
|
33
|
+
end
|
34
|
+
|
35
|
+
def flow
|
36
|
+
base_cmd = Pulsar::Proto::BaseCommand.new(
|
37
|
+
type: Pulsar::Proto::BaseCommand::Type::FLOW,
|
38
|
+
flow: Pulsar::Proto::CommandFlow.new(
|
39
|
+
messagePermits: @prefetch
|
40
|
+
)
|
41
|
+
)
|
42
|
+
|
43
|
+
execute(base_cmd)
|
44
|
+
|
45
|
+
@capacity += @prefetch
|
46
|
+
end
|
47
|
+
|
48
|
+
def subscription
|
49
|
+
@subscription_name
|
50
|
+
end
|
51
|
+
|
52
|
+
def unsubscribe
|
53
|
+
base_cmd = Pulsar::Proto::BaseCommand.new(
|
54
|
+
type: Pulsar::Proto::BaseCommand::Type::UNSUBSCRIBE,
|
55
|
+
unsubscribe: Pulsar::Proto::CommandUnsubscribe.new
|
56
|
+
)
|
57
|
+
execute_async(base_cmd)
|
58
|
+
end
|
59
|
+
|
60
|
+
def flow_if_need
|
61
|
+
return if @capacity > 0 && [@prefetch / 2, 1].max.ceil < (@capacity - @fetched)
|
62
|
+
flow
|
63
|
+
end
|
64
|
+
|
65
|
+
def close
|
66
|
+
base_cmd = Pulsar::Proto::BaseCommand.new(
|
67
|
+
type: Pulsar::Proto::BaseCommand::Type::CLOSE_CONSUMER,
|
68
|
+
close_consumer: Pulsar::Proto::CommandCloseConsumer.new(
|
69
|
+
consumer_id: @consumer_id
|
70
|
+
)
|
71
|
+
)
|
72
|
+
execute(base_cmd) unless disconnect?
|
73
|
+
|
74
|
+
remove_handler!
|
75
|
+
end
|
76
|
+
|
77
|
+
def disconnect?
|
78
|
+
!@established
|
79
|
+
end
|
80
|
+
|
81
|
+
def execute(cmd)
|
82
|
+
write(cmd)
|
83
|
+
end
|
84
|
+
|
85
|
+
def execute_async(cmd)
|
86
|
+
write(cmd, nil, true)
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def write(cmd, *args)
|
91
|
+
grab_cnx if disconnect?
|
92
|
+
cmd.seq_generator = @seq_generator
|
93
|
+
|
94
|
+
@conn.request(cmd, *args)
|
95
|
+
end
|
96
|
+
|
97
|
+
def bind_handler!
|
98
|
+
handler = Proc.new do |cmd, meta_and_payload|
|
99
|
+
cmd.nil? ? (@established = false) : @message_tracker.receive(cmd, meta_and_payload)
|
100
|
+
end
|
101
|
+
@conn.consumer_handlers.add(@consumer_id, handler)
|
102
|
+
end
|
103
|
+
|
104
|
+
def remove_handler!
|
105
|
+
@conn.consumer_handlers.delete(@consumer_id)
|
106
|
+
|
107
|
+
true
|
108
|
+
end
|
109
|
+
|
110
|
+
def init_consumer
|
111
|
+
bind_handler!
|
112
|
+
|
113
|
+
base_cmd = Pulsar::Proto::BaseCommand.new(
|
114
|
+
type: Pulsar::Proto::BaseCommand::Type::SUBSCRIBE,
|
115
|
+
subscribe: Pulsar::Proto::CommandSubscribe.new(
|
116
|
+
topic: @opts.topic,
|
117
|
+
subscription: @opts.subscription_name,
|
118
|
+
subType: @opts.subscription_type,
|
119
|
+
consumer_name: @consumer_name,
|
120
|
+
replicate_subscription_state: @opts.replicate_subscription_state,
|
121
|
+
read_compacted: @opts.read_compacted
|
122
|
+
)
|
123
|
+
)
|
124
|
+
result = execute(base_cmd)
|
125
|
+
|
126
|
+
@message_tracker.add_consumer(self)
|
127
|
+
|
128
|
+
result.consumerStatsResponse
|
129
|
+
end
|
130
|
+
|
131
|
+
# NOTE keep consumer_id and sequence_id static
|
132
|
+
class SeqGenerator
|
133
|
+
def initialize(seq_g)
|
134
|
+
@seq_g = seq_g
|
135
|
+
@consumer_id = @seq_g.new_consumer_id
|
136
|
+
end
|
137
|
+
|
138
|
+
def new_consumer_id
|
139
|
+
@consumer_id
|
140
|
+
end
|
141
|
+
|
142
|
+
def method_missing(method)
|
143
|
+
@seq_g.public_send(method)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module PulsarSdk
|
2
|
+
module Consumer
|
3
|
+
class Manager
|
4
|
+
prepend ::PulsarSdk::Tweaks::CleanInspect
|
5
|
+
|
6
|
+
def initialize(client, opts)
|
7
|
+
raise "client expected a PulsarSdk::Client::Rpc got #{client.class}" unless client.is_a?(PulsarSdk::Client::Rpc)
|
8
|
+
raise "opts expected a PulsarSdk::Options::Consumer got #{opts.class}" unless opts.is_a?(PulsarSdk::Options::Consumer)
|
9
|
+
|
10
|
+
@topic = opts.topic
|
11
|
+
|
12
|
+
@listen_wait = opts.listen_wait
|
13
|
+
|
14
|
+
@message_tracker = ::PulsarSdk::Consumer::MessageTracker.new(opts.redelivery_delay)
|
15
|
+
|
16
|
+
@consumers = init_consumer_by(client, opts)
|
17
|
+
|
18
|
+
@stoped = false
|
19
|
+
end
|
20
|
+
|
21
|
+
# NOTE some topic maybe have large permits if there is no message
|
22
|
+
def flow
|
23
|
+
ensure_connection
|
24
|
+
@consumers.each(&:flow_if_need)
|
25
|
+
end
|
26
|
+
|
27
|
+
# NOTE all consumers has same name
|
28
|
+
def subscription
|
29
|
+
ensure_connection
|
30
|
+
@consumers.find(&:subscription)
|
31
|
+
end
|
32
|
+
|
33
|
+
def unsubscribe
|
34
|
+
ensure_connection
|
35
|
+
@consumers.each(&:unsubscribe)
|
36
|
+
end
|
37
|
+
|
38
|
+
# if timeout is nil wait until get message
|
39
|
+
def receive(timeout = nil)
|
40
|
+
ensure_connection
|
41
|
+
@message_tracker.shift(timeout)
|
42
|
+
end
|
43
|
+
|
44
|
+
def listen(autoack = false)
|
45
|
+
raise 'listen require passing a block!!' if !block_given?
|
46
|
+
ensure_connection
|
47
|
+
|
48
|
+
loop do
|
49
|
+
return if @stoped
|
50
|
+
|
51
|
+
flow
|
52
|
+
|
53
|
+
cmd, msg = receive(@listen_wait)
|
54
|
+
return if msg.nil?
|
55
|
+
|
56
|
+
result = yield cmd, msg
|
57
|
+
|
58
|
+
if autoack && result == false
|
59
|
+
msg.nack
|
60
|
+
next
|
61
|
+
end
|
62
|
+
|
63
|
+
msg.ack if autoack
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def close
|
68
|
+
PulsarSdk.logger.debug(__method__){"current @stoped #{@stoped} close now!"}
|
69
|
+
return if @stoped
|
70
|
+
@consumers.each(&:close)
|
71
|
+
@stoped = true
|
72
|
+
|
73
|
+
@message_tracker.close
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
def init_consumer_by(client, opts)
|
78
|
+
topics = []
|
79
|
+
|
80
|
+
case
|
81
|
+
when !opts.topic.nil?
|
82
|
+
PulsarSdk.logger.debug("#{__method__}:single topic"){opts.topic}
|
83
|
+
|
84
|
+
topics << ::PulsarSdk::Protocol::Topic.parse(opts.topic).to_s
|
85
|
+
when !Array(opts.topics).size.zero?
|
86
|
+
PulsarSdk.logger.debug("#{__method__}:multiple topics"){opts.topics}
|
87
|
+
|
88
|
+
opts.topics.each do |topic|
|
89
|
+
topics << ::PulsarSdk::Protocol::Topic.parse(topic).to_s
|
90
|
+
end
|
91
|
+
when !opts.topics_pattern.nil?
|
92
|
+
PulsarSdk.logger.debug("#{__method__}:pattern topic"){opts.topics_pattern}
|
93
|
+
|
94
|
+
tn = ::PulsarSdk::Protocol::Topic.parse(opts.topics_pattern)
|
95
|
+
pattern = Regexp.compile(tn.topic == '*' ? '^*' : tn.topic)
|
96
|
+
client.namespace_topics(tn.namespace).each do |topic|
|
97
|
+
topics << topic if pattern.match(topic)
|
98
|
+
end
|
99
|
+
else
|
100
|
+
raise 'You must provide one topic by 「topic」or「topics」or「topics_pattern」'
|
101
|
+
end
|
102
|
+
|
103
|
+
PulsarSdk.logger.debug("#{__method__}:topics to initialize"){topics}
|
104
|
+
|
105
|
+
topics.flat_map do |topic|
|
106
|
+
partition_topics = client.partition_topics(topic)
|
107
|
+
|
108
|
+
partition_topics.map do |x|
|
109
|
+
opts_ = opts.dup
|
110
|
+
|
111
|
+
opts_.topic = x
|
112
|
+
PulsarSdk::Consumer::Base.new(client, @message_tracker, opts_).tap do |consumer|
|
113
|
+
consumer.grab_cnx
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def ensure_connection
|
120
|
+
@consumers.each do |consumer|
|
121
|
+
next unless consumer.disconnect?
|
122
|
+
consumer.grab_cnx
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module PulsarSdk
|
2
|
+
module Consumer
|
3
|
+
class MessageTracker
|
4
|
+
|
5
|
+
class ReceivedQueue < PulsarSdk::Tweaks::TimeoutQueue; end
|
6
|
+
class NackQueue < PulsarSdk::Tweaks::BinaryHeap; end
|
7
|
+
|
8
|
+
def initialize(redelivery_delay)
|
9
|
+
@redelivery_delay = redelivery_delay
|
10
|
+
@received_message = ReceivedQueue.new
|
11
|
+
@acknowledge_message = NackQueue.new {|parent, child| child[:ack_at] <=> parent[:ack_at] }
|
12
|
+
@consumers = {}
|
13
|
+
|
14
|
+
@tracker = track
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_consumer(consumer)
|
18
|
+
@consumers[consumer.consumer_id] = consumer
|
19
|
+
end
|
20
|
+
|
21
|
+
def receive(*args)
|
22
|
+
@received_message.add(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def shift(timeout)
|
26
|
+
cmd, meta_and_payload = @received_message.pop(timeout)
|
27
|
+
|
28
|
+
return if cmd.nil?
|
29
|
+
|
30
|
+
message = PulsarSdk::Protocol::Structure.new(meta_and_payload).decode
|
31
|
+
|
32
|
+
consumer_id = cmd.message&.consumer_id
|
33
|
+
real_consumer = @consumers[consumer_id]
|
34
|
+
|
35
|
+
message.assign_attributes(
|
36
|
+
message_id: cmd.message&.message_id,
|
37
|
+
consumer_id: consumer_id,
|
38
|
+
topic: real_consumer&.topic,
|
39
|
+
ack_handler: ack_handler
|
40
|
+
)
|
41
|
+
|
42
|
+
real_consumer&.increase_fetched
|
43
|
+
|
44
|
+
[cmd, message]
|
45
|
+
end
|
46
|
+
|
47
|
+
def close
|
48
|
+
@received_message.close
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def track
|
53
|
+
Thread.new do
|
54
|
+
loop do
|
55
|
+
while item = @acknowledge_message.top
|
56
|
+
break if item[:ack_at] > Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
57
|
+
begin
|
58
|
+
PulsarSdk.logger.debug('acknowledge message'){"#{Process.clock_gettime(Process::CLOCK_MONOTONIC)}: #{item[:cmd].type} --> #{item[:ack_at]}"}
|
59
|
+
execute_async(item[:cmd])
|
60
|
+
@acknowledge_message.shift
|
61
|
+
rescue => exp
|
62
|
+
PulsarSdk.logger.error('Error occur when acknowledge message'){exp}
|
63
|
+
PulsarSdk.logger.error('Error occur when acknowledge message'){item}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
sleep(1)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def ack_handler
|
72
|
+
Proc.new do |cmd|
|
73
|
+
current_clock = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
74
|
+
ack_at = cmd.typeof_ack? ? (current_clock - 1) : (current_clock + @redelivery_delay.to_i)
|
75
|
+
@acknowledge_message.insert(cmd: cmd, ack_at: ack_at)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def execute_async(cmd)
|
80
|
+
consumer = @consumers[cmd.get_consumer_id]
|
81
|
+
|
82
|
+
consumer.execute_async(cmd)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|