pulsar_sdk 0.8.8
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 +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
|