istox 0.1.155.1 → 0.1.156

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- istox (0.1.155)
4
+ istox (0.1.156)
5
5
  amazing_print
6
6
  awesome_print
7
7
  binding_of_caller
@@ -56,6 +56,10 @@ module Istox
56
56
  ch
57
57
  end
58
58
 
59
+ def channel_confirm?(ch)
60
+ ch.using_publisher_confirmations?
61
+ end
62
+
59
63
  def exchange(eid)
60
64
  type = data[:exchanges][eid][:type]
61
65
  name = eid
@@ -254,29 +258,34 @@ module Istox
254
258
 
255
259
  def publish(e, message, options = {})
256
260
  eid = eid e
261
+ # By default:
262
+ # For persistence, if exchange is durable, persistent is enabled
263
+ # For mandatory. if channel is confirmed mode, mandatory is enabled
257
264
  persistent = e.durable?
258
- mandatory = false
265
+ mandatory = channel_confirm? e.channel
266
+ options_dup = options.clone
267
+
259
268
  # Set Mandatory & Persistent flag for non-DLX and non-manual msg
260
- unless %w[dlx manual].include? options[:type]
261
- if options[:routing_key].present?
269
+ unless %w[dlx manual].include? options_dup[:type]
270
+ if options_dup[:routing_key].present?
262
271
  v1 = data['publish'][eid]
263
- v1 = v1[options[:routing_key]] unless v1.nil?
264
- persistent = v1['persistent'] unless v1.nil?
265
- mandatory = v1['mandatory'] unless v1.nil?
272
+ v1 = v1[options_dup[:routing_key]] unless v1.nil? || v1[options_dup[:routing_key]].nil?
273
+ persistent = v1['persistent'] unless v1.nil? || v1['persistent'].nil?
274
+ mandatory = v1['mandatory'] unless v1.nil? || v1['mandatory'].nil?
266
275
  end
267
276
  end
268
- options.merge!(persistent: persistent)
269
- options.merge!(mandatory: mandatory)
277
+ options_dup.merge!(persistent: persistent)
278
+ options_dup.merge!(mandatory: mandatory)
270
279
  # message.merge!(locale: I18n.locale)
271
280
 
272
281
  publisher_interceptors.each do |interceptor|
273
- interceptor.call(message, options)
282
+ interceptor.call(message, options_dup)
274
283
  end
275
284
 
276
285
  message = JSON.dump message
277
- log.debug "Publish options are: #{options}"
286
+ log.debug "Publish options are: #{options_dup}"
278
287
  log.debug "Publish message payload #{message}"
279
- e.publish(message, options)
288
+ e.publish(message, options_dup)
280
289
 
281
290
  options[:message_id]
282
291
  end
@@ -104,7 +104,7 @@ module Istox
104
104
  def channel
105
105
  return @channel[Thread.current.object_id] if @channel.present? && @channel[Thread.current.object_id].present?
106
106
 
107
- log.info "#{Thread.current.object_id} No channel yet, create 2 channels confirm-mode and non-confirm-mode ... ..."
107
+ log.info "Thread<#{Thread.current.object_id}> No channel yet, create 3 channels confirm-mode and non-confirm-mode ... ..."
108
108
  @channel = Hash.new if @channel.nil?
109
109
  @channel[Thread.current.object_id] = Hash.new
110
110
  @channel[Thread.current.object_id]['confirm-0'] = ::Istox::BunnyBoot.channel(connection, confirm: true)
@@ -174,38 +174,61 @@ module Istox
174
174
  # when an unroutable message is returned, the BasicReturn is fired first and then an ack is sent, firing the BasicAck second.
175
175
  # So if the current status is unroutable then we need to make sure that we don't overwrite that status with Success (ack).
176
176
  ex.on_return do |return_info, properties, content|
177
- # log.debug "Got a returned message info: #{return_info}"
178
- # log.debug "Got a returned message properties: #{properties}"
179
- # log.debug "Got a returned message content: #{content}"
180
-
181
- # ::Istox::BunnyBoot.find_trackers("message_id:#{properties[:message_id]}").each do |key|
182
- # log.debug("On_return, update key #{key} in redis on status and retry counter")
183
- # ::Istox::BunnyBoot.update_tracker_by_status(key, 2)
184
- # ::Istox::BunnyBoot.update_tracker_incr_retry(key)
185
- # end
186
-
187
- # publish(return_info[:exchange], return_info[:routing_key], content)
177
+ return_info = return_info.to_hash
178
+ properties = properties.to_hash
179
+ log.debug "Got a returned message info: #{return_info}"
180
+ log.debug "Got a returned message properties: #{properties}"
181
+ log.debug "Got a returned message content: #{content}"
182
+ =begin
183
+ ::Istox::BunnyBoot.find_trackers("message_id:#{properties[:message_id]}").each do |key|
184
+ log.debug("On_return, update key #{key} in redis on status and retry counter")
185
+ ::Istox::BunnyBoot.update_tracker_by_status(key, 2)
186
+ ::Istox::BunnyBoot.update_tracker_incr_retry(key)
187
+ end
188
+ =end
189
+ options = properties.clone
190
+ options[:routing_key] = return_info[:routing_key]
191
+ republish(ex, options, content)
188
192
  end
189
193
 
190
194
  exchanges[id] = ex
191
195
  end
192
196
 
193
- def channel_confirm?(ch)
194
- ch.using_publisher_confirmations?
195
- end
196
-
197
197
  def channel_next_tag(ch)
198
198
  ch.next_publish_seq_no
199
199
  end
200
200
 
201
+ # Handle republish: check and increase retry count
202
+ def republish(ex, options = {}, message)
203
+ options[:headers] = {} if options[:headers].nil?
204
+
205
+ if options[:headers][:republish].nil?
206
+ options[:headers][:republish] = true
207
+ options[:headers][:republish_count] = 1
208
+ else
209
+ options[:headers][:republish_count] += 1
210
+ if options[:headers][:republish_count] > 10
211
+ log.info "Already retry to publish for 10 times, and give up retry"
212
+ log.info "Publish options: #{options.inspect}"
213
+ log.info "Publish to exchange: #{ex.name}"
214
+ log.info "Publish payload: #{message.inspect}"
215
+ return false
216
+ end
217
+ end
218
+
219
+ log.info "Retry to publish for <#{options[:headers][:republish_count]}> times"
220
+ do_publish(ex, options, message)
221
+ end
222
+
201
223
  def do_publish(ex, options = {}, message)
202
224
  eid = ::Istox::BunnyBoot.eid ex
203
225
  ch = ex.channel
204
226
  channel_id = ch.id
205
- confirm = channel_confirm? ch
227
+ confirm = ::Istox::BunnyBoot.channel_confirm? ch
206
228
  mode = confirm_mode eid
207
229
 
208
230
  ::Istox::BunnyBoot.publish(ex, message, options)
231
+ =begin
209
232
  if confirm
210
233
  delivery_tag = channel_next_tag ch
211
234
  if options[:message_id].nil?
@@ -216,36 +239,45 @@ module Istox
216
239
  ::Istox::BunnyBoot.rename_tracker channel_id, options[:delivery_tag], delivery_tag
217
240
  end
218
241
  end
242
+ =end
219
243
 
220
244
  if confirm && mode == 0
221
245
  success = ex.channel.wait_for_confirms
222
246
  if success
223
- ::Istox::BunnyBoot.del_tracker_on_channel channel_id
247
+ log.debug("Message confirm success: remove message for #{channel_id}")
248
+ # ::Istox::BunnyBoot.del_tracker_on_channel channel_id
249
+ # republish(ex, options, message)
250
+ true
224
251
  else
225
252
  ex.channel.nacked_set.each do |n|
226
253
  log.debug("Publish Error: UNACK delivery tag is #{n}, republish message")
227
- options = ::Istox::BunnyBoot.find_tracker_on_channel(channel_id, n, 'options')
228
- options = JSON.parse(options, :symbolize_names => true)
229
- options[:delivery_tag] = n
230
- do_publish(ex, options, message)
254
+ # options = ::Istox::BunnyBoot.find_tracker_on_channel(channel_id, n, 'options')
255
+ # options = JSON.parse(options, :symbolize_names => true)
256
+ # options[:delivery_tag] = n
257
+ republish(ex, options, message)
231
258
  end
232
259
  end
233
260
  end
234
261
  rescue Bunny::ConnectionClosedError => e
235
262
  log.debug "Publish fails due to #{e}"
236
- sleep 1
237
- do_publish(ex,options,message)
263
+ # For network related retry, sleep 2 second before retry
264
+ # Because it may take some seconds for automatic recovery of network
265
+ sleep 2
266
+ republish(ex,options,message)
238
267
  rescue => e
239
- log.debug "Error happens: #{e.message}"
268
+ log.debug "Publish error happening: #{e.message}"
240
269
 
241
270
  # If the error indicates that the channel is already closed
242
271
  # then clear hash @channel and @exchange
272
+ # re-create channel and re-declare exchange on that channel
243
273
  if e.message.include? "cannot use a closed channel"
244
274
  @channel.delete Thread.current.object_id
245
275
  @exchanges.delete Thread.current.object_id
246
276
  ex = exchange(eid)
247
- do_publish(ex, options, message)
248
277
  end
278
+
279
+ # Republish msg
280
+ republish(ex, options, message)
249
281
  end
250
282
  end
251
283
  end
@@ -1,3 +1,3 @@
1
1
  module Istox
2
- VERSION = '0.1.155.1'.freeze
2
+ VERSION = '0.1.156'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: istox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.155.1
4
+ version: 0.1.156
5
5
  platform: ruby
6
6
  authors:
7
7
  - Siong Leng
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-06 00:00:00.000000000 Z
11
+ date: 2020-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: amazing_print
@@ -524,7 +524,7 @@ files:
524
524
  homepage: http://www.abc.com
525
525
  licenses: []
526
526
  metadata: {}
527
- post_install_message:
527
+ post_install_message:
528
528
  rdoc_options: []
529
529
  require_paths:
530
530
  - lib
@@ -539,8 +539,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
539
539
  - !ruby/object:Gem::Version
540
540
  version: '0'
541
541
  requirements: []
542
- rubygems_version: 3.0.6
543
- signing_key:
542
+ rubygems_version: 3.0.8
543
+ signing_key:
544
544
  specification_version: 4
545
545
  summary: istox backend shared gem
546
546
  test_files: []