rails_workflow 0.3.9 → 0.4.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 +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
|