simple_worker 2.0.0.beta.16 → 2.0.0.beta.17

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -20,19 +20,6 @@ You really just need your token, which you can get [here][2]
20
20
  config.token = TOKEN
21
21
  config.project_id = MY_PROJECT_ID
22
22
  end
23
-
24
- Generate a Worker with Rails
25
- ----------------------------
26
- If you're rolling on Rails, use the following:
27
-
28
- rails generate simple_worker worker_class_in_underscore_format
29
-
30
- This will set you up with a worker in ```app/workers```
31
- However, this is not autorequired, so a line similar to this will be required in your initializer:
32
-
33
- Dir.glob("#{Rails.root}/app/workers/*.rb").each{|w| require w}
34
-
35
- This one-liner requires all ```.rb``` files in ```app/workers```
36
23
 
37
24
  Write a Worker
38
25
  --------------
@@ -41,17 +28,13 @@ Here's an example worker that sends an email:
41
28
 
42
29
  require 'simple_worker'
43
30
 
44
- class EmailWorker < SimpleWorker::Base
31
+ class HelloWorker < SimpleWorker::Base
45
32
 
46
- attr_accessor :to, :subject, :body
33
+ attr_accessor :name
47
34
 
48
35
  # This is the method that will be run
49
36
  def run
50
- send_email(:to=>to, :subject=>subject, :body=>body)
51
- end
52
-
53
- def send_email
54
- # Put sending code here
37
+ puts "Hello #{name}!"
55
38
  end
56
39
  end
57
40
 
@@ -60,10 +43,8 @@ Test It Locally
60
43
 
61
44
  Let's say someone does something in your app and you want to send an email about it.
62
45
 
63
- worker = EmailWorker.new
64
- worker.to = current_user.email
65
- worker.subject = "Here is your mail!"
66
- worker.body = "This is the body"
46
+ worker = HelloWorker.new
47
+ worker.name = "Travis"
67
48
  worker.run_local
68
49
 
69
50
  Once you've got it working locally, the next step is to run it on the SimpleWorker cloud.
@@ -73,279 +54,19 @@ Queue up your Worker on the SimpleWorker Cloud
73
54
 
74
55
  Let's say someone does something in your app and you want to send an email about it.
75
56
 
76
- worker = EmailWorker.new
77
- worker.to = current_user.email
78
- worker.subject = "Here is your mail!"
79
- worker.body = "This is the body"
57
+ worker = HelloWorker.new
58
+ worker.name = "Travis"
80
59
  worker.queue
81
60
 
82
61
  This will send it off to the SimpleWorker cloud.
83
62
 
84
- To queue worker without uploading you could try to do following:
85
-
86
- data[:attr_encoded] = Base64.encode64({'@to'=>'example@email.com'}.to_json)
87
- data[:sw_config] = SimpleWorker.config.get_atts_to_send
88
- SimpleWorker.service.queue('EmailWorker', data)
89
-
90
-
91
-
92
- Setting Priority
93
- ----------------------------------------------
94
-
95
- Simply define the priority in your queue command.
96
-
97
- worker.queue(:priority=>1)
98
-
99
- Default priority is 0 and we currently support priority 0, 1, 2. See [pricing page](http://www.simpleworker.com/pricing)
100
- for more information on priorites.
101
-
102
-
103
- Schedule your Worker
104
- --------------------
105
-
106
- There are two scenarios here, one is the scenario where you want something to happen due to a user
107
- action in your application. This is almost the same as queuing your worker.
108
-
109
- worker = EmailWorker.new
110
- worker.to = current_user.email
111
- worker.subject = "Here is your mail!"
112
- worker.body = "This is the body"
113
- worker.schedule(:start_at=>1.hours.since)
114
-
115
- By default, if you call `schedule` more than once for the same worker class, the new schedule will replace the old one. If you'd
116
- like multiple schedules for the same class, provide a `:name` parameter:
117
-
118
- worker.schedule(:name=>"EmailWorkerDaily", :start_at=>......)
119
-
120
- You can also set priority for scheduled jobs:
121
-
122
- worker.schedule(:priority=>1, ....)
123
-
124
-
125
- Check Status
126
- ------------
127
-
128
- If you still have access to the worker object, just call:
129
-
130
- worker.status
131
-
132
- If you only have the job ID, call:
133
-
134
- SimpleWorker.service.status(job_id)
135
-
136
- This will return a hash like:
137
-
138
- {"task_id"=>"ece460ce-12d8-11e0-8e15-12313b0440c6",
139
- "status"=>"running",
140
- "msg"=>nil,
141
- "start_time"=>"2010-12-28T23:19:36+00:00",
142
- "end_time"=>nil,
143
- "duration"=>nil,
144
- "progress"=>{"percent"=>25}}
145
-
146
- There is also a convenience method `worker.wait_until_complete` that will wait until the status returned is completed or error.
147
-
148
- Logging
149
- -------
150
-
151
- In your worker, just call the log method with the string you want logged:
152
-
153
- log "Starting to do something..."
154
-
155
- The log will be available for viewing via the SimpleWorker UI or via log in the API:
156
-
157
- SimpleWorker.service.log(job_id)
158
-
159
- or if you still have a handle to your worker object:
160
-
161
- worker.get_log
162
-
163
- Setting Progress
164
- ----------------
165
-
166
- This is just a way to let your users know where the job is at if required.
167
-
168
- set_progress(:percent => 25, :message => "We are a quarter of the way there!")
169
-
170
- You can actually put anything in this hash and it will be returned with a call to status. We recommend using
171
- the format above for consistency and to get some additional features where we look for these values.
172
-
173
- Schedule a Recurring Job - CRON
174
- ------------------------------
175
-
176
- The alternative is when you want to user it like Cron. In this case you'll probably
177
- want to write a script that will schedule, you don't want to schedule it everytime your
178
- app starts or anything so best to keep it external.
179
-
180
- Create a file called 'schedule_email_worker.rb' and add this:
181
-
182
- require 'simple_worker'
183
- require_relative 'email_worker'
184
-
185
- worker = EmailWorker.new
186
- worker.to = current_user.email
187
- worker.subject = "Here is your mail!"
188
- worker.body = "This is the body"
189
- worker.schedule(:start_at=>1.hours.since, :run_every=>3600)
190
-
191
- Now run it and your worker will be scheduled to run every hour.
192
-
193
- SimpleWorker on Rails
194
- ---------------------
195
-
196
- Rails 2.X:
197
-
198
- config.gem 'simple_worker'
199
-
200
- Rails 3.X:
201
-
202
- gem 'simple_worker'
203
-
204
- Now you can use your workers like they're part of your app! We recommend putting your worker classes in
205
- /app/workers path.
206
-
207
- Configuring a Database Connection
208
- ---------------------------------
209
-
210
- Although you could easily do this in your worker, this makes it a bit more convenient and more importantly
211
- it will create the connection for you. If you are using Rails 3, you just need to add one line:
212
-
213
- config.database = Rails.configuration.database_configuration[Rails.env]
214
-
215
- For non Rails 3, you would add the following to your SimpleWorker config:
216
-
217
- config.database = {
218
- :adapter => "mysql2",
219
- :host => "localhost",
220
- :database => "appdb",
221
- :username => "appuser",
222
- :password => "secret"
223
- }
224
-
225
- Then before you job is run, SimpleWorker will establish the ActiveRecord connection.
226
-
227
- Including/Merging other Ruby Classes
228
- ------------------------------------
229
-
230
- If you need to inclue other classes in for your worker to use (which is very common), then you'll
231
- want to use the merge functions. For example:
232
-
233
- class AvgWorker < SimpleWorker::Base
234
-
235
- attr_accessor :aws_access_key,
236
- :aws_secret_key,
237
- :s3_suffix
238
-
239
- merge File.join(File.dirname(__FILE__), "..", "app", "models", "user.rb")
240
- merge File.join(File.dirname(__FILE__), "..", "app", "models", "account")
241
-
242
- Or simpler yet, try using relative paths:
243
-
244
- merge "../models/user"
245
- merge "../models/account.rb"
246
-
247
- Also you could use wildcards and path in merge_folder
248
-
249
- merge_folder "./foldername/" #will merge all *.rb files from foldername
250
- merge_folder "../lib/**/" # will merge all *.rb files from lib and all subdirectories
251
-
252
- The opposite can be done as well with "unmerge" and can be useful when using Rails to exclude classes that are automatically
253
- merged.
254
-
255
-
256
- Merging other Workers
257
- ---------------------
258
-
259
- Merging other workers is a bit different than merging other code like above because they will be
260
- uploaded separately and treated as distinctly separate workers.
261
-
262
- merge_worker "./other_worker.rb", "OtherWorker"
263
-
264
- Merging Mailers
265
- ---------------------
266
-
267
- You could easily merge mailers you're using in your application.
268
-
269
- merge_mailer 'mailer_file' #if your mailer's templates are placed in default path
270
- #or
271
- merge_mailer 'mailer_file', {:path_to_templates=>"templates_path"}#if you're using mailer outside of rails with custom templates path
272
-
273
- ### Configuring a Mailer Connection
274
-
275
- If you are using Rails 3,your action_mailer connection would be configured automatically from your config
276
-
277
- For non Rails 3 or if you want to use different mailer configs, you should add the following to your SimpleWorker config:
278
-
279
- config.mailer = {
280
- :address => "smtp.gmail.com",
281
- :port => 587,
282
- :domain => 'gmail.com',
283
- :user_name => GMAIL_USERNAME
284
- :password => GMAIL_PASSWORD
285
- :authentication => 'plain',
286
- :enable_starttls_auto => true}
287
-
288
- Then before you job is run, SimpleWorker will establish the ActionMailer connection.
289
-
290
- Merging Gems
291
- ---------------------
292
-
293
- This allows you to use any gem you'd like with SimpleWorker. This uses the same syntax as bundler gem files.
294
-
295
- # merge latest version of the gem
296
- merge_gem "some_gem"
297
- # or specify specific version
298
- merge_gem "some_gem_with_version", "1.2.3"
299
- # or if gem has poor naming scheme
300
- merge_gem 'mongoid_i18n', :require => 'mongoid/i18n'
301
- # of if gem requires other directories outside lib
302
- merge_gem 'prawn', :include_dirs=>['data']
303
-
304
-
305
- [Check here for more info on merge_gem](http://support.simpleworker.com/kb/working-with-simpleworker/merging-gems-into-your-worker).
306
-
307
-
308
- Job Timeout
309
- --------------
310
-
311
- By default, each job has 60 minutes (3600 seconds to complete). If you know that your job should take less than that, you can specify a timeout explicitly:
312
-
313
- worker.queue(:timeout=>1800)
314
-
315
- This will kill your job if it is running more than 1800 seconds, or half an hour.
316
-
317
-
318
-
319
- Global Merging
320
- --------------
321
-
322
- If you want to merge items for all of your workers, you can do merges in your SimpleWorker.configure block:
323
-
324
- config.merge 'my file'
325
- config.merge_gem 'httparty'
326
-
327
-
328
-
329
- Configuration Options
330
- ---------------------
331
-
332
- ### Global Attributes
333
-
334
- These are attributes that can be set as part of your config block then will be set on
335
- all your worker objects automatically. This is particularly good for things like database
336
- connection info or things that you would need to use across the board.
337
-
338
- Eg:
339
-
340
- config.global_attributes[:db_user] = "sa"
341
- config.global_attributes[:db_pass] = "pass"
342
-
343
- Then in your worker, you would have the attributes defined:
344
-
345
- attr_accessor :db_user, :db_pass
63
+ Full Documentation
64
+ -----------------
346
65
 
66
+ Now that you've got your first worker running, be sure to [check out the full documentation](http://docs.simpleworker.com).
67
+ SimpleWorker can do so much more!
347
68
 
348
- Development of the Gem
69
+ Discussion Group
349
70
  ----------------------
350
71
 
351
72
  Join the discussion group at: https://groups.google.com/forum/?hl=en#!forum/simple_worker
@@ -1,5 +1,5 @@
1
1
  require 'rest_client'
2
- require 'patron'
2
+ require 'typhoeus'
3
3
 
4
4
  module SimpleWorker
5
5
 
@@ -56,14 +56,6 @@ module SimpleWorker
56
56
 
57
57
  @base_url = "#{@scheme}://#{@host}:#{@port}/#{@version}"
58
58
 
59
- sess = Patron::Session.new
60
- sess.timeout = 10
61
- sess.base_url = @base_url
62
- sess.headers['User-Agent'] = 'IronMQ Ruby Client'
63
- #sess.enable_debug "/tmp/patron.debug"
64
- @http_sess = sess
65
-
66
-
67
59
  end
68
60
 
69
61
 
@@ -76,13 +68,21 @@ module SimpleWorker
76
68
  "/#{command_path}"
77
69
  end
78
70
 
79
- # Used for RestClient ones that haven't been converted to patron yet
80
- def url_full(command_path)
71
+ def url_full(command_path)
81
72
  url = "#{base_url}/#{command_path}"
82
73
  # @logger.debug "url: " + url.to_s
83
74
  url
84
75
  end
85
76
 
77
+
78
+ def common_req_hash
79
+ {
80
+ :headers=>{"Content-Type" => 'application/json',
81
+ "Authorization"=>"OAuth #{@token}",
82
+ "User-Agent"=>"SimpleWorker Ruby Client"}
83
+ }
84
+ end
85
+
86
86
  def process_ex(ex)
87
87
  logger.error "EX #{ex.class.name}: #{ex.message}"
88
88
  body = ex.http_body
@@ -94,9 +94,18 @@ module SimpleWorker
94
94
  raise exception
95
95
  end
96
96
 
97
+
97
98
  def check_response(response, options={})
98
- status = response.status
99
+ # response.code # http status code
100
+ #response.time # time in seconds the request took
101
+ #response.headers # the http headers
102
+ #response.headers_hash # http headers put into a hash
103
+ #response.body # the response body
104
+ status = response.code
99
105
  body = response.body
106
+ # todo: check content-type == application/json before parsing
107
+ logger.debug "response code=" + status.to_s
108
+ logger.debug "response body=" + body.inspect
100
109
  res = nil
101
110
  unless options[:parse] == false
102
111
  res = JSON.parse(body)
@@ -110,13 +119,16 @@ module SimpleWorker
110
119
  end
111
120
 
112
121
  def get(method, params={}, options={})
113
- full_url = url(method)
114
- all_params = add_params(method, params)
115
- url_plus_params = append_params(full_url, all_params)
116
- logger.debug 'get url=' + url_plus_params
117
- response = @http_sess.request(:get, url_plus_params,
118
- {},
119
- {})
122
+ full_url = url_full(method)
123
+ #all_params = add_params(method, params)
124
+ #url_plus_params = append_params(full_url, all_params)
125
+ logger.debug 'get url=' + full_url
126
+ req_hash = common_req_hash
127
+ req_hash[:params] = params
128
+ response = Typhoeus::Request.get(full_url, req_hash) # could let typhoeus add params, using :params=>x
129
+ #response = @http_sess.request(:get, url_plus_params,
130
+ # {},
131
+ # {})
120
132
  check_response(response, options)
121
133
  body = response.body
122
134
  parse_response(body, options)
@@ -131,7 +143,7 @@ module SimpleWorker
131
143
  logger.debug "data = " + data
132
144
  logger.debug "params = " + params.inspect
133
145
  logger.debug "options = " + options.inspect
134
- # todo: replace with patron
146
+ # todo: replace with typhoeus
135
147
  parse_response(RestClient.post(append_params(url, add_params(method, params)), {:data => data, :file => file}, :content_type => 'application/json'), options)
136
148
  rescue RestClient::Exception => ex
137
149
  process_ex(ex)
@@ -144,11 +156,14 @@ module SimpleWorker
144
156
  logger.debug "params.payload = " + params[:payload].inspect
145
157
  logger.debug "token = "+ token.inspect
146
158
  begin
147
- url = url(method) + "?oauth=" + token
159
+ url = url_full(method)
148
160
  logger.debug 'post url=' + url
149
161
  json = add_params(method, params).to_json
150
162
  logger.debug 'body=' + json
151
- response = @http_sess.post(url, json, {"Content-Type" => 'application/json'})
163
+ req_hash = common_req_hash
164
+ req_hash[:body] = json
165
+ response = Typhoeus::Request.post(url, req_hash)
166
+ #response = @http_sess.post(url, json, {"Content-Type" => 'application/json'})
152
167
  check_response(response)
153
168
  logger.debug 'response: ' + response.inspect
154
169
  body = response.body
@@ -156,7 +171,7 @@ module SimpleWorker
156
171
  rescue SimpleWorker::RequestError => ex
157
172
  # let it throw, came from check_response
158
173
  raise ex
159
- rescue Exception => ex
174
+ rescue RestClient::Exception => ex
160
175
  logger.warn("Exception in post! #{ex.message}")
161
176
  logger.warn(ex.backtrace.join("\n"))
162
177
  process_ex(ex)
@@ -166,7 +181,7 @@ module SimpleWorker
166
181
 
167
182
  def put(method, body, options={})
168
183
  begin
169
- # todo: replace with patron
184
+ # todo: replace with typhoeus
170
185
  parse_response RestClient.put(url_full(method), add_params(method, body).to_json, headers), options
171
186
  rescue RestClient::Exception => ex
172
187
  process_ex(ex)
@@ -175,7 +190,7 @@ module SimpleWorker
175
190
 
176
191
  def delete(method, params={}, options={})
177
192
  begin
178
- # todo: replace with patron
193
+ # todo: replace with typhoeus
179
194
  parse_response RestClient.delete(append_params(url_full(method), add_params(method, params))), options
180
195
  rescue RestClient::Exception => ex
181
196
  process_ex(ex)
@@ -167,6 +167,17 @@ require 'json'
167
167
  end
168
168
  end
169
169
 
170
+ File.open(File.join(File.dirname(__FILE__), 'server', 'overrides.rb'), 'r') do |fr|
171
+ while line = fr.gets
172
+ f.write line
173
+ end
174
+ end
175
+
176
+ # Now we must disable queuing while loading up classes. This is from the overrides.rb file
177
+ f.write("
178
+ SimpleWorker.disable_queueing()
179
+ ")
180
+
170
181
 
171
182
  File.open(File.join(File.dirname(__FILE__), "server", 'runner.rb'), 'r') do |fr|
172
183
  while line = fr.gets
@@ -210,13 +221,7 @@ end
210
221
  f.write "init_mailer(sw_config)\n"
211
222
  f.write "ActionMailer::Base.prepend_view_path('templates')\n"
212
223
  end
213
- f.write "init_database_connection(sw_config)"
214
-
215
- File.open(File.join(File.dirname(__FILE__), 'server', 'overrides.rb'), 'r') do |fr|
216
- while line = fr.gets
217
- f.write line
218
- end
219
- end
224
+ f.write "init_database_connection(sw_config)\n"
220
225
 
221
226
  merged.each_pair do |k, v|
222
227
  if v[:extname] == ".rb"
@@ -228,14 +233,15 @@ end
228
233
  end
229
234
  #end
230
235
  #f.write File.open(filename, 'r') { |mo| mo.read }
231
- f.write("require_relative '#{File.basename(filename)}'")
236
+ f.write("require_relative '#{File.basename(filename)}'\n")
232
237
 
233
238
  f.write("
234
- SimpleWorker.disable_queueing()
235
239
  runner_class = get_class_to_run(job_data['class_name'])
236
240
  SimpleWorker.running_class = runner_class
237
241
  runner = init_runner(runner_class, job_data, dirname, task_id)
238
242
  init_worker_service_for_runner(job_data)
243
+
244
+ # Now reenable after loading
239
245
  SimpleWorker.enable_queueing()
240
246
 
241
247
  # Let's run it!
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: simple_worker
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 6
5
- version: 2.0.0.beta.16
5
+ version: 2.0.0.beta.17
6
6
  platform: ruby
7
7
  authors:
8
8
  - Travis Reeder
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-11-02 00:00:00 Z
13
+ date: 2011-11-03 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: zip
@@ -35,7 +35,7 @@ dependencies:
35
35
  type: :runtime
36
36
  version_requirements: *id002
37
37
  - !ruby/object:Gem::Dependency
38
- name: patron
38
+ name: typhoeus
39
39
  prerelease: false
40
40
  requirement: &id003 !ruby/object:Gem::Requirement
41
41
  none: false