-
Notifications
You must be signed in to change notification settings - Fork 3
/
basics.rb
134 lines (105 loc) · 3.18 KB
/
basics.rb
1
2
3
4
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
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
require 'active_support/concern'
module WorkerTools
module Basics
extend ActiveSupport::Concern
included do
attr_writer :model
def self.wrappers(*args)
@wrappers ||= args.flatten
end
def self.read_wrappers
@wrappers || []
end
end
def model_class
# Ex: Import
raise "model_class has to be defined in #{self}"
end
def model_kind
# Ex: 'sdom'
raise "model_kind has to be defined in #{self}"
end
def run
raise "run has to be defined in #{self}"
end
def perform(model_id = nil)
@model_id = model_id
default_reset
with_wrappers(wrapper_methods) do
send(run_method)
end
end
def wrapper_methods
self.class.read_wrappers.map do |wrapper|
symbolized_method = "with_wrapper_#{wrapper}".to_sym
raise "Missing wrapper #{wrapper}" unless respond_to?(symbolized_method)
symbolized_method
end
end
def with_wrapper_basics(&block)
custom_reset if respond_to?(:custom_reset, true)
block.yield
finalize
# this time we do want to catch Exception to attempt to handle some of the
# critical errors.
# rubocop:disable Lint/RescueException
rescue Exception => e
# rubocop:enable Lint/RescueException
save_state_without_validate('failed')
raise unless silent_error?(e)
end
def finalize
mark_with_warnings = model.notes.any? do |note|
complete_with_warnings_note_levels.include?(note.with_indifferent_access[:level].to_s)
end
model.update!(state: mark_with_warnings ? :complete_with_warnings : :complete)
end
def complete_with_warnings_note_levels
%w[error warning]
end
def model
@model ||= find_model
end
def with_wrappers(wrapper_symbols, &block)
return yield if wrapper_symbols.blank?
current_wrapper_symbol = wrapper_symbols.shift
send(current_wrapper_symbol) { with_wrappers(wrapper_symbols, &block) }
end
def silent_error?(error)
error.is_a?(WorkerTools::Errors::Silent)
# or add your list
# [WorkerTools::Errors::Silent, SomeOtherError].any? { |k| e.is_a?(k) }
end
private
def run_mode
model.try(:options).try(:[], 'run_mode').try(:to_sym)
end
def run_mode_option
model.try(:options).try(:[], 'run_mode_option').try(:to_sym)
end
def run_method
return :run unless run_mode.present?
method_name = "run_in_#{run_mode}_mode"
return method_name.to_sym if respond_to?(method_name, true)
return :run if run_mode == :repeat # common fallback
raise "Missing method #{method_name}"
end
def default_reset
model.attributes = { notes: [], meta: {}, state: 'running' }
model.save!(validate: false)
end
def save_state_without_validate(state)
model.state = state
model.save!(validate: false)
end
def find_model
@model_id ||= nil
return @model_id if @model_id.is_a?(model_class)
return model_class.find(@model_id) if @model_id
t = model_class.new
t.kind = model_kind if t.respond_to?(:kind=)
t.save!(validate: false)
t
end
end
end