fanforce-worker 0.5.0 → 0.10.0

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.
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