istox 0.1.120 → 0.1.121

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,37 @@
1
+ require 'redis'
2
+
3
+ module Istox
4
+ class RedisBoot
5
+ class << self
6
+
7
+ def set(k,v)
8
+ redis.set(k,v)
9
+ end
10
+
11
+ def keys(p)
12
+ redis.keys
13
+ end
14
+
15
+ def del(k)
16
+ redis.del(k)
17
+ end
18
+
19
+ def flushdb
20
+ redis.flushdb
21
+ end
22
+
23
+ def incr(k)
24
+ redis.incr(k)
25
+ end
26
+
27
+ private
28
+
29
+ def redis
30
+ @redis ||= Redis.new(
31
+ url: ENV["REDIS_URL"] || 'redis://127.0.0.1',
32
+ db: 4
33
+ )
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,140 @@
1
+ require 'istox/helpers/logger'
2
+
3
+ module Istox
4
+ # Publisher is relying on BunnyBoot to publish message, please make sure BunnyBoot is initalised properly first during runtime.
5
+ class Subscriber
6
+ class << self
7
+
8
+ # optionally can pass in consumer_key for single subscription / consumer_keys for multiple subcriptions
9
+ # consumer_key must be defined in amqp.yml
10
+ # if nothing pass in it will auto subscribe to all available consumers defined in amqp.yml queues key
11
+ def subscribe
12
+ return if @flag
13
+
14
+ @mutex = Mutex.new unless @mutex.present?
15
+ @mutex.synchronize do
16
+ return if @flag
17
+ =begin
18
+ subscribing_consumer_keys = consumer_keys.present? ? consumer_keys : []
19
+
20
+ if subscribing_consumer_keys.empty? && consumer_key.nil?
21
+ subscribing_consumer_keys = ::Istox::BunnyBoot.queues_keys_for_subscribe
22
+ elsif subscribing_consumer_keys.empty? && consumer_key.present?
23
+ subscribing_consumer_keys = [consumer_key]
24
+ end
25
+ =end
26
+ subscribing_consumer_keys = ::Istox::BunnyBoot.queues_keys_for_subscribe
27
+ subscribing_consumer_keys.each do |key|
28
+ log.debug "Do subscribe key #{key.to_s}"
29
+ do_subscribe(key.to_s)
30
+ end
31
+
32
+ @flag = true
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def do_subscribe(consumer_key)
39
+ manual_ack = ::Istox::BunnyBoot.queue_manual_ack? consumer_key
40
+
41
+ # Create Channel with specified pool_size and prefetch
42
+ pool_size = ::Istox::BunnyBoot.channel_pool_size consumer_key
43
+ prefetch = ::Istox::BunnyBoot.channel_prefetch consumer_key
44
+ active_channel = ::Istox::BunnyBoot.channel(::Istox::BunnyBoot.connection, pool_size: pool_size, prefetch: prefetch)
45
+
46
+ # Declare exchange
47
+ exchange_name = ::Istox::BunnyBoot.exchange_name consumer_key
48
+ exchange_retry_name = if manual_ack
49
+ "#{exchange_name}.retry"
50
+ else
51
+ nil
52
+ end
53
+ exchange_name = ::Istox::BunnyBoot.exchange_name consumer_key
54
+ exchange_durable = ::Istox::BunnyBoot.exchange_durable? exchange_name
55
+ exchange_type = ::Istox::BunnyBoot.exchange_type exchange_name
56
+ case exchange_type
57
+ when 'fanout'
58
+ exchange = active_channel.fanout(exchange_name, durable: exchange_durable)
59
+ exchange_retry = if exchange_retry_name.nil?
60
+ nil
61
+ else
62
+ active_channel.fanout(exchange_retry_name, durable: exchange_durable)
63
+ end
64
+ when 'direct'
65
+ exchange = active_channel.direct(exchange_name, durable: exchange_durable)
66
+ exchange_retry = if exchange_retry_name.nil?
67
+ nil
68
+ else
69
+ active_channel.direct(exchange_retry_name, durable: exchange_durable)
70
+ end
71
+ else
72
+ raise "Exchange type #{exchange_type} is not valid/supported."
73
+ end
74
+
75
+ # Declare queue and bind to exchange
76
+ queue_name = ::Istox::BunnyBoot.queue_name consumer_key
77
+ queue_durable = ::Istox::BunnyBoot.queue_durable? consumer_key
78
+ queue_options = {}
79
+ queue_options[:routing_key] = queue_name if exchange_type == 'direct'
80
+ queue = active_channel.queue(queue_name, durable: queue_durable).bind(exchange, queue_options)
81
+ active_channel.queue("#{queue_name}.retry", arguments: {
82
+ 'x-dead-letter-exchange': exchange.name,
83
+ 'x-dead-letter-routing-key': "#{queue_name}",
84
+ 'x-message-ttl': (::Istox::BunnyBoot.queue_retry_gap consumer_key)
85
+ }).bind(exchange_retry, routing_key: "#{queue_name}.retry") if manual_ack
86
+
87
+ # Subscribe queue
88
+ queue.subscribe manual_ack: manual_ack do |delivery_info, metadata, payload|
89
+ log.debug "Delivery_info: #{delivery_info}"
90
+ log.debug "Metadata: #{metadata}"
91
+ log.debug "Payload: #{payload}"
92
+ log.debug "Redelivered Message?: #{delivery_info.redelivered}"
93
+
94
+ # For retried message, if reaching retry count limit, return ack anyway
95
+ # If retry limit is -1, no retry limit
96
+ # TODO: No matter the amount of retry limit, send cloudwatch critical alarm if fails after 3 times of retry
97
+ retry_limit = ::Istox::BunnyBoot.queue_retry_limit consumer_key
98
+ unless metadata[:priority] && retry_limit != -1 && metadata[:priority] >= retry_limit
99
+ processing_paylod = JSON.parse(payload)
100
+ payload_object = ::Istox::CommonHelper.to_open_struct(processing_paylod)
101
+
102
+ ruby_class = ::Istox::BunnyBoot.ruby_class consumer_key
103
+ klass = Object.const_get(
104
+ '::' + (ruby_class.nil? ? "#{consumer_key.to_s.underscore}_consumer" : ruby_class).camelize
105
+ )
106
+
107
+ log.info "Processing in consumer: #{klass}, paylod: #{payload_object.to_h.inspect}"
108
+
109
+ klass.new.process(payload_object, metadata, delivery_info)
110
+ end
111
+ # active_channel.ack(delivery_info.delivery_tag) if manual_ack
112
+ rescue StandardError => e
113
+ log.error(e)
114
+ if manual_ack
115
+ retry_count = if metadata[:priority].nil?
116
+ 1
117
+ else
118
+ metadata[:priority] + 1
119
+ end
120
+ log.debug "Consumer Retry count: #{retry_count}"
121
+ # @option opts [Integer] :priority Message priority, 0 to 9. Not used by RabbitMQ, only applications
122
+ # here we adopt the unused priority as remaining retry_count
123
+ ::Istox::BunnyBoot.publish(exchange_retry, payload_object, routing_key: "#{queue_name}.retry", priority: retry_count, type: 'dlx')
124
+ end
125
+ =begin
126
+ # For redelivered message, call 'reject' not 'nack' in order to reschedule message to tail not head of queue
127
+ if delivery_info.redelivered
128
+ active_channel.reject(delivery_info.delivery_tag, true)
129
+ else
130
+ active_channel.nack(delivery_info.delivery_tag, false, true)
131
+ end
132
+ =end
133
+
134
+ ensure
135
+ active_channel.ack(delivery_info.delivery_tag) if manual_ack
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
data/lib/istox/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Istox
2
- VERSION = '0.1.120'.freeze
2
+ VERSION = '0.1.121'.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.120
4
+ version: 0.1.121
5
5
  platform: ruby
6
6
  authors:
7
7
  - Siong Leng
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-31 00:00:00.000000000 Z
11
+ date: 2020-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: hashie
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 3.5.7
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 3.5.7
111
+ - !ruby/object:Gem::Dependency
112
+ name: redis-rails
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 5.0.2
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 5.0.2
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: listen
99
127
  requirement: !ruby/object:Gem::Requirement
@@ -389,8 +417,10 @@ files:
389
417
  - lib/istox/helpers/order_book_prorate.rb
390
418
  - lib/istox/helpers/publisher.rb
391
419
  - lib/istox/helpers/rate_limit.rb
420
+ - lib/istox/helpers/redis.rb
392
421
  - lib/istox/helpers/regex_helper.rb
393
422
  - lib/istox/helpers/result_handler.rb
423
+ - lib/istox/helpers/subscriber.rb
394
424
  - lib/istox/helpers/vault.rb
395
425
  - lib/istox/interfaces/chainhub/transaction.rb
396
426
  - lib/istox/models/blockchain_receipt.rb
@@ -415,7 +445,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
415
445
  - !ruby/object:Gem::Version
416
446
  version: '0'
417
447
  requirements: []
418
- rubygems_version: 3.0.6
448
+ rubygems_version: 3.0.3
419
449
  signing_key:
420
450
  specification_version: 4
421
451
  summary: istox backend shared gem