brace_comb 0.0.3 → 0.1.1
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/README.md +48 -25
- data/lib/brace_comb/dependency_helper.rb +12 -10
- data/lib/brace_comb/dependency_model.rb +2 -2
- data/lib/brace_comb/version.rb +1 -1
- data/lib/generators/brace_comb/migration_generator.rb +2 -2
- data/lib/generators/brace_comb/templates/add_associations.rb.erb +1 -1
- data/spec/brace_comb/dependency_helper_spec.rb +5 -5
- data/spec/brace_comb/dependency_model_spec.rb +5 -5
- data/spec/generators/brace_comb/migration_generator_spec.rb +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bfd2a6dfe32328fd413215449ec8880f0a50cba
|
4
|
+
data.tar.gz: d3d8f3995d6695d34cfec43ac0e1fbfd2109d65c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f4d959428312946a06ec5fc78da49a1b30b9ec9d3e08de0bf81c481e310caf64cec80db870dab19a4c1f1732cc1a761576d0e163107603f91991890764a0074
|
7
|
+
data.tar.gz: ce0b8b59c727609cafe7244d29e6e7020af6cbdda06a258767651f9dc5c1ba571381c23ddacc85ff5be2dc27c2de71682484e3877148b46edbf06fd73d0cf353
|
data/README.md
CHANGED
@@ -2,15 +2,36 @@
|
|
2
2
|
|
3
3
|
Brace Comb is a small bit of wax built between two combs or frames to fasten them together. Brace comb is also built between a comb and adjacent wood, or between two wooden parts such as top bars.
|
4
4
|
|
5
|
-
|
5
|
+
This is akin to how workflows are connected to each other with dependencies.
|
6
6
|
|
7
|
-
##
|
7
|
+
## Description
|
8
8
|
|
9
|
-
In workflow management systems, there is often a need to define that certain tasks should only begin when another task(s) is complete.
|
9
|
+
In workflow management systems, there is often a need to define that certain tasks should only begin when another task(s) is complete. BraceComb can be used to define multiple types of workflows and handle each workflow consistently.
|
10
10
|
|
11
|
-
|
11
|
+
## Example
|
12
|
+
A factory production line sytem uses pre-defined workflows with strict dependencies between tasks. In a simplified scenario, let's say we need to define a workflow in which an item on the conveyor belt must be packed before it is dispatched. In this case:
|
12
13
|
|
13
|
-
|
14
|
+
- Dependents/Tasks are the actions such as packing and dispatching
|
15
|
+
- Dependencies are links that define that packing must finish before dispatching
|
16
|
+
|
17
|
+
In this system we can create a dependent entity called `entity1` for `packing` and another dependent entity called `entity2` for `dispatching`. A new dependency between the two entities can be created using the following command:
|
18
|
+
|
19
|
+
```
|
20
|
+
initialize_dependency! from: entity1.id, to: entity2.id, type: 'dispatch'
|
21
|
+
```
|
22
|
+
|
23
|
+
This will create a dependency in `pending` state. In this case `packing` is a strict prerequisite for `dispatching`, hence `entity2` should not start unless the dependency is in `resolved` state. This is also the case for any dependencies of type `dispatch`. This can be defined by declaring a dependency characteristics using:
|
24
|
+
|
25
|
+
```
|
26
|
+
declare_dependency type: :dispatch,
|
27
|
+
resolver: :send_packing_complete_confirmation,
|
28
|
+
before_resolution: [:check_packing_complete?, :check_dispatcher_available?],
|
29
|
+
after_resolution: [:send_dispatch_notification]
|
30
|
+
```
|
31
|
+
|
32
|
+
This declaration will ensure that for all dependencies of type `dispatch`, all `before_resolution` hooks are first run. If any `before_resolution` functions returns false, then the operation is aborted. If all `before_resolution` functions return true, then the resolver code inside `send_packing_complete_confirmation` will be executed, and then all functions inside `after_resolution` would be executed.
|
33
|
+
|
34
|
+
To kick-off this flow just call `dependency.resolve` and the before and after hooks will be invoked in the manner as described above.
|
14
35
|
|
15
36
|
## Installation
|
16
37
|
|
@@ -18,21 +39,23 @@ In addition, it accepts methods/procs to define the logic for dependency resolut
|
|
18
39
|
|
19
40
|
`gem 'brace_comb'`
|
20
41
|
|
21
|
-
2. Create an initializer for `brace_comb`
|
42
|
+
2. Create an initializer for `brace_comb`
|
22
43
|
|
23
44
|
a. `bundle exec rails generate brace_comb:initializer`
|
24
|
-
|
45
|
+
|
25
46
|
b. Modify the name of dependency and dependent tables in the initializer `config/initializers/brace_comb.rb`
|
26
|
-
|
47
|
+
|
27
48
|
c. Run `bundle exec rails generate brace_comb:migration` to create the migration
|
28
|
-
|
49
|
+
|
29
50
|
d. Create the dependency tables and associations using `bundle exec rake db:migrate`
|
30
|
-
|
51
|
+
|
31
52
|
e. Generate the basic dependency model by running:
|
32
53
|
```bundle exec rails generate brace_comb:model ''```
|
33
54
|
|
34
55
|
## Usage
|
35
|
-
|
56
|
+
|
57
|
+
Entity names for dependencies and dependents are configurable and can be set in `config/initializers/brace_comb.rb` before creating the migrations.
|
58
|
+
|
36
59
|
1. Declare a dependency type by adding in the following to the dependency class:
|
37
60
|
```
|
38
61
|
include BraceComb::Helper
|
@@ -44,39 +67,39 @@ In addition, it accepts methods/procs to define the logic for dependency resolut
|
|
44
67
|
```
|
45
68
|
declare_dependency type: :shopping,
|
46
69
|
resolver: :shopping_complete
|
47
|
-
|
48
|
-
|
70
|
+
before_resolution: [:completed_status?],
|
71
|
+
after_resolution: [:complete_job]
|
49
72
|
```
|
50
|
-
|
51
|
-
or
|
52
|
-
|
73
|
+
|
74
|
+
or
|
75
|
+
|
53
76
|
b. Using a proc in the resolver
|
54
|
-
|
77
|
+
|
55
78
|
```
|
56
79
|
declare_dependency type: :shopping,
|
57
80
|
resolver: ->(data) { data.condition },
|
58
|
-
|
59
|
-
|
81
|
+
before_resolution: [:completed_status?],
|
82
|
+
after_resolution: [:complete_job]
|
60
83
|
```
|
61
84
|
3. Create dependencies between the dependent class by using the following helper in any instance method of a model class:
|
62
85
|
|
63
86
|
- When an exception needs to be raised:
|
64
|
-
`initialize_dependency! from:
|
87
|
+
`initialize_dependency! from: entity1.id, to: entity2.id, type: 'shopping'`
|
65
88
|
|
66
89
|
or
|
67
90
|
- When a boolean needs to be returned:
|
68
|
-
`initialize_dependency from:
|
91
|
+
`initialize_dependency from: entity1.id, to: entity2.id, type: 'shopping'`
|
69
92
|
|
70
93
|
5. Resolve dependencies from any active record model by using:
|
71
|
-
|
94
|
+
|
72
95
|
- When an exception needs to be raised:
|
73
96
|
```
|
74
97
|
dependency.resolve!(identifier: 123, status: :resolved)
|
75
98
|
```
|
76
|
-
|
99
|
+
|
77
100
|
or
|
78
|
-
- When a boolean needs to be returned:
|
79
|
-
|
101
|
+
- When a boolean needs to be returned:
|
102
|
+
|
80
103
|
```
|
81
104
|
dependency.resolve(identifier: 123, status: :resolved)
|
82
105
|
```
|
@@ -4,23 +4,23 @@ module BraceComb
|
|
4
4
|
# declare_dependency
|
5
5
|
# type: :shopping
|
6
6
|
# resolver: :shopping_completed
|
7
|
-
#
|
8
|
-
#
|
7
|
+
# before_resolution: [:completed_status?]
|
8
|
+
# after_resolution: :complete_job, Proc.new {}
|
9
9
|
# Options:
|
10
10
|
# resolver: Methods or procs that can mark the dependency as resolved
|
11
|
-
#
|
11
|
+
# before_resolution: Checks that can be performed before a dependency is resolved.
|
12
12
|
# If any of these return false then the dependency resolution will result in a false
|
13
13
|
# or exception.
|
14
|
-
#
|
15
|
-
# executed one by one. All the subsequent
|
16
|
-
# of the predecessor
|
14
|
+
# after_resolution: if the dependency resolution succeeds, each of these methods will be
|
15
|
+
# executed one by one. All the subsequent after_resolution hooks will not be executed if any
|
16
|
+
# of the predecessor after_resolution hook throws an exception. However, this will not make
|
17
17
|
# a difference to the resolution status of the dependency itself
|
18
18
|
def declare_dependency(options = {})
|
19
19
|
dependency_mapping = dependency_mapping_value
|
20
20
|
dependency_mapping[options[:type]] = options.slice(
|
21
21
|
:resolver,
|
22
|
-
:
|
23
|
-
:
|
22
|
+
:before_resolution,
|
23
|
+
:after_resolution
|
24
24
|
)
|
25
25
|
set_dependency_mapping(dependency_mapping)
|
26
26
|
end
|
@@ -51,7 +51,8 @@ module BraceComb
|
|
51
51
|
dependency_model.create(
|
52
52
|
source_id: from,
|
53
53
|
destination_id: to,
|
54
|
-
dependency_type: dependency_type
|
54
|
+
dependency_type: dependency_type,
|
55
|
+
status: :pending
|
55
56
|
)
|
56
57
|
end
|
57
58
|
|
@@ -60,7 +61,8 @@ module BraceComb
|
|
60
61
|
dependency_model.create!(
|
61
62
|
source_id: from,
|
62
63
|
destination_id: to,
|
63
|
-
dependency_type: dependency_type
|
64
|
+
dependency_type: dependency_type,
|
65
|
+
status: :pending
|
64
66
|
)
|
65
67
|
end
|
66
68
|
|
@@ -10,9 +10,9 @@ module BraceComb
|
|
10
10
|
dependency_mapping = self.class.
|
11
11
|
instance_variable_get(:@dependency_mapping)[self.dependency_type.to_sym]
|
12
12
|
ActiveRecord::Base.transaction do
|
13
|
-
execute_before_callbacks(dependency_mapping[:
|
13
|
+
execute_before_callbacks(dependency_mapping[:before_resolution])
|
14
14
|
execute_resolver(dependency_mapping[:resolver], args)
|
15
|
-
execute_after_callbacks(dependency_mapping[:
|
15
|
+
execute_after_callbacks(dependency_mapping[:after_resolution])
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
data/lib/brace_comb/version.rb
CHANGED
@@ -10,7 +10,7 @@ module BraceComb
|
|
10
10
|
def create_migration_file
|
11
11
|
add_migrations(dependent_table_name, 'create_dependent')
|
12
12
|
add_migrations(dependency_table_name, 'create_dependencies')
|
13
|
-
add_migrations(
|
13
|
+
add_migrations('associations', 'add_associations')
|
14
14
|
end
|
15
15
|
|
16
16
|
private
|
@@ -23,7 +23,7 @@ module BraceComb
|
|
23
23
|
else
|
24
24
|
migration_template(
|
25
25
|
"#{template}.rb.erb",
|
26
|
-
"db/migrate
|
26
|
+
"db/migrate/create_#{migration_name.pluralize}.rb",
|
27
27
|
migration_version: migration_version
|
28
28
|
)
|
29
29
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# This migration adds associations between the dependency and dependent
|
2
|
-
class
|
2
|
+
class CreateAssociations < ActiveRecord::Migration<%= migration_version %>
|
3
3
|
def change
|
4
4
|
add_foreign_key :<%= dependency_table_name%>, :<%= dependent_table_name %>, column: :source_id, dependent: :delete
|
5
5
|
add_foreign_key :<%= dependency_table_name%>, :<%= dependent_table_name %>, column: :destination_id, dependent: :delete
|
@@ -30,8 +30,8 @@ describe BraceComb::Helper do
|
|
30
30
|
|
31
31
|
declare_dependency type: :shopping,
|
32
32
|
resolver: :shopping_complete,
|
33
|
-
|
34
|
-
|
33
|
+
before_resolution: [:completed_status?],
|
34
|
+
after_resolution: [:complete_job]
|
35
35
|
end
|
36
36
|
end
|
37
37
|
it 'can declare dependency' do
|
@@ -39,8 +39,8 @@ describe BraceComb::Helper do
|
|
39
39
|
expect(dependency_mapping).to match(
|
40
40
|
shopping: {
|
41
41
|
resolver: :shopping_complete,
|
42
|
-
|
43
|
-
|
42
|
+
before_resolution: [:completed_status?],
|
43
|
+
after_resolution: [:complete_job]
|
44
44
|
}
|
45
45
|
)
|
46
46
|
end
|
@@ -107,4 +107,4 @@ describe BraceComb::Helper do
|
|
107
107
|
end
|
108
108
|
end
|
109
109
|
end
|
110
|
-
end
|
110
|
+
end
|
@@ -30,8 +30,8 @@ describe BraceComb::Model do
|
|
30
30
|
|
31
31
|
declare_dependency type: :shopping,
|
32
32
|
resolver: :mark_as_complete,
|
33
|
-
|
34
|
-
|
33
|
+
before_resolution: [:before_resolve1?, :before_resolve2?],
|
34
|
+
after_resolution: [:complete_job]
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -106,8 +106,8 @@ describe BraceComb::Model do
|
|
106
106
|
dependency_class.constantize.class_eval do
|
107
107
|
declare_dependency type: :shopping,
|
108
108
|
resolver: ->(data) { data.resolved! },
|
109
|
-
|
110
|
-
|
109
|
+
before_resolution: [->(_) { true }, :before_resolve?],
|
110
|
+
after_resolution: [:complete_job]
|
111
111
|
end
|
112
112
|
|
113
113
|
class JobDependency
|
@@ -153,4 +153,4 @@ describe BraceComb::Model do
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
end
|
156
|
-
end
|
156
|
+
end
|
@@ -26,12 +26,12 @@ describe BraceComb::MigrationGenerator, type: :generator do
|
|
26
26
|
expect(destination_root).to have_structure {
|
27
27
|
directory 'db' do
|
28
28
|
directory 'migrate' do
|
29
|
-
migration '
|
29
|
+
migration 'create_jobs' do
|
30
30
|
contains('class CreateJobs < ' + parent_class)
|
31
31
|
contains('create_table :jobs do |t|')
|
32
32
|
contains('t.timestamps null: false')
|
33
33
|
end
|
34
|
-
migration '
|
34
|
+
migration 'create_job_dependencies' do
|
35
35
|
contains('create_table :job_dependencies do |t|')
|
36
36
|
contains('class CreateJobDependencies < ' + parent_class)
|
37
37
|
contains('t.integer :dependency_type, null: false')
|
@@ -40,8 +40,8 @@ describe BraceComb::MigrationGenerator, type: :generator do
|
|
40
40
|
contains('t.integer :destination_id, null: false')
|
41
41
|
contains('t.timestamps null: false')
|
42
42
|
end
|
43
|
-
migration '
|
44
|
-
contains('class
|
43
|
+
migration 'create_associations' do
|
44
|
+
contains('class CreateAssociations < ' + parent_class)
|
45
45
|
contains('add_foreign_key :job_dependencies, :jobs, column: :source_id, dependent: :delete')
|
46
46
|
contains('add_foreign_key :job_dependencies, :jobs, column: :destination_id, dependent: :delete')
|
47
47
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brace_comb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ankita Gupta
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|