simple_worker 0.3.11 → 0.3.13
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/README.markdown +34 -3
- data/lib/simple_worker/base.rb +4 -4
- data/lib/simple_worker.rb +179 -177
- metadata +17 -8
data/README.markdown
CHANGED
@@ -34,6 +34,17 @@ Here's an example worker that sends an email:
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
Test It Locally
|
38
|
+
---------------
|
39
|
+
|
40
|
+
Let's say someone does something in your app and you want to send an email about it.
|
41
|
+
|
42
|
+
worker = EmailWorker.new
|
43
|
+
worker.to = current_user.email
|
44
|
+
worker.subject = "Here is your mail!"
|
45
|
+
worker.body = "This is the body"
|
46
|
+
**worker.run**
|
47
|
+
|
37
48
|
Queue up your Worker
|
38
49
|
--------------------
|
39
50
|
|
@@ -43,7 +54,7 @@ Let's say someone does something in your app and you want to send an email about
|
|
43
54
|
worker.to = current_user.email
|
44
55
|
worker.subject = "Here is your mail!"
|
45
56
|
worker.body = "This is the body"
|
46
|
-
worker.queue
|
57
|
+
**worker.queue**
|
47
58
|
|
48
59
|
Schedule your Worker
|
49
60
|
--------------------
|
@@ -55,7 +66,12 @@ action in your application. This is almost the same as queuing your worker.
|
|
55
66
|
worker.to = current_user.email
|
56
67
|
worker.subject = "Here is your mail!"
|
57
68
|
worker.body = "This is the body"
|
58
|
-
worker.schedule(:start_at=>1.hours.since)
|
69
|
+
**worker.schedule(:start_at=>1.hours.since)**
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
Schedule your Worker Recurring
|
74
|
+
------------------------------
|
59
75
|
|
60
76
|
The alternative is when you want to user it like Cron. In this case you'll probably
|
61
77
|
want to write a script that will schedule, you don't want to schedule it everytime your
|
@@ -71,4 +87,19 @@ Create a file called 'schedule_email_worker.rb' and add this:
|
|
71
87
|
worker.body = "This is the body"
|
72
88
|
worker.schedule(:start_at=>1.hours.since, :run_every=>3600)
|
73
89
|
|
74
|
-
Now your worker will be scheduled to run every hour.
|
90
|
+
Now run it and your worker will be scheduled to run every hour.
|
91
|
+
|
92
|
+
SimpleWorker on Rails
|
93
|
+
---------------------
|
94
|
+
|
95
|
+
SimpleWorker only supports Rails 3+.
|
96
|
+
|
97
|
+
Setup:
|
98
|
+
|
99
|
+
- Make a workers directory at RAILS_ROOT/app/workers.
|
100
|
+
- In application.rb, uncomment config.autoload_paths and put:
|
101
|
+
|
102
|
+
config.autoload_paths += %W(#{config.paths.app}/workers)
|
103
|
+
|
104
|
+
Now you can use your workers like their part of your app!
|
105
|
+
|
data/lib/simple_worker/base.rb
CHANGED
@@ -21,14 +21,14 @@ module SimpleWorker
|
|
21
21
|
def inherited(subclass)
|
22
22
|
subclass.reset!
|
23
23
|
|
24
|
-
puts "subclass.inspect=" + subclass.inspect
|
25
|
-
puts 'existing caller=' + (subclass.instance_variable_defined?(:@caller_file) ? subclass.instance_variable_get(:@caller_file).inspect : "nil")
|
26
|
-
puts "caller=" + caller.inspect
|
24
|
+
# puts "subclass.inspect=" + subclass.inspect
|
25
|
+
# puts 'existing caller=' + (subclass.instance_variable_defined?(:@caller_file) ? subclass.instance_variable_get(:@caller_file).inspect : "nil")
|
26
|
+
# puts "caller=" + caller.inspect
|
27
27
|
# splits = caller[0].split(":")
|
28
28
|
# caller_file = splits[0] + ":" + splits[1]
|
29
29
|
caller_file = caller[0][0...(caller[0].index(":in"))]
|
30
30
|
caller_file = caller_file[0...(caller_file.rindex(":"))]
|
31
|
-
puts 'caller_file=' + caller_file
|
31
|
+
# puts 'caller_file=' + caller_file
|
32
32
|
# don't need these class_variables anymore probably
|
33
33
|
subclass.instance_variable_set(:@caller_file, caller_file)
|
34
34
|
|
data/lib/simple_worker.rb
CHANGED
@@ -1,178 +1,180 @@
|
|
1
|
-
require 'appoxy_api'
|
2
|
-
require
|
3
|
-
require File.join(File.dirname(__FILE__), 'simple_worker', '
|
4
|
-
require File.join(File.dirname(__FILE__), 'simple_worker', '
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
#
|
33
|
-
# - :
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
#
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
hash_to_send
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
# -
|
123
|
-
#
|
124
|
-
# -
|
125
|
-
# -
|
126
|
-
#
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
#
|
132
|
-
|
133
|
-
|
134
|
-
hash_to_send
|
135
|
-
hash_to_send["
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
ret
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
1
|
+
require 'appoxy_api'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
require File.join(File.dirname(__FILE__), 'simple_worker', 'base')
|
4
|
+
require File.join(File.dirname(__FILE__), 'simple_worker', 'config')
|
5
|
+
require File.join(File.dirname(__FILE__), 'simple_worker', 'used_in_worker')
|
6
|
+
|
7
|
+
|
8
|
+
module SimpleWorker
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_accessor :config,
|
12
|
+
:service
|
13
|
+
|
14
|
+
def configure()
|
15
|
+
SimpleWorker.config ||= Config.new
|
16
|
+
yield(config)
|
17
|
+
SimpleWorker.service = Service.new(config.access_key, config.secret_key, :config=>config)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Service < Appoxy::Api::Client
|
22
|
+
|
23
|
+
attr_accessor :config
|
24
|
+
|
25
|
+
def initialize(access_key, secret_key, options={})
|
26
|
+
puts 'Starting SimpleWorker::Service...'
|
27
|
+
self.config = options[:config] if options[:config]
|
28
|
+
super("http://api.simpleworker.com/api/", access_key, secret_key, options)
|
29
|
+
self.host = self.config.host if self.config && self.config.host
|
30
|
+
end
|
31
|
+
|
32
|
+
# Options:
|
33
|
+
# - :callback_url
|
34
|
+
# - :merge => array of files to merge in with this file
|
35
|
+
def upload(filename, class_name, options={})
|
36
|
+
|
37
|
+
# check whether it should upload again
|
38
|
+
tmp = Dir.tmpdir()
|
39
|
+
# puts 'tmp=' + tmp.to_s
|
40
|
+
md5file = "simple_workr_#{class_name.gsub("::", ".")}.md5"
|
41
|
+
existing_md5 = nil
|
42
|
+
f = File.join(tmp, md5file)
|
43
|
+
if File.exists?(f)
|
44
|
+
existing_md5 = IO.read(f)
|
45
|
+
# puts 'existing_md5=' + existing_md5
|
46
|
+
end
|
47
|
+
|
48
|
+
filename = build_merged_file(filename, options[:merge]) if options[:merge]
|
49
|
+
|
50
|
+
# sys.classes[subclass].__file__
|
51
|
+
# puts '__FILE__=' + Base.subclass.__file__.to_s
|
52
|
+
md5 = Digest::MD5.hexdigest(File.read(filename))
|
53
|
+
# puts "new md5=" + md5
|
54
|
+
|
55
|
+
if md5 != existing_md5
|
56
|
+
puts "#{class_name}: new code, so uploading"
|
57
|
+
File.open(f, 'w') { |f| f.write(md5) }
|
58
|
+
else
|
59
|
+
puts "#{class_name}: same code, not uploading"
|
60
|
+
end
|
61
|
+
|
62
|
+
mystring = nil
|
63
|
+
file = File.open(filename, "r") do |f|
|
64
|
+
mystring = f.read
|
65
|
+
end
|
66
|
+
options = {"code"=>mystring, "class_name"=>class_name}
|
67
|
+
ret = post("code/put", options)
|
68
|
+
ret
|
69
|
+
end
|
70
|
+
|
71
|
+
def build_merged_file(filename, merge)
|
72
|
+
merge = merge.dup
|
73
|
+
merge << filename
|
74
|
+
fname2 = File.join(Dir.tmpdir(), File.basename(filename))
|
75
|
+
# puts 'fname2=' + fname2
|
76
|
+
# puts 'merged_file_array=' + merge.inspect
|
77
|
+
File.open(fname2, "w") do |f|
|
78
|
+
merge.each do |m|
|
79
|
+
f.write File.open(m, 'r') { |mo| mo.read }
|
80
|
+
f.write "\n\n"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
fname2
|
84
|
+
end
|
85
|
+
|
86
|
+
def add_sw_params(hash_to_send)
|
87
|
+
# todo: remove secret key?? Can use worker service from within a worker without it now
|
88
|
+
hash_to_send["sw_access_key"] = self.access_key
|
89
|
+
hash_to_send["sw_secret_key"] = self.secret_key
|
90
|
+
end
|
91
|
+
|
92
|
+
# class_name: The class name of a previously upload class, eg: MySuperWorker
|
93
|
+
# data: Arbitrary hash of your own data that your task will need to run.
|
94
|
+
def queue(class_name, data={})
|
95
|
+
if !data.is_a?(Array)
|
96
|
+
data = [data]
|
97
|
+
end
|
98
|
+
hash_to_send = {}
|
99
|
+
hash_to_send["payload"] = data
|
100
|
+
hash_to_send["class_name"] = class_name
|
101
|
+
add_sw_params(hash_to_send)
|
102
|
+
if defined?(RAILS_ENV)
|
103
|
+
hash_to_send["rails_env"] = RAILS_ENV
|
104
|
+
end
|
105
|
+
return queue_raw(class_name, hash_to_send)
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
def queue_raw(class_name, data={})
|
110
|
+
params = nil
|
111
|
+
hash_to_send = data
|
112
|
+
hash_to_send["class_name"] = class_name
|
113
|
+
ret = post("queue/add", hash_to_send)
|
114
|
+
ret
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
#
|
120
|
+
# schedule: hash of scheduling options that can include:
|
121
|
+
# Required:
|
122
|
+
# - start_at: Time of first run - DateTime or Time object.
|
123
|
+
# Optional:
|
124
|
+
# - run_every: Time in seconds between runs. If ommitted, task will only run once.
|
125
|
+
# - delay_type: Fixed Rate or Fixed Delay. Default is fixed_delay.
|
126
|
+
# - end_at: Scheduled task will stop running after this date (optional, if ommitted, runs forever or until cancelled)
|
127
|
+
# - run_times: Task will run exactly :run_times. For instance if :run_times is 5, then the task will run 5 times.
|
128
|
+
#
|
129
|
+
def schedule(class_name, data, schedule)
|
130
|
+
raise "Schedule must be a hash." if !schedule.is_a? Hash
|
131
|
+
# if !data.is_a?(Array)
|
132
|
+
# data = [data]
|
133
|
+
# end
|
134
|
+
hash_to_send = {}
|
135
|
+
hash_to_send["payload"] = data
|
136
|
+
hash_to_send["class_name"] = class_name
|
137
|
+
hash_to_send["schedule"] = schedule
|
138
|
+
add_sw_params(hash_to_send)
|
139
|
+
# puts 'about to send ' + hash_to_send.inspect
|
140
|
+
ret = post("scheduler/schedule", hash_to_send)
|
141
|
+
ret
|
142
|
+
end
|
143
|
+
|
144
|
+
def cancel_schedule(scheduled_task_id)
|
145
|
+
raise "Must include a schedule id." if scheduled_task_id.blank?
|
146
|
+
hash_to_send = {}
|
147
|
+
hash_to_send["scheduled_task_id"] = scheduled_task_id
|
148
|
+
ret = post("scheduler/cancel", hash_to_send)
|
149
|
+
ret
|
150
|
+
end
|
151
|
+
|
152
|
+
def get_schedules()
|
153
|
+
hash_to_send = {}
|
154
|
+
ret = get("scheduler/list", hash_to_send)
|
155
|
+
ret
|
156
|
+
end
|
157
|
+
|
158
|
+
def status(task_id)
|
159
|
+
data = {"task_id"=>task_id}
|
160
|
+
ret = get("task/status", data)
|
161
|
+
ret
|
162
|
+
end
|
163
|
+
|
164
|
+
def schedule_status(schedule_id)
|
165
|
+
data = {"schedule_id"=>schedule_id}
|
166
|
+
ret = get("scheduler/status", data)
|
167
|
+
ret
|
168
|
+
end
|
169
|
+
|
170
|
+
def log(task_id)
|
171
|
+
data = {"task_id"=>task_id}
|
172
|
+
ret = get("task/log", data)
|
173
|
+
# puts 'ret=' + ret.inspect
|
174
|
+
# ret["log"] = Base64.decode64(ret["log"])
|
175
|
+
ret
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
end
|
178
180
|
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_worker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 5
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
8
|
+
- 13
|
9
|
+
version: 0.3.13
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Travis Reeder
|
@@ -15,23 +14,35 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-
|
17
|
+
date: 2010-10-24 00:00:00 -07:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
21
|
+
name: active_support
|
23
22
|
prerelease: false
|
24
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
25
|
requirements:
|
27
26
|
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
28
|
segments:
|
31
29
|
- 0
|
32
30
|
version: "0"
|
33
31
|
type: :runtime
|
34
32
|
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: appoxy_api
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
35
46
|
description: I could tell you, but then I'd have to...
|
36
47
|
email: travis@appoxy.com
|
37
48
|
executables: []
|
@@ -69,7 +80,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
80
|
requirements:
|
70
81
|
- - ">="
|
71
82
|
- !ruby/object:Gem::Version
|
72
|
-
hash: 3
|
73
83
|
segments:
|
74
84
|
- 0
|
75
85
|
version: "0"
|
@@ -78,7 +88,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
88
|
requirements:
|
79
89
|
- - ">="
|
80
90
|
- !ruby/object:Gem::Version
|
81
|
-
hash: 3
|
82
91
|
segments:
|
83
92
|
- 0
|
84
93
|
version: "0"
|