workflow_core 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e37fe908ba22a89b01f43680721ad466544bb1eef47cc8bc95ea26d7a77c00d
4
- data.tar.gz: 1a052885996e219ec88a60d1e890e7b7b49b855b30bef3b073d1b3a98cc19167
3
+ metadata.gz: 811e973c52672a22910d4cbd3cea630788de539f951d0ed5b83185e7bf7b8dc6
4
+ data.tar.gz: 8cac78ded90082dbf6a66c77fb4d2969b3a30846192f27c20d15ae0bae86670a
5
5
  SHA512:
6
- metadata.gz: ad2e77a5043dcbd124a489ef4e0cb047fe3ef15de5db8d23eab6aea2c0f331299cefedb19f9100378db82555cc094ec535ad7d86383b4d50dcb21e5f7b6baada
7
- data.tar.gz: af92427c841e043165b8ad2c7179f83bb1edd4906ebef9adcd54eddaedbde9669b695f8ecfbe486399b846b03b2da5898360ff6be6b82c290e8a0caa23a86ce7
6
+ metadata.gz: 316fef5691389a031987ec16a194d242d5b961511ec20dac720841e07eff364958d210072dd61b6abbec87daa7337e27359450ccbb27e4a2cb09e219dd39ba17
7
+ data.tar.gz: 0adeeeba9b7c7a80aa2b11ac73cc1b28c559ad88f5f47f6a987acfa800eac77bd3842e4753a10eb4be3789db5f449edd0e858db72396b6b264298232dec41a11
data/README.md CHANGED
@@ -9,13 +9,40 @@ Workflow Core
9
9
 
10
10
  A Rails engine which providing essential infrastructure of workflow.
11
11
 
12
- It's based on [Workflow Net](http://mlwiki.org/index.php/Workflow_Nets) technique.
12
+ WorkflowCore is originally designed for Business Process Management (BPM), in this scenario:
13
13
 
14
- The gem provides:
14
+ - Workflows are usually defined by users dynamically
15
+ - Task may tight with application features
16
+ - May meet some special or weird requirements
15
17
 
16
- - Models to describe workflow nets
17
- - Models to describe workflow instances
18
- - Interfaces to define transitions
18
+ WorkflowCore is based on [Workflow Net](http://mlwiki.org/index.php/Workflow_Nets) technique, and only providing essential features for a workflow engine.
19
+
20
+ ## Features
21
+
22
+ ### Models to describe workflow net
23
+
24
+ Workflow Net is a special case of [Petri net](http://mlwiki.org/index.php/Petri_Nets)
25
+
26
+ ![](_assets/workflow_net.png)
27
+
28
+ There are two kinds of nodes
29
+
30
+ - Place (circles): represent the states of a system
31
+ - Transition (squares): represent state changes
32
+
33
+ WorkflowCore provides Place & Transition models that can represent a workflow net, and a Workflow model as root.
34
+
35
+ ### Models to describe workflow instances
36
+
37
+ Workflow net use Token (dots in places) to tracking states of a process, every place can contain one or more tokens.
38
+
39
+ WorkflowCore provides WorkflowInstance model represent processes, and it has many tokens.
40
+
41
+ ### Interfaces to define how to transit
42
+
43
+ Transition has a transactional `fire` method which accept a token that would consume it and generate new token(s), developer could create many kinds of transitions and overrides `on_fire` to define how to transit
44
+
45
+ In addition, `on_error` is used for error handling.
19
46
 
20
47
  ## Why “core”
21
48
 
@@ -27,11 +54,11 @@ BTW, the dummy app is a full-featured app with production level codebase that yo
27
54
 
28
55
  ## Todo
29
56
 
30
- - Make sure transit must be an atomic operation, and help developers to avoiding Rails' nested transaction pitfalls.
31
- - Consider consequences of changing the Net, well handle Net changes. e.g: what about running instances?
57
+ - Find a good way to validate all nodes of the net, when? where? how?
58
+ - Consider native workflows (those which defined in code and tight with the app) support
32
59
  - Stabilizing interfaces.
33
60
  - Evaluate that can supporting async, scheduled and event-based transition properly.
34
- - Efficiency (especially on database).
61
+ - Efficiency (especially database queries).
35
62
  - Easy to use.
36
63
  - Transforming to graph representation for visualization and other usages (e.g proving [Soundness](http://mlwiki.org/index.php/Workflow_Soundness)).
37
64
  - Polish codebase.
@@ -86,41 +113,7 @@ The dummy app integrates with [Form Core](https://github.com/rails-engine/form_c
86
113
 
87
114
  ![](_assets/dummy_overview.png)
88
115
 
89
- ### Features
90
-
91
- #### Importing workflow definitions from a BPMN2 xml,
92
-
93
- ![](_assets/importing_bpmn.png)
94
-
95
- Because there isn't have a easy-to-use web-based flowchart designer, I implement a stupid BPMN2 importer, it have many restrictions:
96
-
97
- - Only supports `Sequence`, `Start event`, `End event`, `Parallel gateway` and `Exclusive gateway`
98
- - Using gateway to fork flows must have corresponding join (or merge) gateway
99
- - Only read `name` property, other such as `condition expression` must configure on the dummy app
100
-
101
- You can check `_samples` folder, or you can try a BPMN2 designer (e.g [Camunda modeler](https://github.com/camunda/camunda-modeler)).
102
-
103
- #### Defining form
104
-
105
- ![](_assets/defining_form.png)
106
-
107
- You can defining a dynamic form for a workflow.
108
-
109
- In transition's options, you can configure field's accessibility
110
-
111
- #### Exclusive choice configuration supports Ruby expression
112
-
113
- ![](_assets/editing_transition.png)
114
-
115
- Exclusive choice is a special transition that needs to configure conditions that determine how to transit to a branch.
116
-
117
- The condition is a Ruby expression, and running in a mRuby sandbox (powered by ScriptCore but it's also undone yet), and you can access form data through `@input[:payload]`, for example, there is a field named `approved`, we can check the field checked by `@input[:payload]["approved"]`
118
-
119
- #### Run a workflow
120
-
121
- That should make sense.
122
-
123
- ### Usage
116
+ **You need to install Graphviz first**
124
117
 
125
118
  Clone the repository.
126
119
 
@@ -140,6 +133,13 @@ Run bundler
140
133
  $ bundle install
141
134
  ```
142
135
 
136
+ Build mruby engine & engine lib
137
+
138
+ ```sh
139
+ $ bin/rails app:script_core:engine:build
140
+ $ bin/rails app:script_core:engine:compile_lib
141
+ ```
142
+
143
143
  Preparing database
144
144
 
145
145
  ```sh
@@ -154,6 +154,42 @@ $ bin/rails s
154
154
 
155
155
  Open your browser, and visit `http://localhost:3000`
156
156
 
157
+ ### Features
158
+
159
+ #### Importing workflow definitions from a BPMN2 xml,
160
+
161
+ ![](_assets/importing_bpmn.png)
162
+
163
+ Because there isn't have a easy-to-use web-based flowchart designer, I implement a stupid BPMN2 importer, it have many restrictions:
164
+
165
+ - Only supports `Sequence`, `Start event`, `End event`, `Parallel gateway` and `Exclusive gateway`
166
+ - Using gateway to fork flows must have corresponding join (or merge) gateway
167
+ - Only read `name` property, other such as `condition expression` must configure on the dummy app
168
+
169
+ You can check `_samples` folder, I've already provided some samples, or you can try a BPMN2 designer (e.g [Camunda modeler](https://github.com/camunda/camunda-modeler)).
170
+
171
+ #### Defining form
172
+
173
+ ![](_assets/defining_form.png)
174
+
175
+ You can defining a dynamic form for a workflow.
176
+
177
+ In transition's options, you can configure field's accessibility
178
+
179
+ #### Exclusive choice configuration supports Ruby expression
180
+
181
+ ![](_assets/editing_transition.png)
182
+
183
+ Exclusive choice is a special transition that needs to configure conditions that determine how to transit to a branch.
184
+
185
+ The condition is a Ruby expression, and running in a mRuby sandbox (powered by [ScriptCore](https://github.com/rails-engine/script_core)),
186
+ and you can access form data through `Input`, for example, there is a field named `approved`,
187
+ we can check the field checked by `Input["approved"]`
188
+
189
+ #### Run a workflow
190
+
191
+ See `Instance` tab, that should make sense.
192
+
157
193
  ## Contributing
158
194
 
159
195
  Bug report or pull request are welcome.
@@ -2,14 +2,16 @@
2
2
 
3
3
  module WorkflowCore
4
4
  class Place < ApplicationRecord
5
+ include WorkflowCore::Concerns::Models::Place
6
+
5
7
  self.table_name = "workflow_places"
6
8
 
7
9
  belongs_to :workflow
8
10
 
9
11
  belongs_to :input_transition, optional: true, foreign_key: "input_transition_id",
10
- class_name: "WorkflowCore::Transition"
12
+ class_name: "WorkflowCore::Transition"
11
13
  belongs_to :output_transition, optional: true, foreign_key: "output_transition_id",
12
- class_name: "WorkflowCore::Transition"
14
+ class_name: "WorkflowCore::Transition"
13
15
 
14
16
  has_many :tokens
15
17
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module WorkflowCore
4
4
  class Token < ApplicationRecord
5
+ include WorkflowCore::Concerns::Models::Token
6
+
5
7
  self.table_name = "workflow_tokens"
6
8
 
7
9
  belongs_to :instance,
@@ -10,7 +12,7 @@ module WorkflowCore
10
12
 
11
13
  belongs_to :place
12
14
  belongs_to :previous, optional: true,
13
- class_name: "WorkflowCore::Token"
15
+ class_name: "WorkflowCore::Token"
14
16
 
15
17
  enum status: {
16
18
  processing: 0,
@@ -2,17 +2,15 @@
2
2
 
3
3
  module WorkflowCore
4
4
  class Transition < ApplicationRecord
5
+ include WorkflowCore::Concerns::Models::Transition
6
+
5
7
  self.table_name = "workflow_transitions"
6
8
 
7
9
  belongs_to :workflow
8
10
 
9
11
  has_many :input_places, dependent: :nullify,
10
- foreign_key: "output_transition_id", class_name: "WorkflowCore::Place"
12
+ foreign_key: "output_transition_id", class_name: "WorkflowCore::Place"
11
13
  has_many :output_places, dependent: :destroy,
12
- foreign_key: "input_transition_id", class_name: "WorkflowCore::Place"
13
-
14
- def fire(_token)
15
- raise NotImplementedError
16
- end
14
+ foreign_key: "input_transition_id", class_name: "WorkflowCore::Place"
17
15
  end
18
16
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module WorkflowCore
4
4
  class Workflow < ApplicationRecord
5
+ include WorkflowCore::Concerns::Models::Workflow
6
+
5
7
  self.table_name = "workflows"
6
8
 
7
9
  has_one :start_place, class_name: "WorkflowCore::Place", dependent: :destroy
@@ -2,6 +2,8 @@
2
2
 
3
3
  module WorkflowCore
4
4
  class WorkflowInstance < ApplicationRecord
5
+ include WorkflowCore::Concerns::Models::WorkflowInstance
6
+
5
7
  self.table_name = "workflow_instances"
6
8
 
7
9
  belongs_to :workflow
@@ -3,8 +3,8 @@
3
3
  class CreateWorkflowPlaces < ActiveRecord::Migration[5.2]
4
4
  def change
5
5
  create_table :workflow_places do |t|
6
- t.references :input_transition, foreign_key: {to_table: "workflow_transitions"}
7
- t.references :output_transition, foreign_key: {to_table: "workflow_transitions"}
6
+ t.references :input_transition, foreign_key: { to_table: "workflow_transitions" }
7
+ t.references :output_transition, foreign_key: { to_table: "workflow_transitions" }
8
8
 
9
9
  t.string :type, null: false
10
10
  t.references :workflow, foreign_key: true
@@ -5,10 +5,10 @@ class CreateWorkflowTokens < ActiveRecord::Migration[5.2]
5
5
  create_table :workflow_tokens do |t|
6
6
  t.integer :status, null: false, default: 0
7
7
 
8
- t.references :place, foreign_key: {to_table: "workflow_places"}
9
- t.references :previous, foreign_key: {to_table: "workflow_tokens"}
8
+ t.references :place, foreign_key: { to_table: "workflow_places" }
9
+ t.references :previous, foreign_key: { to_table: "workflow_tokens" }
10
10
 
11
- t.references :instance, foreign_key: {to_table: "workflow_instances"}
11
+ t.references :instance, foreign_key: { to_table: "workflow_instances" }
12
12
  t.references :workflow, foreign_key: true
13
13
  t.timestamps
14
14
  end
@@ -2,6 +2,11 @@
2
2
 
3
3
  require "workflow_core/engine"
4
4
 
5
+ require "workflow_core/concerns/models/workflow"
6
+ require "workflow_core/concerns/models/transition"
7
+ require "workflow_core/concerns/models/place"
8
+ require "workflow_core/concerns/models/workflow_instance"
9
+ require "workflow_core/concerns/models/token"
10
+
5
11
  module WorkflowCore
6
- # Your code goes here...
7
12
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkflowCore::Concerns
4
+ module Models
5
+ module Place
6
+ extend ActiveSupport::Concern
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkflowCore::Concerns
4
+ module Models
5
+ module Token
6
+ extend ActiveSupport::Concern
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkflowCore::Concerns
4
+ module Models
5
+ module Transition
6
+ extend ActiveSupport::Concern
7
+
8
+ def fire(token, transaction_options: { requires_new: true }, **options)
9
+ transaction(**transaction_options) do
10
+ on_fire(token, transaction_options, options)
11
+ end
12
+ rescue StandardError => e
13
+ rescue_fire_error e
14
+ end
15
+
16
+ protected
17
+
18
+ def on_fire(_token, _transaction_options, **_options)
19
+ raise NotImplementedError
20
+ end
21
+
22
+ def rescue_fire_error(ex)
23
+ raise ex
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkflowCore::Concerns
4
+ module Models
5
+ module Workflow
6
+ extend ActiveSupport::Concern
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkflowCore::Concerns
4
+ module Models
5
+ module WorkflowInstance
6
+ extend ActiveSupport::Concern
7
+ end
8
+ end
9
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WorkflowCore
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workflow_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - jasl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-26 00:00:00.000000000 Z
11
+ date: 2019-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.2'
19
+ version: 6.0.0.rc1
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 7.0.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 6.0.0.rc1
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: '5.2'
32
+ version: 7.0.0
27
33
  description: A Rails engine which providing essential infrastructure of workflow.
28
34
  It's based on Workflow Nets.
29
35
  email:
@@ -49,6 +55,11 @@ files:
49
55
  - db/migrate/20180912223722_create_workflow_tokens.rb
50
56
  - lib/tasks/workflow_core_tasks.rake
51
57
  - lib/workflow_core.rb
58
+ - lib/workflow_core/concerns/models/place.rb
59
+ - lib/workflow_core/concerns/models/token.rb
60
+ - lib/workflow_core/concerns/models/transition.rb
61
+ - lib/workflow_core/concerns/models/workflow.rb
62
+ - lib/workflow_core/concerns/models/workflow_instance.rb
52
63
  - lib/workflow_core/engine.rb
53
64
  - lib/workflow_core/version.rb
54
65
  homepage: https://github.com/rails-engine/workflow_core
@@ -70,8 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
81
  - !ruby/object:Gem::Version
71
82
  version: '0'
72
83
  requirements: []
73
- rubyforge_project:
74
- rubygems_version: 2.7.7
84
+ rubygems_version: 3.0.4
75
85
  signing_key:
76
86
  specification_version: 4
77
87
  summary: A Rails engine which providing essential infrastructure of workflow. It's