rails_workflow 0.3.9 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +2 -0
- data/app/concerns/rails_workflow/operation_status.rb +2 -0
- data/app/concerns/rails_workflow/operation_templates/assignments.rb +3 -1
- data/app/concerns/rails_workflow/operation_templates/dependencies.rb +18 -18
- data/app/concerns/rails_workflow/operations/assignments.rb +7 -5
- data/app/concerns/rails_workflow/operations/dependencies.rb +2 -0
- data/app/concerns/rails_workflow/status.rb +11 -15
- data/app/concerns/rails_workflow/user/assignment.rb +2 -0
- data/app/concerns/rails_workflow/uuid.rb +2 -0
- data/app/controllers/rails_workflow/application_controller.rb +2 -0
- data/app/controllers/rails_workflow/errors_controller.rb +2 -0
- data/app/controllers/rails_workflow/operation_templates_controller.rb +3 -1
- data/app/controllers/rails_workflow/operations_controller.rb +3 -1
- data/app/controllers/rails_workflow/process_templates_controller.rb +10 -8
- data/app/controllers/rails_workflow/processes_controller.rb +10 -8
- data/app/decorators/rails_workflow/context_decorator.rb +2 -0
- data/app/decorators/rails_workflow/decorator.rb +2 -0
- data/app/decorators/rails_workflow/operation_decorator.rb +2 -0
- data/app/decorators/rails_workflow/operation_helper_decorator.rb +2 -0
- data/app/decorators/rails_workflow/operation_template_decorator.rb +2 -0
- data/app/decorators/rails_workflow/paginating_decorator.rb +2 -0
- data/app/decorators/rails_workflow/process_decorator.rb +2 -0
- data/app/decorators/rails_workflow/process_template_decorator.rb +2 -0
- data/app/decorators/rails_workflow/status_decorator.rb +2 -0
- data/app/helpers/rails_workflow/application_helper.rb +2 -0
- data/app/jobs/rails_workflow/operation_execution_job.rb +11 -1
- data/app/models/rails_workflow/context.rb +3 -1
- data/app/models/rails_workflow/error.rb +23 -50
- data/app/models/rails_workflow/operation.rb +39 -3
- data/app/models/rails_workflow/operation_template.rb +2 -2
- data/app/models/rails_workflow/process.rb +34 -5
- data/app/models/rails_workflow/process_template.rb +12 -8
- data/app/models/rails_workflow/user_by_group_operation.rb +2 -0
- data/app/models/rails_workflow/user_by_role_operation.rb +2 -0
- data/app/models/rails_workflow/user_operation.rb +2 -0
- data/app/serializers/rails_workflow/operation_template_serializer.rb +2 -0
- data/app/serializers/rails_workflow/process_template_serializer.rb +2 -0
- data/app/services/rails_workflow/default_importer_preprocessor.rb +2 -0
- data/app/services/rails_workflow/process_importer.rb +2 -0
- data/app/views/rails_workflow/processes/index.html.slim +5 -5
- data/config/initializers/rails_workflow.rb +3 -3
- data/config/routes.rb +4 -2
- data/db/migrate/20150630174700_create_workflow_processes.rb +86 -84
- data/lib/generators/rails_workflow/install/install_generator.rb +2 -0
- data/lib/generators/rails_workflow/install/templates/create_workflow_processes.rb +86 -84
- data/lib/rails_workflow/config.rb +65 -24
- data/lib/rails_workflow/db/mysql.rb +3 -1
- data/lib/rails_workflow/db/pg.rb +3 -1
- data/lib/rails_workflow/dependency_resolver.rb +74 -0
- data/lib/rails_workflow/engine.rb +3 -1
- data/lib/rails_workflow/error_builder.rb +57 -0
- data/lib/rails_workflow/error_resolver.rb +72 -0
- data/lib/rails_workflow/operation_builder.rb +95 -0
- data/lib/rails_workflow/operation_runner.rb +113 -0
- data/lib/rails_workflow/process_builder.rb +57 -0
- data/lib/rails_workflow/process_manager.rb +66 -0
- data/lib/rails_workflow/process_runner.rb +72 -0
- data/lib/rails_workflow/version.rb +3 -1
- data/lib/rails_workflow.rb +2 -0
- data/lib/tasks/rails_workflow_tasks.rake +1 -0
- data/spec/concerns/status_spec.rb +25 -0
- data/spec/controllers/rails_workflow/operation_templates_controller_spec.rb +2 -0
- data/spec/controllers/rails_workflow/operations_controller_spec.rb +2 -0
- data/spec/controllers/rails_workflow/process_templates_controller_spec.rb +2 -0
- data/spec/controllers/rails_workflow/processes_controller_spec.rb +3 -1
- data/spec/dummy/Rakefile +2 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/controllers/leads_controller.rb +2 -0
- data/spec/dummy/app/controllers/sales_contacts_controller.rb +2 -0
- data/spec/dummy/app/decorators/lead_decorator.rb +2 -0
- data/spec/dummy/app/decorators/sales_contact_decorator.rb +2 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/helpers/leads_helper.rb +2 -0
- data/spec/dummy/app/helpers/sales_contacts_helper.rb +2 -0
- data/spec/dummy/app/models/bad_operation.rb +2 -0
- data/spec/dummy/app/models/bad_operation_template.rb +2 -0
- data/spec/dummy/app/models/lead.rb +2 -0
- data/spec/dummy/app/models/sales_contact.rb +2 -0
- data/spec/dummy/app/models/user.rb +2 -0
- data/spec/dummy/bin/bundle +2 -0
- data/spec/dummy/bin/rails +2 -0
- data/spec/dummy/bin/rake +2 -0
- data/spec/dummy/config/application.rb +2 -0
- data/spec/dummy/config/boot.rb +2 -0
- data/spec/dummy/config/database.yml.semaphore +2 -2
- data/spec/dummy/config/environment.rb +2 -0
- data/spec/dummy/config/environments/development.rb +2 -0
- data/spec/dummy/config/environments/production.rb +2 -0
- data/spec/dummy/config/environments/test.rb +2 -0
- data/spec/dummy/config/initializers/assets.rb +2 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +1 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +2 -0
- data/spec/dummy/config/initializers/devise.rb +2 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +2 -0
- data/spec/dummy/config/initializers/inflections.rb +1 -0
- data/spec/dummy/config/initializers/mime_types.rb +1 -0
- data/spec/dummy/config/initializers/session_store.rb +2 -0
- data/spec/dummy/config/initializers/workflow.rb +2 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/config.ru +2 -0
- data/spec/dummy/db/migrate/20150127171613_devise_create_users.rb +2 -0
- data/spec/dummy/db/migrate/20150130042852_create_sales_contacts.rb +2 -0
- data/spec/dummy/db/migrate/20150130043008_create_leads.rb +2 -0
- data/spec/dummy/log/development.log +110 -0
- data/spec/dummy/log/test.log +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7O/7O5OddMZvWFGpj71BCdc0vA55rhj4YPoL0XjBV4_OYk.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Cy/CyixQwp8QvorgpRadtYf6_zY35nZZp0JmrhkDN16XPM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/FW/FWR5Q7EP17cTcY35R1MscF6MX2HYiH5I2ZII89YLYxc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/HQ/HQuQO1k4kOyLSDXJEc8p-XR2agdkPF7mIFyh2noiNrU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/N4/N4e3G5QNTts2OVqkL0kxoP1xnAdDWnumpnH1m6WAsuY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rs/RsIG_ias53xeb4WHWRodcMcDmVyz1QvLQNy4gV2iBSo.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/WI/WI2XYMfwCaPWcjvvouKVltl9oKqKZL-BHePPLhC-rzw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Yc/YcbQRZWzddLfawePxNTEXcFFiS7asAyrujZzciT99l0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ai/aihcJWCIJGiHDpamul8bzy4jMsxnhewX6XWtkdsQ9dc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fR/fRVQN4mU7z3MVJD9u1LMq8idpOH8o2tFh_YouMYGAM8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gU/gUFNMb7SgxFyz5ZZcGfp-VYRVIw711HUeiWonMzYrcU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/h8/h86FNb4MxO5dq40P8KcCgGwZ_uqd8nn_O2fMWGDApW8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q7/q7cZDJXZFXTklMF8JAQSMr-MBxOKc7q1vZAPPR5RBf4.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/s9/s98GbJDqEe4PG3moRH6h-ukIZmQz9Frq4LO_Z9vCBLM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xX/xXCd205lXu7u_BuyBL0kfZwkBGJLvocHDItBfU6tMm4.cache +2 -0
- data/spec/factories/context.rb +2 -0
- data/spec/factories/operation_templates.rb +2 -0
- data/spec/factories/operations.rb +3 -1
- data/spec/factories/process_templates.rb +2 -0
- data/spec/factories/processes.rb +3 -1
- data/spec/factories/user.rb +2 -0
- data/spec/factories/workflow_errors.rb +2 -0
- data/spec/features/operations_spec.rb +2 -0
- data/spec/features/process_template_spec.rb +2 -0
- data/spec/lib/error_builder_spec.rb +137 -0
- data/spec/lib/error_resolver_spec.rb +182 -0
- data/spec/lib/operation_builder_spec.rb +69 -0
- data/spec/lib/process_builder_spec.rb +19 -0
- data/spec/{core/rails_workflow → lib}/process_manager_spec.rb +17 -27
- data/spec/models/rails_workflow/context_spec.rb +6 -3
- data/spec/models/rails_workflow/error_spec.rb +20 -147
- data/spec/models/rails_workflow/operation_spec.rb +64 -97
- data/spec/models/rails_workflow/operation_template_spec.rb +24 -11
- data/spec/models/rails_workflow/process_spec.rb +5 -2
- data/spec/models/rails_workflow/process_template_spec.rb +2 -36
- data/spec/rails_helper.rb +2 -0
- data/spec/serializers/process_template_serializer_spec.rb +2 -0
- data/spec/services/process_importer_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/controller_macros.rb +2 -0
- data/spec/support/pages/operations.rb +2 -0
- data/spec/support/rails_workflow/custom_operation.rb +2 -0
- data/spec/support/rails_workflow/custom_operation_template.rb +2 -0
- data/spec/{core → support}/rails_workflow/prepare_template.rb +3 -1
- data/spec/support/workflow_helper.rb +2 -0
- metadata +54 -28
- data/app/concerns/rails_workflow/operation_templates/default_builder.rb +0 -56
- data/app/concerns/rails_workflow/operations/default_runner.rb +0 -121
- data/app/concerns/rails_workflow/process_templates/default_builder.rb +0 -52
- data/app/concerns/rails_workflow/processes/default_runner.rb +0 -64
- data/app/concerns/rails_workflow/processes/dependency_resolver.rb +0 -54
- data/app/concerns/rails_workflow/reset_cache.rb +0 -13
- data/app/jobs/rails_workflow/operation_error_job.rb +0 -40
- data/app/managers/rails_workflow/process_manager.rb +0 -40
@@ -1,56 +0,0 @@
|
|
1
|
-
module RailsWorkflow
|
2
|
-
module OperationTemplates
|
3
|
-
module DefaultBuilder
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
def build_operation(operation)
|
7
|
-
# for customization
|
8
|
-
end
|
9
|
-
|
10
|
-
def build_operation!(process, completed_dependencies = [])
|
11
|
-
attrs = attributes
|
12
|
-
.with_indifferent_access
|
13
|
-
.slice(:title, :async, :is_background)
|
14
|
-
.merge(template: self,
|
15
|
-
process: process,
|
16
|
-
status: Operation::NOT_STARTED,
|
17
|
-
manager: process.manager)
|
18
|
-
|
19
|
-
attrs[:dependencies] = completed_dependencies.map do |dep|
|
20
|
-
{
|
21
|
-
operation_id: dep.id,
|
22
|
-
status: dep.status
|
23
|
-
}
|
24
|
-
end
|
25
|
-
|
26
|
-
operation = operation_class.create(attrs) do |op|
|
27
|
-
op.context = RailsWorkflow::OperationTemplate.build_context! op, completed_dependencies
|
28
|
-
|
29
|
-
build_operation op
|
30
|
-
end
|
31
|
-
|
32
|
-
if child_process.present?
|
33
|
-
operation.child_process = RailsWorkflow::ProcessManager
|
34
|
-
.build_process(
|
35
|
-
child_process.id,
|
36
|
-
operation.context.data
|
37
|
-
)
|
38
|
-
end
|
39
|
-
operation
|
40
|
-
end
|
41
|
-
|
42
|
-
module ClassMethods
|
43
|
-
def build_context(dependencies)
|
44
|
-
dependencies.first.try(:context).try(:data)
|
45
|
-
end
|
46
|
-
|
47
|
-
def build_context!(operation, dependencies)
|
48
|
-
RailsWorkflow::Context.new(
|
49
|
-
parent: operation,
|
50
|
-
data: build_context(dependencies) || operation.process.data
|
51
|
-
)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,121 +0,0 @@
|
|
1
|
-
module RailsWorkflow
|
2
|
-
module Operations
|
3
|
-
#
|
4
|
-
# = Workflow::Operations::DefaultRunner contains operation starting,
|
5
|
-
# completing etc logic.
|
6
|
-
#
|
7
|
-
module DefaultRunner
|
8
|
-
extend ActiveSupport::Concern
|
9
|
-
|
10
|
-
included do
|
11
|
-
# in this default operation runner we don't need to wait anything
|
12
|
-
# so we just can run operation. If you need to gather some other
|
13
|
-
# information - feel free to redefine operation start logic but
|
14
|
-
# try to gather all your custom logic in operation build method.
|
15
|
-
# operation start can be usefull if you need to send some notifications
|
16
|
-
# to external systems that operation is tarted etc...
|
17
|
-
def start
|
18
|
-
can_start? ? starting : waiting
|
19
|
-
rescue => exception
|
20
|
-
RailsWorkflow::Error.create_from exception, parent: self
|
21
|
-
end
|
22
|
-
|
23
|
-
def starting
|
24
|
-
update_attribute(:status, self.class::IN_PROGRESS)
|
25
|
-
|
26
|
-
is_background && RailsWorkflow.config.activejob_enabled ?
|
27
|
-
OperationExecutionJob.perform_later(id) :
|
28
|
-
OperationExecutionJob.perform_now(id)
|
29
|
-
end
|
30
|
-
|
31
|
-
# This method allows you to add requirements for operation to start. For example
|
32
|
-
# some operation can't start because of some process or overal system conditions.
|
33
|
-
# By default any operation can start :)
|
34
|
-
def can_start?
|
35
|
-
status == Operation::NOT_STARTED
|
36
|
-
end
|
37
|
-
|
38
|
-
# move operation to waiting status. for example - for user operations
|
39
|
-
def waiting
|
40
|
-
update_attribute(:status, self.class::WAITING)
|
41
|
-
start_waiting if respond_to? :start_waiting
|
42
|
-
rescue => exception
|
43
|
-
RailsWorkflow::Error.create_from exception, parent: self
|
44
|
-
end
|
45
|
-
|
46
|
-
def execute_in_transaction
|
47
|
-
status = nil
|
48
|
-
self.class.transaction(requires_new: true) do
|
49
|
-
begin
|
50
|
-
child_process.start if child_process.present?
|
51
|
-
status = execute
|
52
|
-
rescue ActiveRecord::Rollback
|
53
|
-
status = nil
|
54
|
-
end
|
55
|
-
|
56
|
-
raise ActiveRecord::Rollback unless status
|
57
|
-
end
|
58
|
-
|
59
|
-
if status
|
60
|
-
context.save
|
61
|
-
complete
|
62
|
-
end
|
63
|
-
|
64
|
-
rescue ActiveRecord::Rollback => exception
|
65
|
-
# In case of rollback exception we do nothing -
|
66
|
-
# this may be caused by usual validations
|
67
|
-
rescue => exception
|
68
|
-
RailsWorkflow::Error.create_from(
|
69
|
-
exception, parent: self,
|
70
|
-
target: self,
|
71
|
-
method: :execute_in_transaction
|
72
|
-
)
|
73
|
-
end
|
74
|
-
|
75
|
-
def execute
|
76
|
-
true
|
77
|
-
end
|
78
|
-
|
79
|
-
def completed?
|
80
|
-
completed_statuses.include? status
|
81
|
-
end
|
82
|
-
|
83
|
-
def can_complete?
|
84
|
-
child_process.present? ?
|
85
|
-
child_process.status == RailsWorkflow::Process::DONE :
|
86
|
-
true
|
87
|
-
end
|
88
|
-
|
89
|
-
def complete(to_status = nil)
|
90
|
-
if can_complete?
|
91
|
-
|
92
|
-
on_complete if to_status.blank? && respond_to?(:on_complete)
|
93
|
-
|
94
|
-
update_attributes(
|
95
|
-
status: to_status || self.class::DONE,
|
96
|
-
completed_at: Time.zone.now
|
97
|
-
)
|
98
|
-
manager.operation_completed self
|
99
|
-
end
|
100
|
-
rescue => exception
|
101
|
-
RailsWorkflow::Error.create_from(
|
102
|
-
exception, parent: self,
|
103
|
-
target: self,
|
104
|
-
method: :complete,
|
105
|
-
args: [to_status]
|
106
|
-
)
|
107
|
-
end
|
108
|
-
|
109
|
-
def cancel
|
110
|
-
on_cancel if respond_to? :on_cancel
|
111
|
-
complete self.class::CANCELED
|
112
|
-
end
|
113
|
-
|
114
|
-
def skip
|
115
|
-
on_cancel if respond_to? :on_skip
|
116
|
-
complete self.class::SKIPPED
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
module RailsWorkflow
|
3
|
-
module ProcessTemplates
|
4
|
-
# = DefaultBuilder
|
5
|
-
#
|
6
|
-
# Process Builder is used to build new process. All process building logic should be
|
7
|
-
# gathered here. It defines how process is build using template (for example it can used
|
8
|
-
# to gather some additional information from system - for example some information from
|
9
|
-
# existing processes or it can handle hierarchical processes logic for parent / child
|
10
|
-
# processes).
|
11
|
-
#
|
12
|
-
module DefaultBuilder
|
13
|
-
def build_process!(context)
|
14
|
-
process = process_class.create template: self
|
15
|
-
|
16
|
-
process.class.transaction do
|
17
|
-
process.update_attributes(title: title, status: Process::NOT_STARTED)
|
18
|
-
process.create_context(data: context, parent: process)
|
19
|
-
|
20
|
-
build_independent_operations process
|
21
|
-
process
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# Independent operations is template operations that have no dependencies from
|
26
|
-
# any other operations
|
27
|
-
def build_independent_operations(process)
|
28
|
-
independent_operations.each do |operation_template|
|
29
|
-
build_operation process, operation_template
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# Important note: operation template contains Operation Class.
|
34
|
-
# You can specify custom class on template
|
35
|
-
|
36
|
-
def build_operation(process, template, completed_dependencies = [])
|
37
|
-
operation = template.build_operation! process, completed_dependencies
|
38
|
-
|
39
|
-
process.operations << operation if operation.present?
|
40
|
-
|
41
|
-
operation
|
42
|
-
rescue => exception
|
43
|
-
RailsWorkflow::Error.create_from(
|
44
|
-
exception, parent: process,
|
45
|
-
target: process.template,
|
46
|
-
method: :build_operation,
|
47
|
-
args: [process, template, completed_dependencies]
|
48
|
-
)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module RailsWorkflow
|
2
|
-
module Processes
|
3
|
-
#= DefaultRunner
|
4
|
-
#
|
5
|
-
# This module contains logic of process start, stop, cancel etc.
|
6
|
-
#
|
7
|
-
module DefaultRunner
|
8
|
-
def can_start?
|
9
|
-
!operations.empty?
|
10
|
-
end
|
11
|
-
|
12
|
-
def start
|
13
|
-
if can_start?
|
14
|
-
update_attribute(:status, self.class::IN_PROGRESS)
|
15
|
-
operations.where(status: RailsWorkflow::Operation::NOT_STARTED).map(&:start)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def operation_exception
|
20
|
-
self.status = self.class::ERROR
|
21
|
-
end
|
22
|
-
|
23
|
-
# Process can be completed if all sync operations is complete.
|
24
|
-
|
25
|
-
def can_complete?
|
26
|
-
if incomplete_statuses.include? status
|
27
|
-
incompleted_operations.size.zero? &&
|
28
|
-
workflow_errors.unresolved.size.zero?
|
29
|
-
else
|
30
|
-
false
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Returns set or operation that not yet completed.
|
35
|
-
# Operation complete in DONE, SKIPPED, CANCELED, etc many other statuses
|
36
|
-
def incompleted_operations
|
37
|
-
operations.reject(&:completed?)
|
38
|
-
end
|
39
|
-
|
40
|
-
# If operation is completed process is responsible for building new operations.
|
41
|
-
# We need to calculate operations, depends on completed one and detect ones we
|
42
|
-
# can build.
|
43
|
-
def operation_complete(operation)
|
44
|
-
build_dependencies operation
|
45
|
-
end
|
46
|
-
|
47
|
-
def set_done_status
|
48
|
-
self.status = self.class::DONE
|
49
|
-
save
|
50
|
-
end
|
51
|
-
|
52
|
-
def complete_parent_operation
|
53
|
-
parent_operation.complete if parent_operation.present?
|
54
|
-
end
|
55
|
-
|
56
|
-
def complete
|
57
|
-
if can_complete?
|
58
|
-
set_done_status
|
59
|
-
complete_parent_operation
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
module RailsWorkflow
|
2
|
-
module Processes
|
3
|
-
# = DependencyResolver
|
4
|
-
#
|
5
|
-
# New operation can be added to process if all it's dependencies are satisfied.
|
6
|
-
# For example current operation can depend on some existing process operation which
|
7
|
-
# should be completed - then current operation can be build
|
8
|
-
|
9
|
-
module DependencyResolver
|
10
|
-
extend ActiveSupport::Concern
|
11
|
-
|
12
|
-
included do
|
13
|
-
# This methods get's operations that depends on given one.
|
14
|
-
# Operation::DependencyResolver resolves operation template dependencies
|
15
|
-
# but we can define dependencies not only by template but by some other
|
16
|
-
# business logic on process level. That is why I splitted operation
|
17
|
-
# dependencies on process and operation level
|
18
|
-
#
|
19
|
-
def build_dependencies(operation)
|
20
|
-
new_operations = []
|
21
|
-
|
22
|
-
matched_templates(operation).each do |operation_template|
|
23
|
-
completed_dependencies = [operation]
|
24
|
-
|
25
|
-
if operation_template.resolve_dependency operation
|
26
|
-
new_operations << operation_template.build_operation!(self, completed_dependencies)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
new_operations.each do |new_operation|
|
31
|
-
if incomplete_statuses.include?(status)
|
32
|
-
operations << new_operation
|
33
|
-
new_operation.start
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
rescue => exception
|
38
|
-
RailsWorkflow::Error.create_from(
|
39
|
-
exception, parent: self,
|
40
|
-
target: self,
|
41
|
-
method: :build_dependencies,
|
42
|
-
args: [operation]
|
43
|
-
)
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def matched_templates(operation)
|
49
|
-
template.dependent_operations(operation) - operations.map(&:template)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module RailsWorkflow
|
2
|
-
# When some operation fails due to some exceptions this job
|
3
|
-
# is responsible for setting operation to error status. Also it
|
4
|
-
# check if there is parent processes / operations and set it
|
5
|
-
# to error status.
|
6
|
-
class OperationErrorJob < ActiveJob::Base
|
7
|
-
queue_as :default
|
8
|
-
|
9
|
-
def perform(*args)
|
10
|
-
@target_id, @target_class = args
|
11
|
-
|
12
|
-
target.status = target.class::ERROR
|
13
|
-
target.save
|
14
|
-
|
15
|
-
process_parents
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
# Target is either operation or process
|
21
|
-
def target
|
22
|
-
@target ||= @target_class.constantize.find(@target_id)
|
23
|
-
end
|
24
|
-
|
25
|
-
# Target operation have parent process and target process may have
|
26
|
-
# parent operation and they should also be moved to ERROR status
|
27
|
-
def process_parents
|
28
|
-
parent_methods.each do |parent_method|
|
29
|
-
parent_target = target.public_send(parent_method)
|
30
|
-
perform(parent_target.id, parent_target.class.to_s) if parent_target
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Target operation respond to process, process respond to parent_operation
|
35
|
-
def parent_methods
|
36
|
-
[:parent_operation, :process]
|
37
|
-
.select { |method_name| target.respond_to?(method_name) }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module RailsWorkflow
|
2
|
-
# ProcessManager should be used to build and start processes.
|
3
|
-
# It is top level hierarchy class that also can be used
|
4
|
-
# to build enhancements. For example they can be used to implement
|
5
|
-
# processes communications.
|
6
|
-
class ProcessManager
|
7
|
-
attr_accessor :process
|
8
|
-
delegate :template, :operation_exception, to: :process
|
9
|
-
delegate :complete, to: :process, prefix: true
|
10
|
-
|
11
|
-
def initialize(process = nil)
|
12
|
-
@process = process
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.build_process(template_id, context)
|
16
|
-
RailsWorkflow.config.template(template_id).build_process!(context)
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.start_process(template_id, context)
|
20
|
-
process = build_process template_id, context
|
21
|
-
new(process).start_process
|
22
|
-
process
|
23
|
-
end
|
24
|
-
|
25
|
-
def start_process
|
26
|
-
process.start
|
27
|
-
rescue => exception
|
28
|
-
RailsWorkflow::Error.create_from exception, parent: process
|
29
|
-
end
|
30
|
-
|
31
|
-
def operation_completed(operation)
|
32
|
-
process.operation_complete operation
|
33
|
-
process_complete
|
34
|
-
end
|
35
|
-
|
36
|
-
def complete_process
|
37
|
-
process.complete
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|