resque_sqs 1.25.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/HISTORY.md +467 -0
- data/LICENSE +20 -0
- data/README.markdown +866 -0
- data/Rakefile +70 -0
- data/bin/resque-sqs +81 -0
- data/bin/resque-sqs-web +27 -0
- data/lib/resque_sqs/errors.rb +13 -0
- data/lib/resque_sqs/failure/airbrake.rb +33 -0
- data/lib/resque_sqs/failure/base.rb +73 -0
- data/lib/resque_sqs/failure/multiple.rb +59 -0
- data/lib/resque_sqs/failure/redis.rb +108 -0
- data/lib/resque_sqs/failure/redis_multi_queue.rb +89 -0
- data/lib/resque_sqs/failure.rb +113 -0
- data/lib/resque_sqs/helpers.rb +107 -0
- data/lib/resque_sqs/job.rb +346 -0
- data/lib/resque_sqs/log_formatters/quiet_formatter.rb +7 -0
- data/lib/resque_sqs/log_formatters/verbose_formatter.rb +7 -0
- data/lib/resque_sqs/log_formatters/very_verbose_formatter.rb +8 -0
- data/lib/resque_sqs/logging.rb +18 -0
- data/lib/resque_sqs/plugin.rb +66 -0
- data/lib/resque_sqs/server/helpers.rb +52 -0
- data/lib/resque_sqs/server/public/favicon.ico +0 -0
- data/lib/resque_sqs/server/public/idle.png +0 -0
- data/lib/resque_sqs/server/public/jquery-1.3.2.min.js +19 -0
- data/lib/resque_sqs/server/public/jquery.relatize_date.js +95 -0
- data/lib/resque_sqs/server/public/poll.png +0 -0
- data/lib/resque_sqs/server/public/ranger.js +78 -0
- data/lib/resque_sqs/server/public/reset.css +44 -0
- data/lib/resque_sqs/server/public/style.css +91 -0
- data/lib/resque_sqs/server/public/working.png +0 -0
- data/lib/resque_sqs/server/test_helper.rb +19 -0
- data/lib/resque_sqs/server/views/error.erb +1 -0
- data/lib/resque_sqs/server/views/failed.erb +29 -0
- data/lib/resque_sqs/server/views/failed_job.erb +50 -0
- data/lib/resque_sqs/server/views/failed_queues_overview.erb +24 -0
- data/lib/resque_sqs/server/views/key_sets.erb +19 -0
- data/lib/resque_sqs/server/views/key_string.erb +11 -0
- data/lib/resque_sqs/server/views/layout.erb +44 -0
- data/lib/resque_sqs/server/views/next_more.erb +22 -0
- data/lib/resque_sqs/server/views/overview.erb +4 -0
- data/lib/resque_sqs/server/views/queues.erb +58 -0
- data/lib/resque_sqs/server/views/stats.erb +62 -0
- data/lib/resque_sqs/server/views/workers.erb +109 -0
- data/lib/resque_sqs/server/views/working.erb +72 -0
- data/lib/resque_sqs/server.rb +271 -0
- data/lib/resque_sqs/stat.rb +57 -0
- data/lib/resque_sqs/tasks.rb +83 -0
- data/lib/resque_sqs/vendor/utf8_util/utf8_util_18.rb +91 -0
- data/lib/resque_sqs/vendor/utf8_util/utf8_util_19.rb +5 -0
- data/lib/resque_sqs/vendor/utf8_util.rb +20 -0
- data/lib/resque_sqs/version.rb +3 -0
- data/lib/resque_sqs/worker.rb +779 -0
- data/lib/resque_sqs.rb +479 -0
- data/lib/tasks/redis_sqs.rake +161 -0
- data/lib/tasks/resque_sqs.rake +2 -0
- data/test/airbrake_test.rb +27 -0
- data/test/failure_base_test.rb +15 -0
- data/test/job_hooks_test.rb +465 -0
- data/test/job_plugins_test.rb +230 -0
- data/test/logging_test.rb +24 -0
- data/test/plugin_test.rb +116 -0
- data/test/redis-test-cluster.conf +115 -0
- data/test/redis-test.conf +115 -0
- data/test/resque-web_test.rb +59 -0
- data/test/resque_failure_redis_test.rb +19 -0
- data/test/resque_hook_test.rb +165 -0
- data/test/resque_test.rb +278 -0
- data/test/stdout +42 -0
- data/test/test_helper.rb +228 -0
- data/test/worker_test.rb +1080 -0
- metadata +202 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
module ResqueSqs
|
2
|
+
# The stat subsystem. Used to keep track of integer counts.
|
3
|
+
#
|
4
|
+
# Get a stat: Stat[name]
|
5
|
+
# Incr a stat: Stat.incr(name)
|
6
|
+
# Decr a stat: Stat.decr(name)
|
7
|
+
# Kill a stat: Stat.clear(name)
|
8
|
+
module Stat
|
9
|
+
extend self
|
10
|
+
|
11
|
+
# Direct access to the Redis instance.
|
12
|
+
def redis
|
13
|
+
ResqueSqs.redis
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the int value of a stat, given a string stat name.
|
17
|
+
def get(stat)
|
18
|
+
redis.get("stat:#{stat}").to_i
|
19
|
+
end
|
20
|
+
|
21
|
+
# Alias of `get`
|
22
|
+
def [](stat)
|
23
|
+
get(stat)
|
24
|
+
end
|
25
|
+
|
26
|
+
# For a string stat name, increments the stat by one.
|
27
|
+
#
|
28
|
+
# Can optionally accept a second int parameter. The stat is then
|
29
|
+
# incremented by that amount.
|
30
|
+
def incr(stat, by = 1)
|
31
|
+
redis.incrby("stat:#{stat}", by)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Increments a stat by one.
|
35
|
+
def <<(stat)
|
36
|
+
incr stat
|
37
|
+
end
|
38
|
+
|
39
|
+
# For a string stat name, decrements the stat by one.
|
40
|
+
#
|
41
|
+
# Can optionally accept a second int parameter. The stat is then
|
42
|
+
# decremented by that amount.
|
43
|
+
def decr(stat, by = 1)
|
44
|
+
redis.decrby("stat:#{stat}", by)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Decrements a stat by one.
|
48
|
+
def >>(stat)
|
49
|
+
decr stat
|
50
|
+
end
|
51
|
+
|
52
|
+
# Removes a stat from Redis, effectively setting it to 0.
|
53
|
+
def clear(stat)
|
54
|
+
redis.del("stat:#{stat}")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# require 'resque_sqs/tasks'
|
2
|
+
# will give you the resque tasks
|
3
|
+
|
4
|
+
namespace :resque_sqs do
|
5
|
+
task :setup
|
6
|
+
|
7
|
+
desc "Start a Resque worker"
|
8
|
+
task :work => [ :preload, :setup ] do
|
9
|
+
require 'resque_sqs'
|
10
|
+
|
11
|
+
queues = (ENV['QUEUES'] || ENV['QUEUE']).to_s.split(',')
|
12
|
+
|
13
|
+
begin
|
14
|
+
worker = ResqueSqs::Worker.new(*queues)
|
15
|
+
if ENV['LOGGING'] || ENV['VERBOSE']
|
16
|
+
worker.verbose = ENV['LOGGING'] || ENV['VERBOSE']
|
17
|
+
end
|
18
|
+
if ENV['VVERBOSE']
|
19
|
+
worker.very_verbose = ENV['VVERBOSE']
|
20
|
+
end
|
21
|
+
worker.term_timeout = ENV['RESQUE_TERM_TIMEOUT'] || 4.0
|
22
|
+
worker.term_child = ENV['TERM_CHILD']
|
23
|
+
worker.run_at_exit_hooks = ENV['RUN_AT_EXIT_HOOKS']
|
24
|
+
rescue ResqueSqs::NoQueueError
|
25
|
+
abort "set QUEUE env var, e.g. $ QUEUE=critical,high rake resque_sqs:work"
|
26
|
+
end
|
27
|
+
|
28
|
+
if ENV['BACKGROUND']
|
29
|
+
unless Process.respond_to?('daemon')
|
30
|
+
abort "env var BACKGROUND is set, which requires ruby >= 1.9"
|
31
|
+
end
|
32
|
+
Process.daemon(true, true)
|
33
|
+
end
|
34
|
+
|
35
|
+
if ENV['PIDFILE']
|
36
|
+
File.open(ENV['PIDFILE'], 'w') { |f| f << worker.pid }
|
37
|
+
end
|
38
|
+
|
39
|
+
worker.log "Starting worker #{worker}"
|
40
|
+
|
41
|
+
worker.work(ENV['INTERVAL'] || 5) # interval, will block
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Start multiple Resque workers. Should only be used in dev mode."
|
45
|
+
task :workers do
|
46
|
+
threads = []
|
47
|
+
|
48
|
+
ENV['COUNT'].to_i.times do
|
49
|
+
threads << Thread.new do
|
50
|
+
system "rake resque_sqs:work"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
threads.each { |thread| thread.join }
|
55
|
+
end
|
56
|
+
|
57
|
+
# Preload app files if this is Rails
|
58
|
+
task :preload => :setup do
|
59
|
+
if defined?(Rails) && Rails.respond_to?(:application)
|
60
|
+
# Rails 3
|
61
|
+
Rails.application.eager_load!
|
62
|
+
elsif defined?(Rails::Initializer)
|
63
|
+
# Rails 2.3
|
64
|
+
$rails_rake_task = false
|
65
|
+
Rails::Initializer.run :load_application_classes
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
namespace :failures do
|
70
|
+
desc "Sort the 'failed' queue for the redis_multi_queue failure backend"
|
71
|
+
task :sort do
|
72
|
+
require 'resque_sqs'
|
73
|
+
require 'resque_sqs/failure/redis'
|
74
|
+
|
75
|
+
warn "Sorting #{ResqueSqs::Failure.count} failures..."
|
76
|
+
ResqueSqs::Failure.each(0, ResqueSqs::Failure.count) do |_, failure|
|
77
|
+
data = ResqueSqs.encode(failure)
|
78
|
+
ResqueSqs.redis.rpush(ResqueSqs::Failure.failure_queue_name(failure['queue']), data)
|
79
|
+
end
|
80
|
+
warn "done!"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
module UTF8Util
|
4
|
+
HIGH_BIT_RANGE = /[\x80-\xff]/
|
5
|
+
|
6
|
+
# Check if this String is valid UTF-8
|
7
|
+
#
|
8
|
+
# Returns true or false.
|
9
|
+
def self.valid?(str)
|
10
|
+
sc = StringScanner.new(str)
|
11
|
+
|
12
|
+
while sc.skip_until(HIGH_BIT_RANGE)
|
13
|
+
sc.pos -= 1
|
14
|
+
|
15
|
+
if !sequence_length(sc)
|
16
|
+
return false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
# Replace invalid UTF-8 character sequences with a replacement character
|
24
|
+
#
|
25
|
+
# Returns self as valid UTF-8.
|
26
|
+
def self.clean!(str)
|
27
|
+
sc = StringScanner.new(str)
|
28
|
+
while sc.skip_until(HIGH_BIT_RANGE)
|
29
|
+
pos = sc.pos = sc.pos-1
|
30
|
+
|
31
|
+
if !sequence_length(sc)
|
32
|
+
str[pos] = REPLACEMENT_CHAR
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
str
|
37
|
+
end
|
38
|
+
|
39
|
+
# Validate the UTF-8 sequence at the current scanner position.
|
40
|
+
#
|
41
|
+
# scanner - StringScanner instance so we can advance the pointer as we verify.
|
42
|
+
#
|
43
|
+
# Returns The length in bytes of this UTF-8 sequence, false if invalid.
|
44
|
+
def self.sequence_length(scanner)
|
45
|
+
leader = scanner.get_byte[0]
|
46
|
+
|
47
|
+
if (leader >> 5) == 0x6
|
48
|
+
if check_next_sequence(scanner)
|
49
|
+
return 2
|
50
|
+
else
|
51
|
+
scanner.pos -= 1
|
52
|
+
end
|
53
|
+
elsif (leader >> 4) == 0x0e
|
54
|
+
if check_next_sequence(scanner)
|
55
|
+
if check_next_sequence(scanner)
|
56
|
+
return 3
|
57
|
+
else
|
58
|
+
scanner.pos -= 2
|
59
|
+
end
|
60
|
+
else
|
61
|
+
scanner.pos -= 1
|
62
|
+
end
|
63
|
+
elsif (leader >> 3) == 0x1e
|
64
|
+
if check_next_sequence(scanner)
|
65
|
+
if check_next_sequence(scanner)
|
66
|
+
if check_next_sequence(scanner)
|
67
|
+
return 4
|
68
|
+
else
|
69
|
+
scanner.pos -= 3
|
70
|
+
end
|
71
|
+
else
|
72
|
+
scanner.pos -= 2
|
73
|
+
end
|
74
|
+
else
|
75
|
+
scanner.pos -= 1
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# Read another byte off the scanner oving the scan position forward one place
|
85
|
+
#
|
86
|
+
# Returns nothing.
|
87
|
+
def self.check_next_sequence(scanner)
|
88
|
+
byte = scanner.get_byte[0]
|
89
|
+
(byte >> 6) == 0x2
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module UTF8Util
|
2
|
+
# use '?' intsead of the unicode replace char, since that is 3 bytes
|
3
|
+
# and can increase the string size if it's done a lot
|
4
|
+
REPLACEMENT_CHAR = "?"
|
5
|
+
|
6
|
+
# Replace invalid UTF-8 character sequences with a replacement character
|
7
|
+
#
|
8
|
+
# Returns self as valid UTF-8.
|
9
|
+
def self.clean!(str)
|
10
|
+
return str if str.encoding.to_s == "UTF-8"
|
11
|
+
str.force_encoding("binary").encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => REPLACEMENT_CHAR)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Replace invalid UTF-8 character sequences with a replacement character
|
15
|
+
#
|
16
|
+
# Returns a copy of this String as valid UTF-8.
|
17
|
+
def self.clean(str)
|
18
|
+
clean!(str.dup)
|
19
|
+
end
|
20
|
+
end
|