pika_que 0.1.5 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: faba17eaee828074e195258b47a178d6e90e8674
4
- data.tar.gz: '04959436f6a2e742b7cea6ba805d4b10f0b187ca'
3
+ metadata.gz: a9831c848341b3207490dfa3050b377cea179be7
4
+ data.tar.gz: 7ac6527b9df72fb0e2ea7741fb2e3cff8c36a684
5
5
  SHA512:
6
- metadata.gz: e5dc91623fa960d2eb130798ee6a1f89ae7fe2a5fe2199201b1c92bea7e55d6b53512a3a14b373d2bb8b7361a14777f57073aa73cfd33dea678fe0d8d2de6690
7
- data.tar.gz: 9c70e4d7229bcb37409144d4905e9a94e9d6690e9a9babb17a2f397d3e384f4d5d48557702edc885c11c5ff09ea8636bf180a0e9f1bc9df73caa57fbff161975
6
+ metadata.gz: 82309e8a1fa9d93b76f5881f5693059720cc0b496b8a0c7ceacdd20594b6ff70b0575ea8bbf5a0117d0ebffe5243d5da734ca13ac5770ddbcd0b3b58792f6394
7
+ data.tar.gz: e7ba16c2307b6c53a89db6d51d1320b6d40c26066871aa1a4c54c63aa4f59ca585c121b2ca69aa1b7a13e2de3b62e0ee98fd743c7e1a7c3a42e7de4c8d5a9236
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
- --format documentation
1
+ --format progress
2
2
  --color
data/README.md CHANGED
@@ -24,12 +24,10 @@ To create a worker:
24
24
  ```ruby
25
25
  class PokeWorker
26
26
  include PikaQue::Worker
27
- from_queue "rocket"
27
+ from_queue "poke"
28
28
 
29
29
  def perform(msg)
30
30
  # do something with msg["greeting"]
31
- # or below for active job
32
- ActiveJob::Base.execute msg
33
31
  ack!
34
32
  end
35
33
  end
@@ -45,21 +43,27 @@ To run server:
45
43
 
46
44
  $ bundle exec pika_que
47
45
 
48
- ### Rails and ActiveJob
49
46
 
50
- Create workers in:
47
+ ### Rails and ActiveJob Quickstart
48
+
49
+ Create workers(not required for ActiveJob) in:
51
50
 
52
51
  app/workers
53
52
 
54
- Create a initializer file `pika_que.rb` in:
53
+ Create a config file `pika_que.yml` in config:
55
54
 
56
- config/initializers
55
+ config/pika_que.yml
57
56
 
58
- ```ruby
59
- # pika_que.rb
57
+ ```yml
58
+ # pika_que.yml
59
+ processors:
60
+ - workers:
61
+ - queue: default
62
+ - queue: mailers
63
+ - queue: your-active-job-queue-name
64
+ - workers:
65
+ - worker: PokeWorker
60
66
 
61
- # setup workers here. see source for available options
62
- PikaQue.config.add_processor(workers: [PokeWorker])
63
67
  ```
64
68
 
65
69
  Set the backend for active job in `config/application.rb`:
@@ -68,9 +72,11 @@ Set the backend for active job in `config/application.rb`:
68
72
 
69
73
  Then run the server.
70
74
 
71
- ## Specs
75
+ For more details, see [wiki](https://github.com/dwkoogt/pika_que/wiki/Rails-Setup).
76
+
77
+ ### Examples
72
78
 
73
- Coming soon. See examples for reference.
79
+ See examples for more usage reference.
74
80
 
75
81
  ## Development
76
82
 
@@ -0,0 +1,62 @@
1
+ # > bundle exec ruby examples/demo_conpriority.rb
2
+ # https://www.rabbitmq.com/consumer-priority.html
3
+ # https://www.rabbitmq.com/blog/2013/12/16/using-consumer-priorities-with-rabbitmq/
4
+ #
5
+ # Consumer Priority
6
+ # HighPriorityWorker will process more messages than LowPriorityWorker
7
+ #
8
+ require 'pika_que'
9
+ require 'pika_que/worker'
10
+ require 'pika_que/runner'
11
+
12
+ PikaQue.logger.level = ::Logger::DEBUG
13
+
14
+ class HighPriorityWorker
15
+ include PikaQue::Worker
16
+ from_queue "pika-que-demo", :priority => 10
17
+
18
+ def perform(msg)
19
+ logger.info "HighPriorityWorker #{msg['msg']}"
20
+ ack!
21
+ end
22
+
23
+ end
24
+
25
+ class LowPriorityWorker
26
+ include PikaQue::Worker
27
+ from_queue "pika-que-demo", :priority => 1
28
+
29
+ def perform(msg)
30
+ logger.info "LowPriorityWorker #{msg['msg']}"
31
+ ack!
32
+ end
33
+
34
+ end
35
+
36
+ PikaQue.config.add_processor(workers: [LowPriorityWorker], concurrency: 10)
37
+ PikaQue.config.add_processor(workers: [HighPriorityWorker], concurrency: 10)
38
+
39
+ runner = PikaQue::Runner.new
40
+
41
+ begin
42
+ runner.run
43
+ rescue => e
44
+ puts e
45
+ puts e.backtrace.join("\n")
46
+ end
47
+
48
+ sleep 3
49
+
50
+ pub = PikaQue::Publisher.new()
51
+
52
+ 600.times do |i|
53
+ pub.publish({ msg: "hello world #{i}" }, routing_key: 'pika-que-demo')
54
+ end
55
+
56
+ sleep 3
57
+
58
+ runner.stop
59
+
60
+ puts "bye"
61
+
62
+ exit 1
@@ -1,35 +1,25 @@
1
1
  # > bundle exec ruby examples/demo_priority.rb
2
+ #
3
+ # Priority Queue with message priorities
4
+ #
2
5
  require 'pika_que'
3
6
  require 'pika_que/worker'
4
7
 
5
8
  PikaQue.logger.level = ::Logger::DEBUG
6
9
 
7
- class HighPriorityWorker
10
+ class PriorityWorker
8
11
  include PikaQue::Worker
9
- from_queue "pika-que-priority", :arguments => { :'x-max-priority' => 10 }, :priority => 10
12
+ from_queue "pika-que-priority", :arguments => { :'x-max-priority' => 10 }
10
13
 
11
14
  def perform(msg)
12
- logger.info msg["msg"]
15
+ logger.info msg['msg']
13
16
  ack!
14
17
  end
15
18
 
16
19
  end
17
20
 
18
- class LowPriorityWorker
19
- include PikaQue::Worker
20
- from_queue "pika-que-priority", :arguments => { :'x-max-priority' => 10 }, :priority => 1
21
-
22
- def perform(msg)
23
- logger.info msg["msg"]
24
- ack!
25
- end
26
-
27
- end
28
-
29
- workers = [HighPriorityWorker,LowPriorityWorker]
30
-
31
21
  begin
32
- pro = PikaQue::Processor.new(workers: workers, concurrency: 10)
22
+ pro = PikaQue::Processor.new(workers: [PriorityWorker], concurrency: 2)
33
23
  pro.start
34
24
  rescue => e
35
25
  puts e
@@ -38,9 +28,10 @@ end
38
28
 
39
29
  sleep 3
40
30
 
31
+ pub = PikaQue::Publisher.new()
41
32
  300.times do |i|
42
- LowPriorityWorker.enqueue({ msg: "low priority #{i}" })
43
- HighPriorityWorker.enqueue({ msg: "high priority #{i}" })
33
+ prty = (i % 2) == 0 ? 1 : 10
34
+ pub.publish({ msg: "hello world #{i} priority #{prty}" }, routing_key: 'pika-que-priority', priority: prty)
44
35
  end
45
36
 
46
37
  sleep 3
data/lib/pika_que.rb CHANGED
@@ -46,6 +46,12 @@ module PikaQue
46
46
  config[:reporters]
47
47
  end
48
48
 
49
+ def self.reset!
50
+ @config = nil
51
+ @connection = nil
52
+ @chain = nil
53
+ end
54
+
49
55
  end
50
56
 
51
57
  require 'pika_que/rails' if defined?(::Rails::Engine)
data/lib/pika_que/cli.rb CHANGED
@@ -45,7 +45,7 @@ module PikaQue
45
45
 
46
46
  def init_logger
47
47
  PikaQue::Logging.init_logger(config[:logfile]) if config[:logfile]
48
- PikaQue.logger.level = ::Logger::WARN if config[:quite]
48
+ PikaQue.logger.level = ::Logger::WARN if config[:quiet]
49
49
  PikaQue.logger.level = ::Logger::DEBUG if config[:verbose]
50
50
  end
51
51
 
@@ -132,8 +132,8 @@ module PikaQue
132
132
  opts[:environment] = arg
133
133
  end
134
134
 
135
- o.on '-q', '--quite', "Print quite output" do |arg|
136
- opts[:quite] = arg
135
+ o.on '-q', '--quiet', "Print quiet output" do |arg|
136
+ opts[:quiet] = arg
137
137
  end
138
138
 
139
139
  o.on '-v', '--verbose', "Print verbose output" do |arg|
@@ -76,7 +76,7 @@ module PikaQue
76
76
  # }
77
77
 
78
78
  def initialize
79
- @config = DEFAULT_CONFIG.dup
79
+ @config = Marshal.load(Marshal.dump(DEFAULT_CONFIG))
80
80
  @config[:amqp] = ENV.fetch('RABBITMQ_URL', 'amqp://guest:guest@localhost:5672')
81
81
  @config[:vhost] = AMQ::Settings.parse_amqp_url(@config[:amqp]).fetch(:vhost, '/')
82
82
  end
@@ -36,7 +36,7 @@ module PikaQue
36
36
  else
37
37
  PikaQue.logger.debug "ErrorHandler publishing <#{msg}> to [#{@queue.name}]"
38
38
  publish(delivery_info, msg)
39
- channel.acknowledge(delivery_info.delivery_tag, false)
39
+ channel.reject(delivery_info.delivery_tag, false)
40
40
  end
41
41
  end
42
42
 
@@ -72,7 +72,7 @@ module PikaQue
72
72
 
73
73
  #####################################################
74
74
  # formula
75
- # base X = 0, 30, 60, 120, 180, etc defaults to 0
75
+ # base X = 0, 15(2x), 30(3x), 45(4x), 60(5x), 120, 180, etc defaults to 0
76
76
  # (X + 15) * 2 ** (count + 1)
77
77
  def self.backoff_periods(max_retries, backoff_base)
78
78
  (1..max_retries).map{ |c| next_ttl(c, backoff_base) }
@@ -95,7 +95,12 @@ module PikaQue
95
95
 
96
96
  def setup_queues
97
97
  if @opts[:retry_mode] == :const
98
- bo = @opts[:retry_const_backoff]
98
+ backoffs = [@opts[:retry_const_backoff]]
99
+ else
100
+ backoffs = RetryHandler.backoff_periods(@max_retries, @backoff_base)
101
+ end
102
+
103
+ backoffs.each do |bo|
99
104
  PikaQue.logger.debug "RetryHandler creating queue=#{@retry_name}-#{bo} x-dead-letter-exchange=#{@requeue_name}"
100
105
  backoff_queue = @channel.queue("#{@retry_name}-#{bo}",
101
106
  :durable => queue_durable?,
@@ -104,18 +109,6 @@ module PikaQue
104
109
  :'x-message-ttl' => bo * @backoff_multiplier
105
110
  })
106
111
  backoff_queue.bind(@retry_exchange, :arguments => { :backoff => bo })
107
- else
108
- backoffs = RetryHandler.backoff_periods(@max_retries, @backoff_base)
109
- backoffs.each do |bo|
110
- PikaQue.logger.debug "RetryHandler creating queue=#{@retry_name}-#{bo} x-dead-letter-exchange=#{@requeue_name}"
111
- backoff_queue = @channel.queue("#{@retry_name}-#{bo}",
112
- :durable => queue_durable?,
113
- :arguments => {
114
- :'x-dead-letter-exchange' => @requeue_name,
115
- :'x-message-ttl' => bo * @backoff_multiplier
116
- })
117
- backoff_queue.bind(@retry_exchange, :arguments => { :backoff => bo })
118
- end
119
112
  end
120
113
 
121
114
  PikaQue.logger.debug "RetryHandler creating queue=#{@error_name}"
@@ -147,7 +140,7 @@ module PikaQue
147
140
  publish_retry(delivery_info, msg, { backoff: backoff_ttl, count: num_attempts })
148
141
  channel.reject(delivery_info.delivery_tag, false)
149
142
  else
150
- PikaQue.logger.info "RetryHandler msg=failing, retry_count=#{num_attempts}, headers=#{metadata[:headers]}, reason=#{reason}"
143
+ PikaQue.logger.info "RetryHandler msg=failing, retried_count=#{num_attempts - 1}, headers=#{metadata[:headers]}, reason=#{reason}"
151
144
 
152
145
  publish_error(delivery_info, msg)
153
146
  channel.reject(delivery_info.delivery_tag, false)
@@ -80,10 +80,10 @@ module PikaQue
80
80
  Thread.list.each do |thread|
81
81
  logger.warn "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}"
82
82
  if thread.backtrace
83
- logger.warn thread.backtrace.join("\n")
84
- else
85
- logger.warn "<no backtrace available>"
86
- end
83
+ logger.warn thread.backtrace.join("\n")
84
+ else
85
+ logger.warn "<no backtrace available>"
86
+ end
87
87
  end
88
88
  end
89
89
 
@@ -11,7 +11,7 @@ module PikaQue
11
11
  def self.init_metrics
12
12
  if PikaQue.config[:metrics]
13
13
  @metrics = PikaQue.config[:metrics].new
14
- elsif PikaQue.config[:quite]
14
+ elsif PikaQue.config[:quiet]
15
15
  @metrics = PikaQue::Metrics::NullMetric.new
16
16
  else
17
17
  @metrics = PikaQue::Metrics::LogMetric.new
@@ -29,7 +29,7 @@ module PikaQue
29
29
  Thread.current['label'] = 'processor'
30
30
  setup
31
31
  process
32
- end.abort_on_exception = true
32
+ end.tap{ |t| t.abort_on_exception = true }
33
33
  end
34
34
 
35
35
  def stop
@@ -21,5 +21,9 @@ module PikaQue
21
21
  @exchange.publish(msg, options)
22
22
  end
23
23
 
24
+ def exchange_name
25
+ @opts[:exchange]
26
+ end
27
+
24
28
  end
25
29
  end
@@ -32,36 +32,40 @@ module PikaQue
32
32
  @consumer = queue.subscribe(:block => false, :manual_ack => @opts[:ack], :arguments => worker.consumer_arguments) do | delivery_info, metadata, msg |
33
33
  # TODO make idletime configurable on thread pool? default is 60.
34
34
  pool.post do
35
- res = nil
36
- error = nil
37
- begin
38
- decoded_msg = @codec.decode(msg)
39
- metrics.measure("work.#{worker.class.name}.time") do
40
- PikaQue.middleware.invoke(worker, delivery_info, metadata, decoded_msg) do
41
- res = worker.work(delivery_info, metadata, decoded_msg)
42
- end
43
- end
44
- logger.debug "done processing #{res} <#{msg}>"
45
- rescue => worker_err
46
- res = :error
47
- error = worker_err
48
- notify_reporters(worker_err, worker.class, msg)
49
- end
35
+ handle_message(worker, delivery_info, metadata, msg)
36
+ end
37
+ end
38
+ end
50
39
 
51
- if @opts[:ack]
52
- begin
53
- handler.handle(res, broker.channel, delivery_info, metadata, msg, error)
54
- metrics.increment("work.#{worker.class.name}.handled.#{res}")
55
- rescue => handler_err
56
- notify_reporters(handler_err, handler.class, msg)
57
- metrics.increment("work.#{worker.class.name}.handler.error")
58
- end
59
- else
60
- metrics.increment("work.#{worker.class.name}.handled.noop")
40
+ def handle_message(worker, delivery_info, metadata, msg)
41
+ res = nil
42
+ error = nil
43
+ begin
44
+ decoded_msg = @codec.decode(msg)
45
+ metrics.measure("work.#{worker.class.name}.time") do
46
+ PikaQue.middleware.invoke(worker, delivery_info, metadata, decoded_msg) do
47
+ res = worker.work(delivery_info, metadata, decoded_msg)
61
48
  end
62
- metrics.increment("work.#{worker.class.name}.processed")
63
49
  end
50
+ logger.debug "done processing #{res} <#{msg}>"
51
+ rescue => worker_err
52
+ res = :error
53
+ error = worker_err
54
+ notify_reporters(worker_err, worker.class, msg)
55
+ end
56
+
57
+ if @opts[:ack]
58
+ begin
59
+ handler.handle(res, broker.channel, delivery_info, metadata, msg, error)
60
+ metrics.increment("work.#{worker.class.name}.handled.#{res}")
61
+ rescue => handler_err
62
+ notify_reporters(handler_err, handler.class, msg)
63
+ metrics.increment("work.#{worker.class.name}.handler.error")
64
+ end
65
+ else
66
+ metrics.increment("work.#{worker.class.name}.handled.noop")
64
67
  end
68
+ metrics.increment("work.#{worker.class.name}.processed")
65
69
  end
66
70
 
67
71
  def unsubscribe
@@ -1,3 +1,3 @@
1
1
  module PikaQue
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -75,7 +75,7 @@ module PikaQue
75
75
  alias_method :perform_async, :enqueue
76
76
 
77
77
  def enqueue_at(msg, timestamp, opts={})
78
- opts[:to_queue] ||= "#{PikaQue.config[:exchange]}-delay"
78
+ opts[:to_queue] ||= "#{publisher.exchange_name}-delay"
79
79
  work_queue = opts.delete(:routing_key) || (queue_opts[:routing_key] if queue_opts) || queue_name
80
80
  opts[:headers] = { work_at: timestamp, work_queue: work_queue }
81
81
 
data/pika_que.gemspec CHANGED
@@ -34,4 +34,5 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency "bundler", "~> 1.11"
35
35
  spec.add_development_dependency "rake", "~> 10.0"
36
36
  spec.add_development_dependency "rspec", "~> 3.0"
37
+ spec.add_development_dependency "simplecov", "~> 0.15"
37
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pika_que
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dong Wook Koo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-10 00:00:00.000000000 Z
11
+ date: 2018-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.15'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.15'
97
111
  description: Ruby background processor for RabbitMQ.
98
112
  email:
99
113
  - dwkoogt@gmail.com
@@ -113,6 +127,7 @@ files:
113
127
  - bin/console
114
128
  - bin/setup
115
129
  - examples/demo.rb
130
+ - examples/demo_conpriority.rb
116
131
  - examples/demo_delay.rb
117
132
  - examples/demo_oneoff.rb
118
133
  - examples/demo_priority.rb
@@ -177,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
192
  version: '0'
178
193
  requirements: []
179
194
  rubyforge_project:
180
- rubygems_version: 2.5.2.2
195
+ rubygems_version: 2.4.5.2
181
196
  signing_key:
182
197
  specification_version: 4
183
198
  summary: Ruby background processor for RabbitMQ.