pika_que 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
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.