beanstalker 0.0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,27 +1,6 @@
1
- This is Async Observer -- a Rails plugin that provides deep integration with
2
- Beanstalk.
1
+ This is Beanstalker -- a Rails gem that provides deep integration with
2
+ Beanstalk. (forked from async_observer)
3
3
 
4
- For more information, see http://async-observer.rubyforge.org/.
4
+ This version is rewritten using daemonizer.
5
5
 
6
- For more information on Beanstalk, see its home page at
7
- http://xph.us/software/beanstalkd/.
8
-
9
-
10
- Worker Options:
11
- -d : daemonize
12
- --pid [path to pidfile] : drop a pid file to a path
13
- -e [test,production,development] : set the rails environment
14
-
15
- Example Usage:
16
-
17
- start 3 workers
18
- ./vendor/plugins/async_observer/bin/worker -d --pid log/worker1.pid -e production
19
- ./vendor/plugins/async_observer/bin/worker -d --pid log/worker2.pid -e production
20
- ./vendor/plugins/async_observer/bin/worker -d --pid log/worker3.pid -e production
21
-
22
- kill one
23
- kill -s INT `cat log/worker1.pid`
24
-
25
- Remember kill a worker will cause it to go into a shutdown phase.
26
- Run the above again to kill immediately, but remember all jobs in
27
- the workers queue is lost at that point...
6
+ Documentation coming soon...
data/Rakefile CHANGED
@@ -6,12 +6,14 @@ begin
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "beanstalker"
8
8
  gem.summary = %Q{Beanstalker provides deep integration with Beanstalk. Fork from http://github.com/kristjan/async_observer}
9
- gem.description = %Q{Beanstalker provides deep integration with Beanstalk. Fork from http://github.com/kristjan/async_observer}
9
+ gem.description = %Q{Beanstalker is a tool for executing long tasks in background in our rails application.}
10
10
  gem.email = "glebpom@gmail.com"
11
11
  gem.homepage = "http://github.com/glebpom/beanstalker"
12
12
  gem.authors = ["Gleb Pomykalov"]
13
13
  # gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
- gem.add_dependency "daemonizer"
14
+ gem.add_dependency "daemonizer", "~>0.2.0"
15
+ gem.add_dependency "beanstalk-client"
16
+ gem.add_dependency "rails", ">= 2.2.0"
15
17
  end
16
18
  Jeweler::GemcutterTasks.new
17
19
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.1.1
@@ -0,0 +1,56 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{glebpom-async_observer}
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 = ["Gleb Pomykalov"]
12
+ s.date = %q{2010-07-14}
13
+ s.description = %q{async_observer provides deep integration with Beanstalk. Fork from http://github.com/kristjan/async_observer}
14
+ s.email = %q{glebpom@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "COPYING",
21
+ "README",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "glebpom-async_observer.gemspec",
25
+ "init.rb",
26
+ "lib/async_observer/daemonizer_handler.rb",
27
+ "lib/async_observer/extend.rb",
28
+ "lib/async_observer/queue.rb",
29
+ "lib/async_observer/worker.rb"
30
+ ]
31
+ s.homepage = %q{http://github.com/glebpom/async_observer}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.3.7}
35
+ s.summary = %q{async_observer provides deep integration with Beanstalk. Fork from http://github.com/kristjan/async_observer}
36
+
37
+ if s.respond_to? :specification_version then
38
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
39
+ s.specification_version = 3
40
+
41
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
42
+ s.add_runtime_dependency(%q<daemonizer>, ["~> 0.2.0"])
43
+ s.add_runtime_dependency(%q<beanstalk-client>, [">= 0"])
44
+ s.add_runtime_dependency(%q<rails>, [">= 2.2.0"])
45
+ else
46
+ s.add_dependency(%q<daemonizer>, ["~> 0.2.0"])
47
+ s.add_dependency(%q<beanstalk-client>, [">= 0"])
48
+ s.add_dependency(%q<rails>, [">= 2.2.0"])
49
+ end
50
+ else
51
+ s.add_dependency(%q<daemonizer>, ["~> 0.2.0"])
52
+ s.add_dependency(%q<beanstalk-client>, [">= 0"])
53
+ s.add_dependency(%q<rails>, [">= 2.2.0"])
54
+ end
55
+ end
56
+
@@ -0,0 +1,21 @@
1
+ module AsyncObserver
2
+ class DaemonizerHandler < Daemonizer::Handler
3
+ def prepare(block)
4
+ logger.info "Loading Rails"
5
+ require File.join(Daemonizer.root, '/config/environment')
6
+ require 'async_observer/worker'
7
+ logger.info "Rails loaded"
8
+ super
9
+ end
10
+
11
+ def start
12
+ logger.info "Starting cycle"
13
+ Worker.new(binding,
14
+ :tube => option(:tube),
15
+ :servers => option(:servers),
16
+ :worker_id => worker_id,
17
+ :workers_count => workers_count).run
18
+ logger.info "Ending cycle"
19
+ end
20
+ end
21
+ end
@@ -29,12 +29,39 @@ CLASSES_TO_EXTEND = [
29
29
  ]
30
30
 
31
31
  module AsyncObserver::Extensions
32
+ def self.included(receiver)
33
+ @@methods_async_options = {}
34
+ receiver.extend(ClassMethods)
35
+ end
36
+
37
+ module ClassMethods
38
+ def async_method(method, options = {})
39
+ methods_async_options = class_variable_get(:@@methods_async_options)
40
+ if options
41
+ class_variable_set(:@@methods_async_options, methods_async_options.merge(method.to_sym => options))
42
+ end
43
+ end
44
+ end
45
+
46
+ def interpolate_async_options(options, object)
47
+ result = {}
48
+ options.each do |k,v|
49
+ result[k] = if v.is_a?(Proc)
50
+ v.call(object)
51
+ else
52
+ v
53
+ end
54
+ end
55
+ result
56
+ end
57
+
32
58
  def async_send(selector, *args)
33
- async_send_opts(selector, {}, *args)
59
+ async_send_opts(selector, @@methods_async_options[selector.to_sym] || {}, *args)
34
60
  end
35
61
 
36
62
  def async_send_opts(selector, opts, *args)
37
- AsyncObserver::Queue.put_call!(self, selector, opts, args)
63
+ interpolated_options = interpolate_async_options(opts, self)
64
+ AsyncObserver::Queue.put_call!(self, selector, interpolated_options, args)
38
65
  end
39
66
  end
40
67
 
@@ -73,7 +100,7 @@ class Range
73
100
  fanout_opts = opts.merge(:fuzz => opts.fetch(:fanout_fuzz,
74
101
  DEFAULT_FANOUT_FUZZ))
75
102
  fanout_opts[:pri] = opts[:fanout_pri] || opts[:pri]
76
- fanout_opts = fanout_opts.reject_hash{|k,v| nil.equal?(v)}
103
+ fanout_opts = fanout_opts.reject{ |k,v| v.nil? }
77
104
  split_to(fanout_degree) do |subrange|
78
105
  subrange.async_send_opts(:async_each_opts, fanout_opts, rcv, selector,
79
106
  opts, *extra)
@@ -29,7 +29,7 @@ class << AsyncObserver::Queue
29
29
  DEFAULT_TTR = 120
30
30
  DEFAULT_TUBE = 'default'
31
31
 
32
- attr_accessor :queue, :app_version, :after_put
32
+ attr_accessor :queue, :after_put
33
33
 
34
34
  # This is a fake worker instance for running jobs synchronously.
35
35
  def sync_worker()
@@ -48,7 +48,7 @@ class << AsyncObserver::Queue
48
48
 
49
49
  def put!(obj, pri=DEFAULT_PRI, delay=DEFAULT_DELAY, ttr=DEFAULT_TTR,
50
50
  tube=DEFAULT_TUBE)
51
- return sync_run(obj) if (:direct.equal?(pri) or !queue)
51
+ return sync_run(obj) if pri == :direct || !queue
52
52
  queue.connect()
53
53
  queue.use(tube)
54
54
  info = [queue.yput(obj, pri, delay, ttr), queue.last_server]
@@ -64,14 +64,21 @@ class << AsyncObserver::Queue
64
64
  fuzz = opts.fetch(:fuzz, DEFAULT_FUZZ)
65
65
  delay = opts.fetch(:delay, DEFAULT_DELAY)
66
66
  ttr = opts.fetch(:ttr, DEFAULT_TTR)
67
- tube = opts.fetch(:tube, (app_version or DEFAULT_TUBE))
67
+ tube = opts.fetch(:tube, DEFAULT_TUBE)
68
68
  worker_opts = opts.reject{|k,v| SUBMIT_OPTS.include?(k)}
69
-
70
- pri = pri + rand(fuzz + 1) if !:direct.equal?(pri)
71
-
72
- code = gen(obj, sel, args)
73
- RAILS_DEFAULT_LOGGER.info("put #{pri} #{code}")
74
- put!(pkg(code, worker_opts), pri, delay, ttr, tube)
69
+ interpolator = opts.fetch(:interpolator, nil)
70
+
71
+ pri = pri + rand(fuzz + 1) if pri != :direct
72
+
73
+ if interpolator
74
+ code = packed = interpolator
75
+ else
76
+ code = gen(obj, sel, args)
77
+ packed = pkg(code, worker_opts)
78
+ end
79
+
80
+ RAILS_DEFAULT_LOGGER.info("put #{pri} #{code} to #{tube}")
81
+ put!(packed, pri, delay, ttr, tube)
75
82
  end
76
83
 
77
84
  def pkg(code, opts)
@@ -15,20 +15,11 @@
15
15
  # You should have received a copy of the GNU General Public License
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
-
19
- begin
20
- require 'mysql'
21
- rescue LoadError
22
- # Ignore case where we don't have mysql
23
- end
24
18
  require 'async_observer/queue'
25
- require 'async_observer/util'
26
19
 
27
20
  module AsyncObserver; end
28
21
 
29
22
  class AsyncObserver::Worker
30
- extend AsyncObserver::Util
31
- include AsyncObserver::Util
32
23
 
33
24
  SLEEP_TIME = 60 if !defined?(SLEEP_TIME) # rails loads this file twice
34
25
 
@@ -55,58 +46,50 @@ class AsyncObserver::Worker
55
46
  end
56
47
 
57
48
  def run_before_reserve
58
- before_reserves.each {|b| b.call()}
49
+ before_reserves.each {|b| b.call}
59
50
  end
60
51
  end
52
+
53
+ def logger
54
+ $logger or RAILS_DEFAULT_LOGGER
55
+ end
61
56
 
62
- def initialize(top_binding)
57
+ def initialize(top_binding, options = {})
63
58
  @top_binding = top_binding
64
59
  @stop = false
60
+ @options = options
61
+ if @options && @options[:servers]
62
+ AsyncObserver::Queue.queue = Beanstalk::Pool.new(@options[:servers])
63
+ end
65
64
  end
66
65
 
67
- def main_loop()
66
+ def main_loop
68
67
  trap('TERM') { @stop = true }
69
68
  loop do
70
69
  break if @stop
71
- safe_dispatch(get_job())
70
+ safe_dispatch(get_job)
72
71
  end
73
72
  end
74
73
 
75
- def startup()
76
- log_bracketed('worker-startup') do
77
- appver = AsyncObserver::Queue.app_version
78
- RAILS_DEFAULT_LOGGER.info "pid is #{$$}"
79
- RAILS_DEFAULT_LOGGER.info "app version is #{appver}"
80
- mark_db_socket_close_on_exec()
81
- if AsyncObserver::Queue.queue.nil?
82
- RAILS_DEFAULT_LOGGER.info 'no queue has been configured'
83
- exit(1)
84
- end
85
- AsyncObserver::Queue.queue.watch(appver) if appver
86
- end
74
+ def startup
75
+ tube = @options[:tube] || "default"
76
+ logger.info "Using tube #{tube}"
77
+ AsyncObserver::Queue.queue.watch(tube)
87
78
  flush_logger
88
79
  end
89
80
 
90
- # This prevents us from leaking fds when we exec. Only works for mysql.
91
- def mark_db_socket_close_on_exec()
92
- ActiveRecord::Base.active_connections.each(&:set_close_on_exec)
93
- rescue NoMethodError
94
- end
95
-
96
- def shutdown()
97
- log_bracketed('worker-shutdown') do
98
- do_all_work()
99
- end
81
+ def shutdown
82
+ do_all_work
100
83
  end
101
84
 
102
- def run()
103
- startup()
104
- main_loop()
85
+ def run
86
+ startup
87
+ main_loop
105
88
  rescue Interrupt
106
- shutdown()
89
+ shutdown
107
90
  end
108
91
 
109
- def q_hint()
92
+ def q_hint
110
93
  @q_hint || AsyncObserver::Queue.queue
111
94
  end
112
95
 
@@ -114,9 +97,9 @@ class AsyncObserver::Worker
114
97
  # if the connection returns a job right away, it probably has more available.
115
98
  # But if it takes time, then it's probably empty. So reuse the same
116
99
  # connection as long as it stays fast. Otherwise, have no preference.
117
- def reserve_and_set_hint()
100
+ def reserve_and_set_hint
118
101
  t1 = Time.now.utc
119
- return job = q_hint().reserve()
102
+ return job = q_hint.reserve
120
103
  ensure
121
104
  t2 = Time.now.utc
122
105
  @q_hint = if brief?(t1, t2) and job then job.conn else nil end
@@ -126,29 +109,27 @@ class AsyncObserver::Worker
126
109
  ((t2 - t1) * 100).to_i.abs < 10
127
110
  end
128
111
 
129
- def get_job()
130
- log_bracketed('worker-get-job') do
131
- loop do
132
- begin
133
- AsyncObserver::Queue.queue.connect()
134
- self.class.run_before_reserve
135
- return reserve_and_set_hint()
136
- rescue Interrupt => ex
137
- raise ex
138
- rescue SignalException => ex
139
- raise ex
140
- rescue Beanstalk::DeadlineSoonError
141
- # Do nothing; immediately try again, giving the user a chance to
142
- # clean up in the before_reserve hook.
143
- RAILS_DEFAULT_LOGGER.info 'Job deadline soon; you should clean up.'
144
- rescue Exception => ex
145
- @q_hint = nil # in case there's something wrong with this conn
146
- RAILS_DEFAULT_LOGGER.info(
147
- "#{ex.class}: #{ex}\n" + ex.backtrace.join("\n"))
148
- RAILS_DEFAULT_LOGGER.info 'something is wrong. We failed to get a job.'
149
- RAILS_DEFAULT_LOGGER.info "sleeping for #{SLEEP_TIME}s..."
150
- sleep(SLEEP_TIME)
151
- end
112
+ def get_job
113
+ loop do
114
+ begin
115
+ AsyncObserver::Queue.queue.connect
116
+ self.class.run_before_reserve
117
+ return reserve_and_set_hint
118
+ rescue Interrupt => ex
119
+ raise ex
120
+ rescue SignalException => ex
121
+ raise ex
122
+ rescue Beanstalk::DeadlineSoonError
123
+ # Do nothing; immediately try again, giving the user a chance to
124
+ # clean up in the before_reserve hook.
125
+ logger.info 'Job deadline soon; you should clean up.'
126
+ rescue Exception => ex
127
+ @q_hint = nil # in case there's something wrong with this conn
128
+ logger.info(
129
+ "#{ex.class}: #{ex}\n" + ex.backtrace.join("\n"))
130
+ logger.info 'something is wrong. We failed to get a job.'
131
+ logger.info "sleeping for #{SLEEP_TIME}s..."
132
+ sleep(SLEEP_TIME)
152
133
  end
153
134
  end
154
135
  end
@@ -160,30 +141,26 @@ class AsyncObserver::Worker
160
141
  end
161
142
 
162
143
  def safe_dispatch(job)
163
- log_bracketed('worker-dispatch') do
164
- RAILS_DEFAULT_LOGGER.info "got #{job.inspect}:\n" + job.body
165
- log_bracketed('job-stats') do
166
- job.stats.each do |k,v|
167
- RAILS_DEFAULT_LOGGER.info "#{k}=#{v}"
168
- end
169
- end
170
- begin
171
- return dispatch(job)
172
- rescue Interrupt => ex
173
- begin job.release() rescue :ok end
174
- raise ex
175
- rescue Exception => ex
176
- handle_error(job, ex)
177
- ensure
178
- flush_logger
179
- end
144
+ logger.info "got #{job.inspect}:\n" + job.body
145
+ job.stats.each do |k,v|
146
+ logger.info "#{k}=#{v}"
147
+ end
148
+ begin
149
+ return dispatch(job)
150
+ rescue Interrupt => ex
151
+ begin job.release rescue :ok end
152
+ raise ex
153
+ rescue Exception => ex
154
+ handle_error(job, ex)
155
+ ensure
156
+ flush_logger
180
157
  end
181
158
  end
182
159
 
183
160
  def flush_logger
184
- if defined?(RAILS_DEFAULT_LOGGER) &&
185
- RAILS_DEFAULT_LOGGER.respond_to?(:flush)
186
- RAILS_DEFAULT_LOGGER.flush
161
+ if defined?(logger) &&
162
+ logger.respond_to?(:flush)
163
+ logger.flush
187
164
  end
188
165
  end
189
166
 
@@ -196,25 +173,30 @@ class AsyncObserver::Worker
196
173
  end
197
174
 
198
175
  def self.default_handle_error(job, ex)
199
- RAILS_DEFAULT_LOGGER.info "Job failed: #{job.server}/#{job.id}"
200
- RAILS_DEFAULT_LOGGER.info("#{ex.class}: #{ex}\n" + ex.backtrace.join("\n"))
201
- job.decay()
176
+ logger.info "Job failed: #{job.server}/#{job.id}"
177
+ logger.info("#{ex.class}: #{ex}\n" + ex.backtrace.join("\n"))
178
+ if job.stats['releases'] > 10
179
+ job.bury
180
+ logger.info "BURY job due to many releases"
181
+ else
182
+ job.decay
183
+ end
202
184
  rescue Beanstalk::UnexpectedResponse
203
185
  end
204
186
 
205
187
  def run_ao_job(job)
206
- RAILS_DEFAULT_LOGGER.info 'running as async observer job'
188
+ logger.info 'running as async observer job'
207
189
  f = self.class.before_filter
208
190
  f.call(job) if f
209
191
  job.delete if job.ybody[:delete_first]
210
192
  run_code(job)
211
- job.delete() unless job.ybody[:delete_first]
193
+ job.delete unless job.ybody[:delete_first]
212
194
  rescue ActiveRecord::RecordNotFound => ex
213
195
  unless job.ybody[:delete_first]
214
196
  if job.age > 60
215
- job.delete() # it's old; this error is most likely permanent
197
+ job.delete # it's old; this error is most likely permanent
216
198
  else
217
- job.decay() # it could be replication delay so retry quietly
199
+ job.decay # it could be replication delay so retry quietly
218
200
  end
219
201
  end
220
202
  end
@@ -228,36 +210,14 @@ class AsyncObserver::Worker
228
210
  end
229
211
 
230
212
  def run_other(job)
231
- RAILS_DEFAULT_LOGGER.info 'trying custom handler'
213
+ logger.info 'trying custom handler'
232
214
  self.class.handle.call(job)
233
215
  end
234
216
 
235
- def do_all_work()
236
- RAILS_DEFAULT_LOGGER.info 'finishing all running jobs. interrupt again to kill them.'
217
+ def do_all_work
218
+ logger.info 'finishing all running jobs. interrupt again to kill them.'
237
219
  f = self.class.finish
238
- f.call() if f
220
+ f.call if f
239
221
  end
240
222
  end
241
223
 
242
- class ActiveRecord::ConnectionAdapters::MysqlAdapter < ActiveRecord::ConnectionAdapters::AbstractAdapter
243
- def set_close_on_exec()
244
- @connection.set_close_on_exec()
245
- end
246
- end
247
-
248
- class Mysql
249
- def set_close_on_exec()
250
- if @net
251
- @net.set_close_on_exec()
252
- else
253
- # we are in the c mysql binding
254
- RAILS_DEFAULT_LOGGER.info "Warning: we are using the C mysql binding, can't set close-on-exec"
255
- end
256
- end
257
- end
258
-
259
- class Mysql::Net
260
- def set_close_on_exec()
261
- @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
262
- end
263
- end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beanstalker
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 0
9
8
  - 1
10
- version: 0.0.1
9
+ - 1
10
+ version: 0.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gleb Pomykalov
@@ -15,13 +15,29 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-06 00:00:00 +04:00
19
- default_executable: worker
18
+ date: 2010-07-14 00:00:00 +04:00
19
+ default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: daemonizer
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 0
32
+ - 2
33
+ - 0
34
+ version: 0.2.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: beanstalk-client
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
25
41
  none: false
26
42
  requirements:
27
43
  - - ">="
@@ -31,11 +47,27 @@ dependencies:
31
47
  - 0
32
48
  version: "0"
33
49
  type: :runtime
34
- version_requirements: *id001
35
- description: Beanstalker provides deep integration with Beanstalk. Fork from http://github.com/kristjan/async_observer
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: rails
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 7
60
+ segments:
61
+ - 2
62
+ - 2
63
+ - 0
64
+ version: 2.2.0
65
+ type: :runtime
66
+ version_requirements: *id003
67
+ description: Beanstalker is a tool for executing long tasks in background in our rails application.
36
68
  email: glebpom@gmail.com
37
- executables:
38
- - worker
69
+ executables: []
70
+
39
71
  extensions: []
40
72
 
41
73
  extra_rdoc_files:
@@ -46,12 +78,11 @@ files:
46
78
  - README
47
79
  - Rakefile
48
80
  - VERSION
49
- - bin/worker
81
+ - glebpom-async_observer.gemspec
50
82
  - init.rb
51
- - lib/async_observer/daemonize.rb
83
+ - lib/async_observer/daemonizer_handler.rb
52
84
  - lib/async_observer/extend.rb
53
85
  - lib/async_observer/queue.rb
54
- - lib/async_observer/util.rb
55
86
  - lib/async_observer/worker.rb
56
87
  has_rdoc: true
57
88
  homepage: http://github.com/glebpom/beanstalker
data/bin/worker DELETED
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # async-observer - Rails plugin for asynchronous job execution
3
-
4
- # Copyright (C) 2007 Philotic Inc.
5
-
6
- # This program is free software: you can redistribute it and/or modify
7
- # it under the terms of the GNU General Public License as published by
8
- # the Free Software Foundation, either version 3 of the License, or
9
- # (at your option) any later version.
10
-
11
- # This program is distributed in the hope that it will be useful,
12
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- # GNU General Public License for more details.
15
-
16
- # You should have received a copy of the GNU General Public License
17
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
-
19
-
20
- # Use the same pointer (and therefore same buffer) for stdout and stderr.
21
- $VERBOSE = nil; STDERR = $stderr = STDOUT = $stdout; $VERBOSE = false
22
-
23
- require 'time'
24
-
25
- def load_rails_and_run
26
- # Rails initialization.
27
- # We do this here instead of using script/runner because script/runner
28
- # breaks __FILE__, which we use below.
29
- begin
30
- puts "#!load-rails!begin!#{Time.now.utc.xmlschema(6)}"
31
- require File.expand_path(File.dirname(__FILE__) + '/../../../../config/boot')
32
- puts "RAILS_ROOT=#{RAILS_ROOT.inspect}"
33
- require RAILS_ROOT + '/config/environment'
34
- ensure
35
- puts "#!load-rails!end!#{Time.now.utc.xmlschema(6)}"
36
- end
37
- require 'async_observer/worker'
38
- AsyncObserver::Worker.new(binding).run()
39
- end
40
-
41
- # set environment
42
- if ARGV.include?('-e') # check rails env
43
- env=nil
44
- ARGV.each_with_index{|arg,i| env = ARGV[i+1] if arg == '-e' }
45
- RAILS_ENV=env unless env.nil?
46
- end
47
-
48
- if ARGV.include?('-d')
49
- pidpath = 'log/worker.pid'
50
- if ARGV.include?('--pid') # look up the pid path
51
- ARGV.each_with_index{|arg,i| pidpath = ARGV[i+1] if arg == '--pid' }
52
- STDERR.puts "Missing pid file path!" and exit(1) if pidpath.nil?
53
- end
54
- unless File.writable?(File.dirname(pidpath))
55
- STDERR.puts "#{pidpath} not writable!"
56
- exit(1)
57
- end
58
-
59
- if File.exist?(pidpath)
60
- STDERR.puts "#{pidpath} exits! Make sure the worker isn't still running and try again after rm #{pidpath}"
61
- exit(1)
62
- end
63
-
64
- require File.dirname(__FILE__) + '/../lib/async_observer/daemonize'
65
- AsyncObserver::Daemonize.detach(pidpath) do
66
- load_rails_and_run
67
- end
68
- else
69
- load_rails_and_run
70
- end
@@ -1,35 +0,0 @@
1
- # async-observer - Rails plugin for asynchronous job execution
2
- # Copyright (C) 2009 Todd A. Fisher.
3
-
4
- # This program is free software: you can redistribute it and/or modify
5
- # it under the terms of the GNU General Public License as published by
6
- # the Free Software Foundation, either version 3 of the License, or
7
- # (at your option) any later version.
8
-
9
- # This program is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU General Public License for more details.
13
-
14
- # You should have received a copy of the GNU General Public License
15
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
- module AsyncObserver; end
17
-
18
- class AsyncObserver::Daemonize
19
- def self.detach(pidfile='log/worker.pid',&block)
20
- # daemonize, create a pipe to send status to the parent process, after the child has successfully started or failed
21
- fork do
22
- Process.setsid
23
- fork do
24
- Process.setsid
25
- File.open(pidfile, 'wb') {|f| f << Process.pid}
26
- at_exit { File.unlink(pidfile) }
27
- File.umask 0000
28
- STDIN.reopen "/dev/null"
29
- STDOUT.reopen "/dev/null", "a"
30
- STDERR.reopen STDOUT
31
- block.call
32
- end
33
- end
34
- end
35
- end
@@ -1,31 +0,0 @@
1
- # async-observer - Rails plugin for asynchronous job execution
2
-
3
- # Copyright (C) 2007 Philotic Inc.
4
-
5
- # This program is free software: you can redistribute it and/or modify
6
- # it under the terms of the GNU General Public License as published by
7
- # the Free Software Foundation, either version 3 of the License, or
8
- # (at your option) any later version.
9
-
10
- # This program is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- # GNU General Public License for more details.
14
-
15
- # You should have received a copy of the GNU General Public License
16
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
-
18
-
19
- require 'open3'
20
-
21
- module AsyncObserver; end
22
- module AsyncObserver::Util
23
- def log_bracketed(name)
24
- begin
25
- RAILS_DEFAULT_LOGGER.info "#!#{name}!begin!#{Time.now.utc.xmlschema(6)}"
26
- yield()
27
- ensure
28
- RAILS_DEFAULT_LOGGER.info "#!#{name}!end!#{Time.now.utc.xmlschema(6)}"
29
- end
30
- end
31
- end