resque-priority-jobs 0.2

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.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in resque-priority-jobs.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ resque-priority-jobs (0.1)
5
+ resque
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.1.3)
11
+ facets (2.9.3)
12
+ json (1.6.3)
13
+ rack (1.3.5)
14
+ redis (2.2.2)
15
+ redis-namespace (0.7.0)
16
+ redis (< 3.0.0)
17
+ resque (1.9.8)
18
+ json (>= 1.1.0)
19
+ redis-namespace (~> 0.7.0)
20
+ sinatra (>= 0.9.2)
21
+ vegas (~> 0.1.2)
22
+ rspec (2.7.0)
23
+ rspec-core (~> 2.7.0)
24
+ rspec-expectations (~> 2.7.0)
25
+ rspec-mocks (~> 2.7.0)
26
+ rspec-core (2.7.1)
27
+ rspec-expectations (2.7.0)
28
+ diff-lcs (~> 1.1.2)
29
+ rspec-mocks (2.7.0)
30
+ sinatra (1.2.6)
31
+ rack (~> 1.1)
32
+ tilt (>= 1.2.2, < 2.0)
33
+ tilt (1.3.3)
34
+ vegas (0.1.8)
35
+ rack (>= 1.0.0)
36
+
37
+ PLATFORMS
38
+ ruby
39
+
40
+ DEPENDENCIES
41
+ facets
42
+ resque-priority-jobs!
43
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 rajofchennai
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Resque::Priority::Jobs
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'resque-priority-jobs'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install resque-priority-jobs
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,10 @@
1
+ module Resque
2
+ class Job
3
+ # checks if klass and queue are valid
4
+ #FIXME: Not implemented Resque.inline?
5
+ def self.create_with_priority queue, klass, priority, *args
6
+ Resque.validate(klass, queue)
7
+ Resque.push_with_priority(queue, priority, :class => klass.to_s, :args => args)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,30 @@
1
+ module Resque
2
+ class MultiQueue
3
+ # worker polling aliased
4
+ #TODO: Known Performance issue to ensure that same job is not done twice. Can be fixed after redis-2.6 is released
5
+ def poll_with_priority timeout
6
+ normal_queue_names = @queues.map {|queue| queue.redis_name unless queue.is_a_priority_queue? }
7
+ normal_queue_names.compact!
8
+ priority_queue_names = @queues.map {|queue| queue.redis_name if queue.is_a_priority_queue? }
9
+ priority_queue_names.compact!
10
+ priority_queue_names.each do |queue_name|
11
+ synchronize do
12
+ payload = Resque::JobFetch.fetch_one_job @redis, queue_name
13
+ if payload
14
+ queue = @queue_hash[queue_name]
15
+ return [queue, queue.decode(payload)]
16
+ end
17
+ end
18
+ end
19
+ normal_queue_names = normal_queue_names.size == 0 ? "" : normal_queue_names
20
+ queue_name, payload = @redis.blpop(normal_queue_names, :timeout => timeout)
21
+ return unless payload
22
+
23
+ synchronize do
24
+ queue = @queue_hash[queue_name]
25
+ [queue, queue.decode(payload)]
26
+ end
27
+ end
28
+ alias :poll :poll_with_priority
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ module Resque
2
+ class Queue
3
+ # adds entry into redis
4
+ def push_with_priority priority, object
5
+ synchronize do
6
+ @redis.zadd @redis_name, priority, encode(object)
7
+ end
8
+ end
9
+
10
+ # remove entry from queue use default pop in case of non-priority queue see alias_method_chain
11
+ def pop_with_priority non_block = false
12
+ return pop_without_priority non_block unless is_a_priority_queue?
13
+ synchronize do
14
+ value = Resque::JobFetch.fetch_one_job @redis, @redis_name until non_block || value
15
+ raise ThreadError if non_block && !value
16
+ decode value
17
+ end
18
+ end
19
+ alias :pop_without_priority :pop
20
+ alias :pop :pop_with_priority
21
+
22
+ # not optimial has an extra redis call for priority call. Assumtion is that there are lesser queues using priority
23
+ def length
24
+ @redis.llen @redis_name rescue @redis.zcard @redis_name
25
+ end
26
+
27
+ # To identify whether a queue is priority queue or not. Empty queues are always non-priority
28
+ # Assumption : Once a queue type is set to be a priority queue, it cannot be changed and vice-versa.
29
+ def is_a_priority_queue?
30
+ @@queue_types ||= {}
31
+ (@@queue_types[@redis_name] ||= queue_type) == 'zset'
32
+ end
33
+
34
+ def queue_type
35
+ type = @redis.type(@redis_name)
36
+ type == 'none' ? nil : type
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,7 @@
1
+ module Resque
2
+ module Priority
3
+ module Jobs
4
+ VERSION = "0.2"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,47 @@
1
+ require 'resque'
2
+ require 'resque-priority-jobs/queue'
3
+ require 'resque-priority-jobs/multi_queue'
4
+ require 'resque-priority-jobs/job'
5
+
6
+ # Max priority is the highest priority similarly for min priority. These numbers are arbitrary
7
+ MIN_PRIORITY = 20
8
+ MAX_PRIORITY = 1
9
+
10
+ module Resque
11
+ # Queues which need priority scheduling need to use this method instead of enqueue
12
+ #FIXME: Known issue - If a use is already enqueued without priority and then we do a enqueue with priority we get an error of different datatype from redis.
13
+ def enqueue_with_priority klass, priority = MIN_PRIORITY, *args
14
+ queue = queue_from_class(klass)
15
+ before_hooks = Plugin.before_enqueue_hooks(klass).collect do |hook|
16
+ klass.send(hook, *args)
17
+ end
18
+ return nil if before_hooks.any? { |result| result == false }
19
+
20
+ Job.create_with_priority(queue, klass, priority, *args)
21
+
22
+ Plugin.after_enqueue_hooks(klass).each do |hook|
23
+ klass.send(hook, *args)
24
+ end
25
+
26
+ return true
27
+ end
28
+
29
+ def push_with_priority queue, priority, item
30
+ queue(queue).push_with_priority priority, item
31
+ end
32
+
33
+ class JobFetch
34
+ def self.fetch_one_job redis, queue
35
+ #lua script to get item with maximum priority
36
+ get_and_rem = "local resp = redis.call('zrangebyscore', KEYS[1], '-inf', '+inf', 'LIMIT', '0', '1');
37
+ if (resp[1] ~= nil) then
38
+ local val = resp[# resp]
39
+ redis.call('zrem', KEYS[1], val)
40
+ return val
41
+ else
42
+ return false
43
+ end"
44
+ redis.eval get_and_rem, [queue]
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/resque-priority-jobs/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["rajofchennai"]
6
+ gem.email = ["rajofchennai@yahoo.com"]
7
+ gem.description = %q{resque plugin to have priority in the queue}
8
+ gem.summary = %q{This plugin can be used to have priority inside a queue for resques}
9
+ gem.homepage = ""
10
+
11
+ gem.add_dependency "resque"
12
+ gem.add_development_dependency "rspec"
13
+ gem.add_development_dependency "facets"
14
+ gem.add_development_dependency "systemtimer"
15
+ gem.files = `git ls-files`.split($\)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.name = "resque-priority-jobs"
19
+ gem.require_paths = ["lib"]
20
+ gem.version = Resque::Priority::Jobs::VERSION
21
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: resque-priority-jobs
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.2'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - rajofchennai
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: resque
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: facets
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: systemtimer
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: resque plugin to have priority in the queue
79
+ email:
80
+ - rajofchennai@yahoo.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - Gemfile
86
+ - Gemfile.lock
87
+ - LICENSE
88
+ - README.md
89
+ - Rakefile
90
+ - lib/resque-priority-jobs.rb
91
+ - lib/resque-priority-jobs/job.rb
92
+ - lib/resque-priority-jobs/multi_queue.rb
93
+ - lib/resque-priority-jobs/queue.rb
94
+ - lib/resque-priority-jobs/version.rb
95
+ - resque-priority-jobs.gemspec
96
+ homepage: ''
97
+ licenses: []
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 1.8.24
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: This plugin can be used to have priority inside a queue for resques
120
+ test_files: []