fanforce-worker 0.5.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NGZiNDQyNDQ3MzFmYmI2ZWVhZTExZjc3MDFjNzVmODk0OGQ3MzRlZg==
4
+ YmY2YzQ4NDNlOTEwOWMzMWIxMGYzMTBjNDMxOTY0ODViZjVmOGM0MQ==
5
5
  data.tar.gz: !binary |-
6
- YTM0NDNkN2I3OGQ5YmQ1Yzg2NmM5MzZkOGIyOWZhMzRhYjhkOGI1Ng==
6
+ NmU1YTU5M2Q1ZTcxZjJkNTZhNTBlZTNlN2Y1MWQ5NDlhNjVkZjIzZg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NzU5NTNkYTYzODViNGJiYTc4NWVmYTkyYmJlN2QyYzdiMjgzYjNiYjA3Y2Vk
10
- Y2MyNjQ1ODFmMzQxZGFhYTEzOGEwMmNlMjgxNGFmYjFjMjk5M2Q4ZDVmNWMx
11
- N2M5NDA3ODgxNjI2ZWMyNzYxNTM4NDJjMGIwZDk0OWMxZTU4Mzk=
9
+ Y2ZkOTkxMWIwMjE2MTBiOGM1ZTdkZGVmZDI1MzdjNzU4Yzk3ZWVkNjVjMTQ0
10
+ MmRhNDc1NjQzYTUwYjZkNGE2ZTBjNjk5NDU0M2YyZDNiYWNjZjBjNWQ2YWVl
11
+ YzI4NmQyZmZlOTNhZjZmNmExZmE0NjkwNDJiYThiZWM5ZjZkNDM=
12
12
  data.tar.gz: !binary |-
13
- MzFjN2RkNDI3YTI0OWQ1ZjY3ZmQ3MWNjMmRjNzcyZTY5ZmI5MmM1ZTQ4NjJm
14
- NzZiYWIwODI2OGZkODI1NmY5ZTNmYjM4MWM5NWI5MGYyZWViZTBkZGYwOTM4
15
- NGVmN2M2YzgxMzNhMGViNzRkOGM1ZmExOGM4NDhhMzU3NDczNTk=
13
+ ZGJhYzM3MmZmYTljODhhZGJhODc1OWYzMmY5YmQ5OGMwYmYxYWI1YzhkYWI3
14
+ ZTI4Mzg3OWM3NmI2NmVmOTlhMGI5Mzc2MmRmMmJmZDg3NzVlNzY3Y2U2MGU4
15
+ ZTZmMGY4ZWVlNTUzYWMwNTEyYmUwYzUxOThmYTRiZDAzZTNhZjI=
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
1
  fanforce-worker
2
2
  ==
3
3
 
4
- Fanforce worker library used by addons to connect with iron_mg and iron_worker_ng
4
+ Fanforce worker used by addons to connect with iron_mg and iron_worker_ng
@@ -7,7 +7,7 @@ Gem::Specification.new do |gem|
7
7
  gem.name = 'fanforce-worker'
8
8
  gem.version = Fanforce::Worker::VERSION
9
9
  gem.date = '2012-10-19'
10
- gem.summary = %q{Fanforce worker library used by various Fanforce addons.}
10
+ gem.summary = %q{Fanforce worker used by various Fanforce addons for background processing.}
11
11
  gem.authors = ['Caleb Clark']
12
12
  gem.email = ['cclark@fanforce.com']
13
13
  gem.homepage = 'http://github.com/fanforce/fanforce-worker'
@@ -17,6 +17,9 @@ Gem::Specification.new do |gem|
17
17
  gem.require_paths = ['lib']
18
18
 
19
19
  gem.add_runtime_dependency 'iron_mq', '~> 4'
20
- gem.add_runtime_dependency 'typhoeus'
21
- gem.add_runtime_dependency 'fanforce-api', '~> 0.9'
20
+ gem.add_runtime_dependency 'iron_cache', '~> 1.4'
21
+ gem.add_runtime_dependency 'uuidtools', '~> 2.1'
22
+ gem.add_runtime_dependency 'activesupport', '~> 3.2'
23
+
24
+ gem.add_runtime_dependency 'fanforce-api', '~> 0.14'
22
25
  end
@@ -1,6 +1,5 @@
1
1
  class Fanforce
2
2
  require_relative 'worker/version'
3
- require_relative 'worker/workers'
4
3
  require_relative 'worker/worker'
5
4
  end
6
5
 
@@ -1,5 +1,5 @@
1
1
  class Fanforce
2
2
  class Worker
3
- VERSION = '0.5.0'
3
+ VERSION = '0.10.0'
4
4
  end
5
5
  end
@@ -0,0 +1,214 @@
1
+ class Fanforce::Worker
2
+
3
+ LOAD_TIME = Time.now
4
+
5
+ def initialize(opts={})
6
+ @opts = opts
7
+ end
8
+
9
+ def iron_mq
10
+ require 'iron_mq'
11
+ @iron_mq ||= IronMQ::Client.new(:token => @opts[:token] || ENV['IRON_TOKEN'], :project_id => @opts[:project_id] || ENV['IRON_PROJECT_ID'])
12
+ end
13
+
14
+ def iron_cache
15
+ require 'iron_cache'
16
+ @iron_cache ||= IronCache::Client.new(:token => @opts[:token] || ENV['IRON_TOKEN'], :project_id => @opts[:project_id] || ENV['IRON_PROJECT_ID'])
17
+ end
18
+
19
+ def enqueue(queue_id, params, options={})
20
+ retries = (options[:retries].present?) ? options.delete(:retries) : 0
21
+ raise 'Params being sent to the queue must be a Hash' if !params.is_a?(Hash)
22
+ iron_mq.queue(queue_id).post({params: params, retries: retries}.to_json, options)
23
+ end
24
+
25
+ def add_error(queue_id, error)
26
+ require 'uuidtools'
27
+ details_id = UUIDTools::UUID.random_create.to_s
28
+ iron_cache.cache("#{queue_id}-ERRORS").put(details_id, error.to_json)
29
+ iron_mq.queue("#{queue_id}-ERRORS").post({
30
+ details_id: details_id,
31
+ exception: truncate(error[:exception]),
32
+ message: truncate(error[:message].to_s),
33
+ params: truncate(error[:params].to_json),
34
+ errored_at: error[:errored_at],
35
+ retries: error[:retries],
36
+ env_vars: truncate(error[:env_vars].to_json),
37
+ curl_command: truncate(error[:curl_command].to_s)
38
+ }.to_json)
39
+ rescue => e
40
+ puts '-----------------------------------------------------'
41
+ puts 'WORKER ERROR WHILE RECOVERING FROM JOB ERROR:'
42
+ puts e.message
43
+ puts e.backtrace
44
+ puts '-----------------------------------------------------'
45
+ puts 'JOB ERROR:'
46
+ puts "details_id: #{details_id}"
47
+ puts "exception: #{truncate(error[:exception])}"
48
+ puts "message: #{truncate(error[:message].to_s)}"
49
+ puts "params: #{truncate(error[:params].to_json)}"
50
+ puts "errored_at: #{error[:errored_at]}"
51
+ puts "retries: #{error[:retries]}"
52
+ puts "env_vars: #{truncate(error[:env_vars].to_json)}"
53
+ puts "curl_command: #{truncate(error[:curl_command].to_s)}"
54
+ end
55
+
56
+ def delete_error(queue_id, job_id, details_id)
57
+ iron_mq.queue("#{queue_id}-ERRORS").delete(job_id)
58
+ iron_cache.cache("#{queue_id}-ERRORS").delete(details_id)
59
+ end
60
+
61
+ def error_details(queue_id, details_id)
62
+ cache = iron_cache.cache("#{queue_id}-ERRORS").get(details_id)
63
+ MultiJson.load(cache.value, :symbolize_keys => true)
64
+ end
65
+
66
+ def retry_error(queue_id, job_id, details_id)
67
+ cache = iron_cache.cache("#{queue_id}-ERRORS").get(details_id)
68
+ cache_data = MultiJson.load(cache.value, :symbolize_keys => true)
69
+ enqueue(queue_id, cache_data[:params], :retries => cache_data[:retries] + 1)
70
+
71
+ cache.delete and iron_mq.queue("#{queue_id}-ERRORS").delete(job_id)
72
+ end
73
+
74
+ def truncate(text, length=130, truncate_string="...")
75
+ if text
76
+ l = length - truncate_string.chars.to_a.length
77
+ chars = text.chars.to_a
78
+ (chars.length > length ? chars[0...l].join('') + truncate_string : text).to_s
79
+ end
80
+ end
81
+
82
+ ##########################################################################################
83
+
84
+ def self.enqueue(queue_id, params, options={})
85
+ self.new.enqueue(queue_id, params, options)
86
+ end
87
+
88
+ def self.add_error(queue_id, error)
89
+ self.new.add_error(queue_id, error)
90
+ end
91
+
92
+ ##########################################################################################
93
+
94
+ def self.current_queue_id=(queue_id)
95
+ @current_queue_id = queue_id
96
+ end
97
+
98
+ def self.current_queue_id
99
+ @current_queue_id
100
+ end
101
+
102
+ def self.current_worker_env=(env_vars)
103
+ @current_worker_env = env_vars
104
+ end
105
+
106
+ def self.current_worker_env
107
+ @current_worker_env
108
+ end
109
+
110
+ def self.current_params=(params)
111
+ @current_params = params
112
+ end
113
+
114
+ def self.current_params
115
+ @current_params
116
+ end
117
+
118
+ def self.current_retries=(retries)
119
+ @current_retries = retries
120
+ end
121
+
122
+ def self.current_retries
123
+ @current_retries
124
+ end
125
+
126
+ def self.current_job=(job)
127
+ @current_job = job
128
+ end
129
+
130
+ def self.current_job
131
+ @current_job
132
+ end
133
+
134
+ def self.load_env
135
+ if File.exists?('.developmentenv.rb')
136
+ require '.developmentenv'
137
+ elsif File.exists?('.stagingenv.rb')
138
+ require '.stagingenv'
139
+ elsif File.exists?('.productionenv.rb')
140
+ require '.productionenv'
141
+ end
142
+ end
143
+
144
+ def self.run(worker_data, &code_block)
145
+ load_env
146
+ require 'iron_mq'
147
+ require 'iron_cache'
148
+ require 'fanforce/api'
149
+ require 'active_support/all'
150
+
151
+ self.current_queue_id = worker_data['queue_id']
152
+ self.current_worker_env = worker_data['env_vars']
153
+ queue = IronMQ::Client.new.queue(current_queue_id)
154
+
155
+ job_num = 0
156
+ puts 'PROCESSING...'
157
+ while (Time.now - LOAD_TIME) < 1800 and (job = queue.get(timeout: 3600)) do
158
+ puts "JOB #{job_num+=1}: #{job.body}"
159
+ run_job job, &code_block
160
+ self.delete_job
161
+ end
162
+ self.delete_job
163
+ puts 'DONE'
164
+ end
165
+
166
+ def self.retry(options)
167
+ self.new.enqueue(current_queue_id, current_params, options.merge(retries: current_retries + 1))
168
+ end
169
+
170
+ def self.run_job(job, &code_block)
171
+ puts '----------------------------------------------------------'
172
+ print 'PROCESSING MESSAGE: '
173
+
174
+ task_data = Fanforce.decode_json(job.body)
175
+ self.current_job = job
176
+ self.current_params = task_data[:params]
177
+ self.current_retries = task_data[:retries]
178
+
179
+ set_env_vars(current_worker_env)
180
+ code_block.call(task_data[:params].clone, retries: task_data[:retries], queue_id: current_queue_id)
181
+ self.delete_job(job)
182
+
183
+ rescue Exception => e
184
+ if job.nil?
185
+ puts 'MESSAGE IS NIL'
186
+ return
187
+ end
188
+ error = task_data.merge(
189
+ exception: e.class.name,
190
+ message: e.message,
191
+ backtrace: e.backtrace,
192
+ errored_at: Time.now,
193
+ env_vars: current_worker_env
194
+ )
195
+ error[:curl_command] = e.curl_command if e.respond_to?(:curl_command)
196
+
197
+ puts "ADDING TO ERROR CACHE: #{error.to_json}"
198
+ self.delete_job(job)
199
+ puts 'DELETED MESSAGE'
200
+
201
+ self.add_error current_queue_id, error
202
+ end
203
+
204
+ def self.delete_job(job=nil)
205
+ return if job.nil? and current_job.nil?
206
+ (job || current_job).delete
207
+ self.current_job = nil
208
+ end
209
+
210
+ def self.set_env_vars(vars)
211
+ vars.each {|k,v| ENV[k.to_s]=v }
212
+ end
213
+
214
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fanforce-worker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Caleb Clark
@@ -25,33 +25,61 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '4'
27
27
  - !ruby/object:Gem::Dependency
28
- name: typhoeus
28
+ name: iron_cache
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: uuidtools
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
32
46
  - !ruby/object:Gem::Version
33
- version: '0'
47
+ version: '2.1'
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - ! '>='
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
39
67
  - !ruby/object:Gem::Version
40
- version: '0'
68
+ version: '3.2'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: fanforce-api
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - ~>
46
74
  - !ruby/object:Gem::Version
47
- version: '0.9'
75
+ version: '0.14'
48
76
  type: :runtime
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - ~>
53
81
  - !ruby/object:Gem::Version
54
- version: '0.9'
82
+ version: '0.14'
55
83
  description:
56
84
  email:
57
85
  - cclark@fanforce.com
@@ -65,9 +93,8 @@ files:
65
93
  - Rakefile
66
94
  - fanforce-worker.gemspec
67
95
  - lib/fanforce/worker.rb
68
- - lib/fanforce/worker/iron.rb
69
96
  - lib/fanforce/worker/version.rb
70
- - lib/fanforce/worker/worker.rb
97
+ - lib/fanforce/worker/workers.rb
71
98
  homepage: http://github.com/fanforce/fanforce-worker
72
99
  licenses: []
73
100
  metadata: {}
@@ -90,5 +117,5 @@ rubyforge_project:
90
117
  rubygems_version: 2.0.3
91
118
  signing_key:
92
119
  specification_version: 4
93
- summary: Fanforce worker library used by various Fanforce addons.
120
+ summary: Fanforce worker used by various Fanforce addons for background processing.
94
121
  test_files: []
@@ -1,17 +0,0 @@
1
- require 'iron_mq'
2
-
3
- class Fanforce::Worker::Iron
4
-
5
- def initialize(opts={})
6
- @mq_client = IronMQ::Client.new(:token => opts[:token] || ENV['IRON_TOKEN'], :project_id => opts[:project_id] || ENV['IRON_PROJECT_ID'])
7
- end
8
-
9
- def enqueue(queue_id, payload)
10
- @mq_client.queue(queue_id).post(payload.to_json)
11
- end
12
-
13
- def client
14
- @mq_client
15
- end
16
-
17
- end
@@ -1,83 +0,0 @@
1
- class Fanforce::Worker
2
-
3
- def initialize(opts={})
4
- @opts = opts
5
- end
6
-
7
- def iron
8
- require_relative 'iron'
9
- @iron ||= Fanforce::Worker::Iron.new(@opts)
10
- end
11
-
12
- def enqueue(queue_id, payload)
13
- raise 'Payload being sent to the queue must be a Hash' if !payload.is_a?(Hash)
14
- iron.enqueue queue_id, params: payload, retries: 0
15
- end
16
-
17
- def retry_error(queue_id, msg_id)
18
- msg = iron.client.queue(queue_id + '-ERRORS').peek(msg_id)
19
- data = MultiJson.load(msg.body, :symbolize_keys => true)
20
- iron.enqueue queue_id, params: data[:params], retries: data[:retries] + 1
21
- msg.delete
22
- end
23
-
24
- ##########################################################################################
25
-
26
- def self.add_error(queue_id, payload)
27
- self.new.iron.enqueue("#{queue_id}-ERRORS", payload)
28
- end
29
-
30
- def self.enqueue(queue_id, payload)
31
- self.new.enqueue(queue_id, payload)
32
- end
33
-
34
- ##########################################################################################
35
-
36
- def self.run(worker_data, &code_block)
37
- require '.pluginenv'
38
- require 'iron_mq'
39
- require 'fanforce/api'
40
-
41
- run_validations
42
- run_worker IronMQ::Client.new.queue(worker_data['worker_id']).get(timeout: 3600), worker_data, &code_block
43
- end
44
-
45
- def self.run_validations
46
-
47
- end
48
-
49
- def run_worker(msg, worker_data, &code_block)
50
- puts '----------------------------------------------------------'
51
- print 'PROCESSING MESSAGE: '
52
- task_data = Fanforce.decode_json(msg.body)
53
-
54
- set_env_vars(worker_data['env_vars'])
55
- code_block.call(task_data[:params].clone, task_data[:retries])
56
- msg.delete
57
-
58
- rescue Exception => e
59
- if msg.nil?
60
- puts 'MESSAGE IS NIL'
61
- return
62
- end
63
- task_data[:last_error] = {
64
- exception: e.class.name,
65
- message: e.message,
66
- backtrace: e.backtrace,
67
- raised_at: Time.now
68
- }
69
- task_data[:last_error][:curl_command] = e.curl_command if e.respond_to?(:curl_command)
70
- task_data[:env_vars] = worker_data['env_vars']
71
-
72
- puts "ADDING TO ERROR QUEUE: #{task_data.to_json}"
73
- self.add_error worker_data['worker_id'], task_data
74
- msg.delete
75
- puts 'DELETED MESSAGE'
76
- end
77
-
78
- def set_env_vars(vars)
79
- vars.each {|k,v| ENV[k.to_s]=v }
80
- load 'fanforce/api/ff_globals.rb'
81
- end
82
-
83
- end