langrove-plugin-resque 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  GIT
2
2
  remote: git@github.com:cluetechnologies/langrove-enterprise.git
3
- revision: ba46ec4bfd41f9c8962e6aab938c2733f4be225d
3
+ revision: 0fdc27f345889dabbf8df4f22a9636bf5af920d8
4
4
  branch: master
5
5
  specs:
6
6
  langrove (0.0.5.2)
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  `Plugin::Resque`
2
2
  ===============
3
3
 
4
- Integrates [Resque](https://github.com/defunkt/resque/) Worker and Job functionality into LanGrove. Resque used [Redis](http://redis.io/documentation) under the hood.
4
+ Integrates [Resque](https://github.com/defunkt/resque/) Worker and Job functionality into LanGrove. Resque uses [Redis](http://redis.io/documentation) under the hood.
5
5
 
6
6
  `gem install langrove-plugin-resque`
7
7
 
@@ -10,14 +10,20 @@ Implements
10
10
 
11
11
  * `Adaptor::ResqueAdaptor < LanGrove::Adaptor::Base` ...the worker (de-queue-er)
12
12
  * `Handler::ResqueHandler < LanGrove::Handler::Base` ...the job
13
- * `Plugin::ResqueQueue < LanGrove::Plugin::Deferror` ...the en-queue-er
14
-
13
+ * `Plugin::ResqueQueue < LanGrove::Plugin::Enqueuer` ...the en-queue-er
15
14
 
16
15
  Supports
17
16
  --------
18
17
 
19
- * `LanGrove::Behaviour::Deferrable`
18
+ * `LanGrove::Behaviour::Enqueueable`
19
+
20
+ Important
21
+ ---------
20
22
 
23
+ * Departs form traditional Resqu use.
24
+ * Each queue has a corresponding queue_failed queue.
25
+ * Uncaught exceptions from the Job are caught in the Worker and posted onto the _failed queue along with the original payload.
26
+ * There is no infrastructure to resubmit.
21
27
 
22
28
  Examples
23
29
  --------
@@ -30,18 +36,26 @@ Examples
30
36
 
31
37
  :plugins:
32
38
  :a_job_queue:
33
- :class: ResqueQueue
39
+ :class: ResqueQueue
34
40
  :job: JobName
35
41
  :queue: job_name
36
42
 
43
+ #
44
+ # Optionals (with defaults)
45
+ #
46
+ # Refers to the redis connection
47
+ #
48
+ :hostname: localhost
49
+ :port: 6397
50
+
37
51
  ...
38
52
 
39
53
  :server:
40
54
  :behavior:
41
- :deferrable:
55
+ :enqueueable:
42
56
  :plugin: :a_job_queue
43
57
  :at:
44
- :handler_after_receive: :defer_capsule
58
+ :handler_after_receive: :enqueue_capsule
45
59
  #
46
60
  # will post the caspsule as payload
47
61
  # onto the specified resque queue
@@ -61,7 +75,7 @@ Examples
61
75
 
62
76
  :adaptor:
63
77
  :class: ResqueAdaptor
64
- :queue: job_name
78
+ :plugin: :a_job_queue
65
79
 
66
80
  ...
67
81
 
@@ -75,3 +89,18 @@ Examples
75
89
 
76
90
  </pre>
77
91
 
92
+
93
+ Change Log
94
+ ----------
95
+
96
+ ### 2012-07-29
97
+
98
+ * Added support for sharing common plugin subconfig branch
99
+ * Added support for remote redis server.
100
+
101
+ ### 2012-07-31
102
+
103
+ * Deferrable was renamed to enqueueable
104
+ * v0.3
105
+
106
+
@@ -2,7 +2,7 @@ $LOAD_PATH.unshift 'lib'
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = %q{langrove-plugin-resque}
5
- spec.version = '0.2'
5
+ spec.version = '0.3'
6
6
  spec.date = DateTime.now.strftime( "%Y-%m-%d" )
7
7
  spec.authors = ["Richard","","",""]
8
8
  spec.email = %q{ops@clue.co.za}
@@ -35,24 +35,73 @@ module Adaptor
35
35
 
36
36
  def initialize( root, config, deamon_name )
37
37
 
38
- super
39
-
40
- @type = :not_eventmachine
41
-
42
38
  raise config_exception(
43
39
 
44
- "#{self.class} requires :queue:"
40
+ "#{self.class} requires :plugin:"
45
41
 
46
42
  ) if (
47
43
 
48
44
  config.nil? or
49
-
50
- not config.has_key?( :queue ) or
51
- not @queue = config[ :queue ] or
52
- @queue == ''
45
+ config[:plugin].nil?
46
+
47
+ )
48
+
49
+ super
50
+
51
+ raise config_exception(
52
+
53
+ "#{self.class} requires :plugin: to define :queue:"
54
+
55
+ ) if (
53
56
 
57
+ config[:plugin][:queue].nil?
58
+
59
+ )
60
+
61
+ @queue = config[:plugin][:queue]
62
+
63
+
64
+ #
65
+ # Departure from traditional use of resque...
66
+ # - Each job has its own failed queue
67
+ # - Failed jobs are not resubmittable
68
+ # - The failure queue contains the exception
69
+ #
70
+
71
+ failed_queue = "#{@queue}_failed"
72
+
73
+ @failed_job_class = Object.const_set( failed_queue.camelize,
74
+
75
+ Class.new do
76
+
77
+ self.instance_variable_set(
78
+
79
+ :@queue, failed_queue
80
+
81
+ )
82
+
83
+ end
84
+
54
85
  )
55
86
 
87
+ @hostname = config[:plugin][:hostname].nil? ?
88
+
89
+ 'localhost' : config[:plugin][:hostname]
90
+
91
+ @port = config[:plugin][:port].nil? ?
92
+
93
+ 6379 : config[:plugin][:port]
94
+
95
+
96
+ Resque.redis = Redis.new(
97
+
98
+ :host => @hostname,
99
+ :port => @port
100
+
101
+ )
102
+
103
+ @type = :not_eventmachine
104
+
56
105
  end
57
106
 
58
107
  def connector( params, &block )
@@ -62,7 +111,7 @@ module Adaptor
62
111
  # one at a time,
63
112
  # into the caller.
64
113
  #
65
-
114
+
66
115
  wait_for_job( @queue, &block )
67
116
 
68
117
  end
@@ -74,21 +123,49 @@ module Adaptor
74
123
  worker = Resque::Worker.new( queue )
75
124
 
76
125
  worker.work do |job_spec|
77
-
78
- new_job = job_spec.payload_class.new
79
-
80
- new_job.payload = job_spec.payload
81
-
82
- #
83
- # Job is yielded up the assignment pipeline to
84
- # get access to all the local infrastructure.
85
- #
86
-
87
- yield new_job
126
+
127
+ new_job = nil
128
+
129
+ begin
130
+
131
+ new_job = job_spec.payload_class.new
132
+
133
+ new_job.payload = job_spec.payload
134
+
135
+ #
136
+ # Job is yielded up the assignment pipeline to
137
+ # get access to all the local infrastructure.
138
+ #
139
+
140
+ yield new_job if block
141
+
142
+ rescue Exception => e
143
+
144
+ job_failed( job_spec, new_job, e )
145
+
146
+ end
88
147
 
89
148
  end
90
149
 
91
150
  end
151
+
152
+ def job_failed( spec, job, exception )
153
+
154
+ @logger.error "JOB FAILED ~ exception: #{exception.to_s}, payload: #{spec.payload}"
155
+
156
+ @root.trigger( job, :handler, :error )
157
+
158
+ Resque.enqueue(
159
+
160
+ @failed_job_class, Time.now, {
161
+ :exception => exception.inspect,
162
+ :payload => spec.payload
163
+
164
+ } )
165
+
166
+ job.error( exception )
167
+
168
+ end
92
169
 
93
170
  end
94
171
 
@@ -4,7 +4,7 @@ module Handler
4
4
 
5
5
  attr_accessor :payload
6
6
 
7
- def do_work
7
+ def work
8
8
 
9
9
  #
10
10
  # OVERRIDE
@@ -60,28 +60,10 @@ module Handler
60
60
 
61
61
 
62
62
  #
63
- # Call implementor overridable start
63
+ # Call implementor overridables
64
64
  #
65
65
  start
66
-
67
- do_work
68
-
69
-
70
- #
71
- # Job was sent up the same assignment pipeline as
72
- # socket handler,
73
- #
74
- # It has therefore been assigned into the server's
75
- # @client collection
76
- #
77
- # It needs to be removed
78
- #
79
- I.notify( @logger, "need to disconnect from server here", [:vital] )
80
- #
81
- #
82
- #
83
-
84
- stop
66
+ work
85
67
 
86
68
  end
87
69
 
@@ -12,7 +12,7 @@
12
12
 
13
13
  module Plugin
14
14
 
15
- class ResqueQueue < LanGrove::Plugin::Deferrer
15
+ class ResqueQueue < LanGrove::Plugin::Enqueuer
16
16
 
17
17
  def validate_config
18
18
 
@@ -48,11 +48,28 @@ module Plugin
48
48
  end
49
49
 
50
50
  )
51
+
52
+
53
+ @hostname = @config[:hostname].nil? ?
54
+
55
+ 'localhost' : @config[:hostname]
56
+
57
+ @port = @config[:port].nil? ?
58
+
59
+ 6379 : @config[:port]
60
+
61
+
62
+ Resque.redis = Redis.new(
63
+
64
+ :host => @hostname,
65
+ :port => @port
66
+
67
+ )
51
68
 
52
69
  end
53
70
 
54
71
 
55
- def defer_key( handler )
72
+ def enqueue_key( handler )
56
73
 
57
74
  #
58
75
  # Enqueue job with the handler.key
@@ -68,7 +85,7 @@ module Plugin
68
85
 
69
86
  end
70
87
 
71
- def defer_capsule( handler )
88
+ def enqueue_capsule( handler )
72
89
 
73
90
  #
74
91
  # Enqueue job with the handler.capsule
@@ -3,123 +3,119 @@ require 'spec_helper'
3
3
  describe Adaptor::ResqueAdaptor do
4
4
 
5
5
  before :all do
6
-
7
- class FakeJob < Handler::ResqueHandler
8
-
9
- end
6
+
7
+ @daemon_name = 'deferror'
8
+ @plugin_name = :deferror
9
+ @queue_name = :resque_handler
10
10
 
11
11
  end
12
12
 
13
13
 
14
14
  before :each do
15
15
 
16
- @queue_name = :queue_name
17
-
18
- @config = {
19
-
20
- :queue => @queue_name
21
-
22
- }
23
-
24
- @connect_spec = {
25
-
26
- :handler => {
27
-
28
- :class => Handler::ResqueHandler,
29
-
30
- :config => {}
31
-
32
- }
33
-
16
+ CONFIG.plugins[@plugin_name] = {
17
+
18
+ :class => 'ResqueQueue',
19
+ :job => 'ResqueHandler',
20
+ :queue => @queue_name
21
+
34
22
  }
35
-
23
+
36
24
  end
37
25
 
38
26
  subject {
39
27
 
40
28
  Adaptor::ResqueAdaptor.new(
41
29
 
42
- ROOT, @config , nil
30
+ ROOT, ROOT.config[:daemons][@daemon_name][:adaptor] , nil
43
31
 
44
32
  )
45
33
 
46
34
  }
35
+
47
36
 
48
- it 'raises on missing queue name' do
49
-
50
- expect {
51
-
52
- Adaptor::ResqueAdaptor.new(
53
-
54
- ROOT, { :queue => '' }, nil
55
-
56
- )
37
+ context 'raises on' do
38
+
39
+ before :each do
40
+
41
+ CONFIG.create( @daemon_name, :adaptor, 'ResqueAdaptor' )
42
+
43
+ end
44
+
45
+ it 'missing :plugin: config' do
46
+
47
+ expect {
57
48
 
58
- }.to raise_error(
59
-
60
- LanGrove::DaemonConfigException,
49
+ Adaptor::ResqueAdaptor.new(
61
50
 
62
- "Adaptor::ResqueAdaptor requires :queue:"
63
-
64
- )
51
+ ROOT, ROOT.config[:daemons][@daemon_name][:adaptor], nil
52
+
53
+ )
54
+
55
+ }.to raise_error(
56
+
57
+ LanGrove::DaemonConfigException,
58
+
59
+ "Adaptor::ResqueAdaptor requires :plugin:"
60
+
61
+ )
62
+ end
65
63
 
66
64
  end
67
65
 
68
66
  context 'uses requeue to' do
69
67
 
70
68
  before :each do
71
-
72
- @parameters = {
73
-
74
- :handler => {
75
-
76
- :class => 'FakeJob'
77
-
78
- }
79
-
80
- }
81
-
82
- #
83
- # Mock the resque infrastructure
84
- #
85
-
86
- @worker = mock( 'Resque::Worker' )
87
-
88
- @job = mock( 'Job' )
89
-
90
- @payload = {}
91
-
92
- Resque::Worker.should_receive(
93
-
94
- :new
95
-
96
- ).and_return(
97
-
98
- @worker
99
-
100
- )
101
-
102
- @worker.should_receive(
103
-
104
- :work
105
-
106
- ).and_yield(
107
-
108
- @job
109
-
69
+
70
+ CONFIG.create( @daemon_name, :adaptor, 'ResqueAdaptor', {
71
+
72
+ :plugin => @plugin_name
73
+
74
+ })
75
+
76
+ end
77
+
78
+ it 'initializes redis with hostname and port' do
79
+
80
+ Redis.should_receive(
81
+
82
+ :new).with( {:host => "localhost", :port => 6397}
83
+
110
84
  )
111
-
112
- @job.should_receive(
85
+
86
+ subject
87
+
88
+ end
89
+
90
+ it 'get jobs from a queue' do
91
+
92
+ worker = mock( 'Resque::Worker' )
93
+
94
+ job = mock( 'Resque::Job' )
95
+
96
+ Resque::Worker.should_receive(
97
+
98
+ :new ).with( @queue_name
99
+
100
+ ).and_return( worker )
101
+
102
+ worker.should_receive(
103
+
104
+ :work).and_yield( job
105
+
106
+ )
107
+
108
+ job.should_receive(
113
109
 
114
110
  :payload_class
115
111
 
116
112
  ).and_return(
117
113
 
118
- FakeJob
114
+ Handler::ResqueHandler
119
115
 
120
116
  )
121
-
122
- @job.should_receive(
117
+
118
+ job.should_receive(
123
119
 
124
120
  :payload
125
121
 
@@ -128,23 +124,19 @@ describe Adaptor::ResqueAdaptor do
128
124
  @payload
129
125
 
130
126
  )
131
-
132
- end
133
-
134
- it 'yields jobs' do
135
-
127
+
136
128
  job = nil
137
-
138
- subject.connector( @parameters ) do |new_job|
139
-
140
- job = new_job
141
-
129
+
130
+ subject.connector( {} ) do |next_job|
131
+
132
+ job = next_job
133
+
142
134
  end
143
-
144
- job.should be_a( FakeJob )
145
-
135
+
136
+ job.should be_a( Handler::ResqueHandler )
137
+
146
138
  end
147
-
139
+
148
140
  end
149
141
 
150
142
  end
@@ -1,12 +1,7 @@
1
1
  require 'langrove-plugin-resque'
2
2
 
3
- RESQUE_DEFERRER = {
4
-
5
- :class => 'ResqueQueue',
6
- :job => 'ResqueWorker',
7
- :queue => :resque_queue
8
-
9
- }
10
-
11
- ROOT = LanGrove::FakeRoot.new
3
+ RESQUE_DEFERRER =
12
4
 
5
+ CONFIG = LanGrove::FakeConfig.new
6
+ LOG = LanGrove::FakeLogger
7
+ ROOT = LanGrove::Root::Base.new( nil, LOG, CONFIG )
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: langrove-plugin-resque
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
4
+ version: '0.3'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2012-07-29 00:00:00.000000000 Z
15
+ date: 2012-07-31 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: langrove