forklift_etl 1.0.19 → 1.1.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 +8 -8
- data/Gemfile.lock +1 -1
- data/lib/forklift/plan.rb +19 -7
- data/lib/forklift/version.rb +1 -1
- data/readme.md +23 -0
- data/spec/unit/misc/error_spec.rb +33 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YjE2NGE4ZGQ0N2M3YWI2OTE4MDdkMGIzYTdhZTUzOWRmNzM0YzU3MQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
N2EzZTBmNDFhZjEyMTQ3MzZkNmZkMDU3NmU3NGY1MzUyYmY2YmU1MQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NTQyNzc0OGI0YzMyOGQyNzE4YmQ3MDBlMDEwMDk2ZjQ4ODFlMTI1MmU2M2Mx
|
10
|
+
MzJjZDg2NzA1Y2Y1NDVmOWU0NTAzNDhkNmRhMGFjNGY2ZmE0MGYyYzJmNzBh
|
11
|
+
MGU5NmE3NmYyMTE2MzRjMTc2MzIwZjYwZTE3MWViOTE5ZmRlMDc=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
N2EwNjZiM2JlNzQzOTFlNGUzM2I5YWEwM2Y0ZGRlMjUyZTZhZTlkZWQ3MTJh
|
14
|
+
NzA3YTE5ZDgzMTkxMzFjZjZiMWYyYzMzZTEzZjVlMDg0NTlhYWUyNDBlODJm
|
15
|
+
Njk2ZGJmOTIwOTgyOWFkNTRkMTFkYjZhMjFkZDMzODZhOGJhOWQ=
|
data/Gemfile.lock
CHANGED
data/lib/forklift/plan.rb
CHANGED
@@ -37,17 +37,25 @@ module Forklift
|
|
37
37
|
logger.debug "loaded a #{type.camelcase} connection from #{f}"
|
38
38
|
rescue Exception => e
|
39
39
|
logger.fatal "cannot create a class type of #{loader} from #{f} | #{e}"
|
40
|
-
raise e
|
40
|
+
# raise e ## Don't raise here, but let a step fail so the error_handler can report
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
|
46
|
+
def default_error_handler
|
47
|
+
return lambda {|name, e| raise e }
|
48
|
+
end
|
49
|
+
|
45
50
|
def step(*args, &block)
|
46
|
-
name
|
51
|
+
name = args[0].to_sym
|
52
|
+
error_handler = default_error_handler
|
53
|
+
error_handler = args[1] unless args[1].nil?
|
47
54
|
self.steps[name] = {
|
48
|
-
:ran
|
49
|
-
:to_run
|
50
|
-
:block
|
55
|
+
:ran => false,
|
56
|
+
:to_run => false,
|
57
|
+
:block => block,
|
58
|
+
:error_handler => error_handler,
|
51
59
|
}
|
52
60
|
end
|
53
61
|
|
@@ -63,8 +71,12 @@ module Forklift
|
|
63
71
|
self.logger.log "skipping step `#{name}`"
|
64
72
|
else
|
65
73
|
self.logger.log "*** step: #{name} ***"
|
66
|
-
|
67
|
-
|
74
|
+
begin
|
75
|
+
step[:block].call
|
76
|
+
step[:ran] = true
|
77
|
+
rescue Exception => e
|
78
|
+
step[:error_handler].call(name, e)
|
79
|
+
end
|
68
80
|
end
|
69
81
|
end
|
70
82
|
end
|
data/lib/forklift/version.rb
CHANGED
data/readme.md
CHANGED
@@ -265,6 +265,29 @@ end
|
|
265
265
|
|
266
266
|
When you use steps, you can run your whole plan, or just part if it with command line arguments. For example, `forklift plan.rb "Elasticsearch Import"` would just run that single portion of the plan. Note that any parts of your plan not within a step will be run each time.
|
267
267
|
|
268
|
+
### Error Handling
|
269
|
+
|
270
|
+
By default, exceptions within your plan will raise and crash your application. However, you can pass an optional `error_handler` lambda to your step about how to handle the error. the `error_handler` will be passed (`step_name`,`exception`). If you don't re-raise within your error handler, your plan will continue to excecute. For example:
|
271
|
+
|
272
|
+
```ruby
|
273
|
+
|
274
|
+
error_handler = lambda { |name, exception|
|
275
|
+
if exception.class =~ /connection/
|
276
|
+
# I can't connect, I should halt
|
277
|
+
raise e
|
278
|
+
elsif exception.class =~ /SoftError/
|
279
|
+
# this type of error is OK
|
280
|
+
else
|
281
|
+
raise e
|
282
|
+
end
|
283
|
+
}
|
284
|
+
|
285
|
+
plan.step('a_complex_step', error_handler){
|
286
|
+
# ...
|
287
|
+
}
|
288
|
+
|
289
|
+
```
|
290
|
+
|
268
291
|
## Transports
|
269
292
|
|
270
293
|
Transports are how you interact with your data. Every transport defines `read` and `write` methods which handle arrays of data objects (and the helper methods required).
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'misc forklift core' do
|
4
|
+
describe 'error handling' do
|
5
|
+
|
6
|
+
it "un-caught errors will raise" do
|
7
|
+
plan = SpecPlan.new
|
8
|
+
expect{
|
9
|
+
plan.do! {
|
10
|
+
plan.step("step_a"){ raise 'BREAK' }
|
11
|
+
}
|
12
|
+
}.to raise_error 'BREAK'
|
13
|
+
plan.pid.delete!
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'can make error handlers' do
|
17
|
+
plan = SpecPlan.new
|
18
|
+
name = ''
|
19
|
+
ex = ''
|
20
|
+
error_handler = lambda{ |n, e|
|
21
|
+
ex = e
|
22
|
+
name = n
|
23
|
+
}
|
24
|
+
plan.do! {
|
25
|
+
plan.step("step_a", error_handler){ raise 'BREAK' }
|
26
|
+
}
|
27
|
+
|
28
|
+
expect(name).to eql :step_a
|
29
|
+
expect(ex.to_s).to eql 'BREAK'
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forklift_etl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Tahler
|
@@ -179,6 +179,7 @@ files:
|
|
179
179
|
- spec/template/spec_email_template.erb
|
180
180
|
- spec/unit/connection/mysql_spec.rb
|
181
181
|
- spec/unit/misc/email_spec.rb
|
182
|
+
- spec/unit/misc/error_spec.rb
|
182
183
|
- spec/unit/misc/pid_spec.rb
|
183
184
|
- spec/unit/misc/step_spec.rb
|
184
185
|
- template/destination.yml
|
@@ -237,6 +238,7 @@ test_files:
|
|
237
238
|
- spec/template/spec_email_template.erb
|
238
239
|
- spec/unit/connection/mysql_spec.rb
|
239
240
|
- spec/unit/misc/email_spec.rb
|
241
|
+
- spec/unit/misc/error_spec.rb
|
240
242
|
- spec/unit/misc/pid_spec.rb
|
241
243
|
- spec/unit/misc/step_spec.rb
|
242
244
|
has_rdoc:
|