brace_comb 0.0.3 → 0.1.1

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
  SHA1:
3
- metadata.gz: 8fe368a2abc127eb6eabb97dd00821f440d0e715
4
- data.tar.gz: 31c9abbd499456fa9fa5a4d0c734166ead74d4cc
3
+ metadata.gz: 1bfd2a6dfe32328fd413215449ec8880f0a50cba
4
+ data.tar.gz: d3d8f3995d6695d34cfec43ac0e1fbfd2109d65c
5
5
  SHA512:
6
- metadata.gz: 56f9d83c4244ba7d54317b750c0f25efb4615344cd4e855bd9fb461b426b64d78619d6ae799151bd32a7ea83720be202fd0a593e17771c7615ac9ec265944661
7
- data.tar.gz: 8c3c00d2aa57ed9308a9d73f77da66f3f9234a6861ed9a172ca98504cf197b01390e8e0a8f642f8359e60e063f0319938c83d9bf0cfafca281c3f1fef58d0ead
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
- Allows setting dependency logic between entities, and declaring resolution methods and callbacks to resolve dependencies.
5
+ This is akin to how workflows are connected to each other with dependencies.
6
6
 
7
- ## Background
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
- Instead of having each workflow system define database entities to denote dependency relationships between tasks/dependents, this gem provides features that can create both the dependency and dependent model. These entity names are configurable based on the project needs.
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
- In addition, it accepts methods/procs to define the logic for dependency resolution via resolution callbacks. In the same vein as active record callbacks, dependency resolution callbacks can define actions that should be executed before a dependency is resolved and after a dependency is resolved. If any before callbacks fail, then dependency resolution will also fail.
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
- before_resolved: [:completed_status?],
48
- after_resolved: [:complete_job]
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
- before_resolved: [:completed_status?],
59
- after_resolved: [:complete_job]
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: job1, to: job2, type: 'shopping'`
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: job1, to: job2, type: 'shopping'`
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
- # before_resolved: [:completed_status?]
8
- # after_resolved: :complete_job, Proc.new {}
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
- # before_resolved: Checks that can be performed before a dependency is resolved.
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
- # after_resolved: if the dependency resolution succeeds, each of these methods will be
15
- # executed one by one. All the subsequent after_resolved hooks will not be executed if any
16
- # of the predecessor after_resolved hook throws an exception. However, this will not make
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
- :before_resolved,
23
- :after_resolved
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[:before_resolved])
13
+ execute_before_callbacks(dependency_mapping[:before_resolution])
14
14
  execute_resolver(dependency_mapping[:resolver], args)
15
- execute_after_callbacks(dependency_mapping[:after_resolved])
15
+ execute_after_callbacks(dependency_mapping[:after_resolution])
16
16
  end
17
17
  end
18
18
 
@@ -1,3 +1,3 @@
1
1
  module BraceComb
2
- VERSION = '0.0.3'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -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(nil, 'add_associations')
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/#{migration_name.pluralize}.rb",
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 AddAssociations < ActiveRecord::Migration<%= migration_version %>
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
- before_resolved: [:completed_status?],
34
- after_resolved: [:complete_job]
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
- before_resolved: [:completed_status?],
43
- after_resolved: [:complete_job]
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
- before_resolved: [:before_resolve1?, :before_resolve2?],
34
- after_resolved: [:complete_job]
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
- before_resolved: [->(_) { true }, :before_resolve?],
110
- after_resolved: [:complete_job]
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 'jobs' do
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 'job_dependencies' do
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 'add_associations' do
44
- contains('class AddAssociations < ' + parent_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.0.3
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-18 00:00:00.000000000 Z
11
+ date: 2017-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord