stalker 0.1.0

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/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'jeweler'
2
+
3
+ Jeweler::Tasks.new do |s|
4
+ s.name = "stalker"
5
+ s.summary = "A job queueing and background workers system using Beanstalkd."
6
+ s.description = "A job queueing and background workers system using Beanstalkd. Inspired by the Minion gem."
7
+ s.author = "Adam Wiggins"
8
+ s.email = "adam@heroku.com"
9
+ s.homepage = "http://github.com/adamwiggins/stalker"
10
+ s.executables = [ "stalk" ]
11
+ s.rubyforge_project = "stalker"
12
+
13
+ s.add_dependency 'beanstalk-client'
14
+
15
+ s.files = FileList["[A-Z]*", "{bin,lib}/**/*"]
16
+ end
17
+
18
+ Jeweler::GemcutterTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bin/stalk ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../lib/stalker'
4
+
5
+ usage = "stalk <jobs.rb> [<priority>[,<priority>,..]]"
6
+ file = ARGV.shift or abort usage
7
+ priorities = (ARGV.shift || 'all').split(',')
8
+
9
+ require file
10
+
11
+ jobs = Stalker.jobs(priorities)
12
+ puts "Working #{jobs.size} #{priorities.join(', ')} priority jobs: [ #{jobs.join(' ')} ]"
13
+
14
+ trap('INT') do
15
+ puts "\rExiting"
16
+ exit
17
+ end
18
+
19
+ Stalker.work priorities
20
+
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'stalker'
3
+
4
+ require 'jobs'
5
+
6
+ Stalker.enqueue('send.email', :email => 'hello@example.com')
7
+ Stalker.enqueue('cleanup.strays')
8
+
data/examples/jobs.rb ADDED
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'stalker'
3
+
4
+ include Stalker
5
+
6
+ priority :high do
7
+ job 'send.email' do |args|
8
+ puts "Sending email to args['email']"
9
+ end
10
+
11
+ job 'transform.image' do |args|
12
+ puts "Image transform"
13
+ end
14
+ end
15
+
16
+ priority :low do
17
+ job 'cleanup.strays' do |args|
18
+ puts "Cleaning up"
19
+ end
20
+ end
data/lib/stalker.rb ADDED
@@ -0,0 +1,109 @@
1
+ require 'beanstalk-client'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ module Stalker
6
+ extend self
7
+
8
+ def enqueue(job, args={})
9
+ beanstalk.use find_priority(job)
10
+ beanstalk.put [ job, args ].to_json
11
+ end
12
+
13
+ def priority(p, &block)
14
+ @@priority = p.to_s
15
+ block.call
16
+ @@priority = nil
17
+ end
18
+
19
+ def job(j, &block)
20
+ @@priority ||= 'default'
21
+ @@priorities ||= {}
22
+ @@priorities[j] = @@priority
23
+
24
+ @@handlers ||= {}
25
+ @@handlers[j] = block
26
+ end
27
+
28
+ def work(priorities=['all'])
29
+ if Array(priorities) == [ 'all' ]
30
+ priorities = @@priorities.values.uniq
31
+ end
32
+
33
+ beanstalk.list_tubes_watched.each { |tube| beanstalk.ignore(tube) }
34
+ priorities.each { |priority| beanstalk.watch(priority) }
35
+
36
+ loop do
37
+ work_one_job
38
+ end
39
+ end
40
+
41
+ class NoSuchJob < RuntimeError; end
42
+
43
+ def work_one_job
44
+ job = beanstalk.reserve
45
+ name, args = JSON.parse job.body
46
+ log_job(name, args)
47
+ handler = @@handlers[name]
48
+ raise(NoSuchJob, name) unless handler
49
+ handler.call(args)
50
+ job.delete
51
+ rescue => e
52
+ STDERR.puts exception_message(e)
53
+ job.bury
54
+ end
55
+
56
+ def log_job(name, args)
57
+ args_flat = args.inject("") do |accum, (key,value)|
58
+ accum += "#{key}=#{value} "
59
+ end
60
+
61
+ log sprintf("%-15s :: #{args_flat}", name)
62
+ end
63
+
64
+ def log(msg)
65
+ puts "[#{Time.now}] #{msg}"
66
+ end
67
+
68
+ def jobs(priorities=['all'])
69
+ jobs = []
70
+ @@priorities.each do |job, priority|
71
+ jobs << job if priorities == %w(all) or priorities.include? priority
72
+ end
73
+ jobs
74
+ end
75
+
76
+ class NoJobsDefined < RuntimeError; end
77
+
78
+ def find_priority(job)
79
+ raise NoJobsDefined unless defined?(@@priorities)
80
+ @@priorities[job] or raise(NoSuchJob, job)
81
+ end
82
+
83
+ def beanstalk
84
+ @@beanstalk ||= Beanstalk::Pool.new([ beanstalk_host_and_port ])
85
+ end
86
+
87
+ def beanstalk_url
88
+ ENV['BEANSTALK_URL'] || 'beanstalk://localhost:11300/'
89
+ end
90
+
91
+ class BadURL < RuntimeError; end
92
+
93
+ def beanstalk_host_and_port
94
+ uri = URI.parse(beanstalk_url)
95
+ raise(BadURL, beanstalk_url) if uri.scheme != 'beanstalk'
96
+ return "#{uri.host}:#{uri.port}"
97
+ end
98
+
99
+ def exception_message(e)
100
+ msg = [ "Exception #{e.class} -> #{e.message}" ]
101
+
102
+ base = File.expand_path(Dir.pwd) + '/'
103
+ e.backtrace.each do |t|
104
+ msg << " #{File.expand_path(t).gsub(/#{base}/, '')}"
105
+ end
106
+
107
+ msg.join("\n")
108
+ end
109
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stalker
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Adam Wiggins
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-26 00:00:00 -07:00
18
+ default_executable: stalk
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: beanstalk-client
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description: A job queueing and background workers system using Beanstalkd. Inspired by the Minion gem.
33
+ email: adam@heroku.com
34
+ executables:
35
+ - stalk
36
+ extensions: []
37
+
38
+ extra_rdoc_files: []
39
+
40
+ files:
41
+ - Rakefile
42
+ - VERSION
43
+ - bin/stalk
44
+ - lib/stalker.rb
45
+ has_rdoc: true
46
+ homepage: http://github.com/adamwiggins/stalker
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ requirements: []
69
+
70
+ rubyforge_project: stalker
71
+ rubygems_version: 1.3.6
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: A job queueing and background workers system using Beanstalkd.
75
+ test_files:
76
+ - examples/enqueue.rb
77
+ - examples/jobs.rb