peon 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "peon"
5
+ gemspec.summary = "Work queue library with DSL for defining jobs"
6
+ gemspec.description = "Peon is a work queue library for Ruby with an awesome DSL for defining jobs, and it's compatible with the beanstalkd message queue."
7
+ gemspec.email = "charlie@pushyapp.com"
8
+ gemspec.homepage = "http://github.com/cmelbye/peon"
9
+ gemspec.authors = ["Charlie Melbye"]
10
+
11
+ gemspec.files.exclude 'examples/*'
12
+ gemspec.add_dependency('beanstalk-client', '>= 1.0.2')
13
+ gemspec.add_dependency('dj2-jack', '>= 0.0.2')
14
+ gemspec.add_dependency('json', '>= 1.1.9')
15
+ end
16
+ rescue LoadError
17
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
18
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'peon'
5
+
6
+ include Peon
7
+
8
+ job "test.job" do |args|
9
+ puts "Hello #{args['what']}! It worked!"
10
+ end
11
+
12
+ job "test.two" do |args|
13
+ puts "Hello there. This is just another #{args['type']}."
14
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'peon'
5
+
6
+ include Peon
7
+
8
+ job "add.bread" do |args|
9
+ { "bread" => "sourdough" }
10
+ end
11
+
12
+ job "add.meat" do |args|
13
+ { "meat" => "turkey" }
14
+ end
15
+
16
+ job "add.condiments" do |args|
17
+ { "condiments" => "mayo" }
18
+ end
19
+
20
+ job "eat.sandwich" do |args|
21
+ puts "YUM! A #{args['meat']} on #{args['bread']} sandwich with #{args['condiments']}"
22
+ end
23
+
24
+ enqueue(["add.bread", "add.meat", "add.condiments", "eat.sandwich" ])
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'peon'
5
+
6
+ include Peon
7
+
8
+ loop do
9
+ enqueue("test.job", { "what" => "Jack" })
10
+ sleep 1
11
+ enqueue("test.two", { "type" => "cat" })
12
+ sleep 1
13
+ end
14
+
data/lib/peon.rb ADDED
@@ -0,0 +1,112 @@
1
+ require 'rubygems'
2
+ require 'eventmachine'
3
+ require 'json'
4
+ require 'jack'
5
+ require 'beanstalk-client'
6
+ require 'peon/handler'
7
+
8
+ module Peon
9
+ extend self
10
+
11
+ def enqueue(jobs, data = {})
12
+ if jobs.respond_to? :shift
13
+ queue = jobs.shift
14
+ data["next_job"] = jobs unless jobs.empty?
15
+ else
16
+ queue = jobs
17
+ end
18
+
19
+ log "send: #{queue}:#{data.to_json}"
20
+ beanstalk.use(queue)
21
+ beanstalk.put(data.to_json)
22
+ end
23
+
24
+ def log(msg)
25
+ @@logger ||= proc { |m| puts "#{Time.now} :peon: #{m}" }
26
+ @@logger.call(msg)
27
+ end
28
+
29
+ def error(&blk)
30
+ @@error_handler = blk
31
+ end
32
+
33
+ def logger(&blk)
34
+ @@logger = blk
35
+ end
36
+
37
+ def job(queue, options = {}, &blk)
38
+ handler = Peon::Handler.new(queue)
39
+ handler.when = options[:when] if options[:when]
40
+ handler.unsub = lambda do
41
+ log "unsubscribing to #{queue}"
42
+ jack.ignore(queue)
43
+ end
44
+ handler.sub = lambda do
45
+ log "subscribing to #{queue}"
46
+ jack.watch(queue)
47
+ end
48
+ handler.task = blk
49
+ @@handlers ||= {}
50
+ at_exit { Peon.run } if @@handlers.size == 0
51
+ @@handlers[queue] = handler
52
+ end
53
+
54
+ def check_all
55
+ @@handlers.each do |queue, handler|
56
+ handler.check
57
+ end
58
+ end
59
+
60
+ def reserve_job
61
+ r = jack.reserve
62
+ r.callback do |job|
63
+ job.stats.callback do |stats|
64
+ process_job(job, stats)
65
+ end
66
+ end
67
+ end
68
+
69
+ def process_job(job, stats)
70
+ queue = stats['tube']
71
+ args = JSON.load job.body
72
+ log "recv: #{queue}:#{job.body}"
73
+ handler = @@handlers[queue]
74
+ response = handler.task.call(args)
75
+ jack.delete(job)
76
+ check_all
77
+ next_job(args, response)
78
+ reserve_job
79
+ end
80
+
81
+ def run
82
+ log "Starting up"
83
+
84
+ Signal.trap('INT') { EM.stop }
85
+ Signal.trap('TERM') { EM.stop }
86
+
87
+ EM.run do
88
+ check_all
89
+ reserve_job
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ def beanstalk
96
+ @@beanstalk ||= Beanstalk::Pool.new(['127.0.0.1:11300'])
97
+ end
98
+
99
+ def jack
100
+ @@jack ||= Jack::Connection.new
101
+ end
102
+
103
+ def next_job(args, response)
104
+ queue = args.delete("next_job")
105
+ enqueue(queue, args.merge(response)) if queue
106
+ end
107
+
108
+ def error_handler
109
+ @@error_handler ||= nil
110
+ end
111
+ end
112
+
@@ -0,0 +1,33 @@
1
+ module Peon
2
+ class Handler
3
+ attr_accessor :queue, :sub, :unsub, :when, :on, :task
4
+
5
+ def initialize(queue)
6
+ @queue = queue
7
+ @when = lambda { true }
8
+ @sub = lambda {}
9
+ @unsub = lambda {}
10
+ @on = false
11
+ @task = lambda {}
12
+ end
13
+
14
+ def should_sub?
15
+ @when.call
16
+ end
17
+
18
+ def check
19
+ if should_sub?
20
+ @sub.call unless @on
21
+ @on = true
22
+ else
23
+ @unsub.call if @on
24
+ @on = false
25
+ end
26
+ end
27
+
28
+ def to_s
29
+ "<handler queue=#{@queue} on=#{@on}>"
30
+ end
31
+ end
32
+ end
33
+
data/peon.gemspec ADDED
@@ -0,0 +1,51 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{peon}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Charlie Melbye"]
12
+ s.date = %q{2009-10-05}
13
+ s.description = %q{Peon is a work queue library for Ruby with an awesome DSL for defining jobs, and it's compatible with the beanstalkd message queue.}
14
+ s.email = %q{charlie@pushyapp.com}
15
+ s.files = [
16
+ "Rakefile",
17
+ "VERSION",
18
+ "lib/peon.rb",
19
+ "lib/peon/handler.rb",
20
+ "peon.gemspec"
21
+ ]
22
+ s.homepage = %q{http://github.com/cmelbye/peon}
23
+ s.rdoc_options = ["--charset=UTF-8"]
24
+ s.require_paths = ["lib"]
25
+ s.rubygems_version = %q{1.3.5}
26
+ s.summary = %q{Work queue library with DSL for defining jobs}
27
+ s.test_files = [
28
+ "examples/client.rb",
29
+ "examples/sandwich.rb",
30
+ "examples/server.rb"
31
+ ]
32
+
33
+ if s.respond_to? :specification_version then
34
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
35
+ s.specification_version = 3
36
+
37
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
38
+ s.add_runtime_dependency(%q<beanstalk-client>, [">= 1.0.2"])
39
+ s.add_runtime_dependency(%q<dj2-jack>, [">= 0.0.2"])
40
+ s.add_runtime_dependency(%q<json>, [">= 1.1.9"])
41
+ else
42
+ s.add_dependency(%q<beanstalk-client>, [">= 1.0.2"])
43
+ s.add_dependency(%q<dj2-jack>, [">= 0.0.2"])
44
+ s.add_dependency(%q<json>, [">= 1.1.9"])
45
+ end
46
+ else
47
+ s.add_dependency(%q<beanstalk-client>, [">= 1.0.2"])
48
+ s.add_dependency(%q<dj2-jack>, [">= 0.0.2"])
49
+ s.add_dependency(%q<json>, [">= 1.1.9"])
50
+ end
51
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: peon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Charlie Melbye
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-05 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: beanstalk-client
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.0.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: dj2-jack
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.2
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: json
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.1.9
44
+ version:
45
+ description: Peon is a work queue library for Ruby with an awesome DSL for defining jobs, and it's compatible with the beanstalkd message queue.
46
+ email: charlie@pushyapp.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files: []
52
+
53
+ files:
54
+ - Rakefile
55
+ - VERSION
56
+ - lib/peon.rb
57
+ - lib/peon/handler.rb
58
+ - peon.gemspec
59
+ has_rdoc: true
60
+ homepage: http://github.com/cmelbye/peon
61
+ licenses: []
62
+
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --charset=UTF-8
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "0"
73
+ version:
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ version:
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.5
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Work queue library with DSL for defining jobs
87
+ test_files:
88
+ - examples/client.rb
89
+ - examples/sandwich.rb
90
+ - examples/server.rb