depth_first 1.0.2 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 639dafea3e41c28485b5363b5bc9b8840b2fbee26b034409b6823fe41cd5db14
4
- data.tar.gz: 98ec27e41c2b8d4385c3fe246ca31377e56995659a57de678b150de195ab95be
3
+ metadata.gz: f458b23b4e11951bfe32ce363890c693ad436c02a8a01c06d7a63f1e1d1310db
4
+ data.tar.gz: a5fbd2c177fd85f4fe5edf6b0dd46e1354ee94fd4de2a72cdb6c3f9a18b1c0f9
5
5
  SHA512:
6
- metadata.gz: c19b6195c6600b41d3499a3df177430d5c82d134657929843a46de3aeaedd1d160bf238d8c01bf91209f94190945bf58728088c93a58ec87319098ebaad773a3
7
- data.tar.gz: 6358f250ae799e01c778649af1fef18d320f93091f16b7c1447df9ad89967e677ecb0a736b8e2873a2980729dfc82d1bab788feb5428573be3788e9e6ca56e15
6
+ metadata.gz: 32f4030a7a3cc8e214fbe1ae02a60ac77de467ae87725afc62cc3756cf39778d8c1719f92e813fe0cacfd99551ef8fc4745bee8f4cc160dbc7dbf48f2b00ad5f
7
+ data.tar.gz: a7e2ea90b8b5246d22352e75d94a78f354a15e9b686019dbab1206c95594b3750853818b25ef30cac01527ee714a4360f5e7a2b319bb839c5581e7e5fb29e8ea
data/README.md CHANGED
@@ -1,2 +1,73 @@
1
1
  # depth_first
2
- Depth-first search code organization
2
+ Depth-first search code organization gem allowing for sequential and concurrent code execution using [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby).
3
+
4
+ ## Tasks
5
+ A task accepts an input hash and merges in a results hash.
6
+
7
+ ### Examples
8
+ ```
9
+ class A < DepthFirst::Task
10
+ def perform
11
+ { a: 1 }
12
+ end
13
+ end
14
+
15
+ class B < DepthFirst::Task
16
+ def perform
17
+ { b: 2 }
18
+ end
19
+ end
20
+
21
+ class C < DepthFirst::Task
22
+ def perform
23
+ { c: 3 }
24
+ end
25
+ end
26
+ ```
27
+
28
+ ### Usage
29
+ ```
30
+ > A.new(test: true).perform
31
+ => { test: true, a: 1 }
32
+
33
+ > B.new(test: true).perform
34
+ => { test: true, b: 2 }
35
+ ```
36
+
37
+ ## Organizers
38
+ An organizer chains together tasks, piping a hash through each subtask.
39
+
40
+ ## SequentialOrganizer
41
+ Data is passed through `A`, `B`, and `C` sequentially. The input hash `{ testing: true }` is piped through A. The resulting hash `{ testing: true, a: 1 }` is then piped through B. And so on.
42
+
43
+ ### Example
44
+ ```
45
+ class SequentialAbc < DepthFirst::SequentialOrganizer
46
+ TASKS = [A, B, C].freeze
47
+ end
48
+ ```
49
+
50
+ ### Usage
51
+ ```
52
+ > SequentialAbc.new(testing: true).perform
53
+ => { testing: true, a: 1, b: 2, c: 3 }
54
+ ```
55
+
56
+ ## ParallelOrganizer
57
+ Data is passed through `A`, `B`, and `C` concurrently. All three classes execute in parallel. The input hash `{ testing: true }` is passed to all three classes and all three intermediate result hashes are merged into the final result hash once their promises are resolved.
58
+
59
+ ### Example
60
+ ```
61
+ class ParallelAbc < DepthFirst::ParallelOrganizer
62
+ TASKS = [A, B, C].freeze
63
+ end
64
+ ```
65
+
66
+ ### Usage
67
+ ```
68
+ > ParallelAbc.new(testing: true).perform
69
+ => { testing: true, a: 1, b: 2, c: 3}
70
+ ```
71
+
72
+ ## Note
73
+ An organizer can have a subtask which is itself another organizer. In this manner, code can be organized in an arbitrarily-deep tree structure with order of execution roughly matching a Depth First Search algorithm.
@@ -1,6 +1,13 @@
1
1
  module DepthFirst
2
2
  # Base parallel organizer class
3
3
  class ParallelOrganizer < SequentialOrganizer
4
+ DEPENDENCIES = [].freeze
5
+
6
+ def initialize(options)
7
+ super(options)
8
+ load_dependencies
9
+ end
10
+
4
11
  def perform
5
12
  tasks.map { |task| execute_promise(task) }
6
13
  .reduce(options) { |a, e| resolve_promise(a, e) }
@@ -8,6 +15,16 @@ module DepthFirst
8
15
 
9
16
  private
10
17
 
18
+ # Load dependencies before concurrency to get
19
+ # around lazy-loading race condition.
20
+ def load_dependencies
21
+ dependencies.each { |dependency| dependency }
22
+ end
23
+
24
+ def dependencies
25
+ self.class::DEPENDENCIES
26
+ end
27
+
11
28
  def execute_promise(task)
12
29
  Concurrent::Promise.new { task.new(options).perform }.execute
13
30
  end
@@ -1,3 +1,3 @@
1
1
  module DepthFirst
2
- VERSION = '1.0.2'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: depth_first
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Isaac Anthony