attr-gather 1.0.0 → 1.2.0

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: 07b0cde44c4761c85df967f235497ee50b8970940907fce14a2690edd94c17db
4
- data.tar.gz: bd01757a8ef862482555d1ed0d10c4ea5e935712f68ab9cad835a01e1d0ed6f5
3
+ metadata.gz: ee9b30fd44bd8931964b53b904815224fa6a5a592ac1f22d19605a982a326d42
4
+ data.tar.gz: 7954a71a61dc89266358909ce189312b3b3164e4092d62ae4fae973712efca9d
5
5
  SHA512:
6
- metadata.gz: 2d6687e01237ef8f573bb67dadf413eab97a448367d8d16773db6e8a855a388d1ee768d0f171c11f5afdd5109799aa2635f5b23ce2f2c9e9956875a6291313f1
7
- data.tar.gz: 5c46841afea4865187f23674a25ff0c3a0db79f826ca11d62b4c29df0bfcfe5e2833ae39520cb616005f59e1fee8f43dc5fccede3d355ac8a387eb5d415c3090
6
+ metadata.gz: 040b490aba781f8f851b617a365d2aea061f9d2afb189bcdf4e0e086effebc2135109a648b0f116d4be7000cbe4d3e10e369fadcb38d9e2910114c36957cce68
7
+ data.tar.gz: 59a93d0d6e16f9b2433822c4faf7ef4cda25f3e9e37da8a5fae816e313e1d6e0b86906a1d652b3c64125eae888607c9117ade38fc17ff11b84c361add21f4c62
@@ -0,0 +1,7 @@
1
+ ---
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: "bundler"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
@@ -0,0 +1,19 @@
1
+ ---
2
+ pull_request_rules:
3
+ - name: Automatic approval for Dependabot pull requests
4
+ conditions:
5
+ - author~=^dependabot(|-preview)\[bot\]$
6
+ - "check-success=build-test-lint"
7
+ actions:
8
+ review:
9
+ type: APPROVE
10
+ message: ✅ Auto-approved passing Dependabot PR with [Mergify.io](https://doc.mergify.io/actions.html#review)
11
+
12
+ - name: Automatic merge for Dependabot pull requests
13
+ conditions:
14
+ - author~=^dependabot(|-preview)\[bot\]$
15
+ - "#approved-reviews-by>=1"
16
+ - "check-success=build-test-lint"
17
+ actions:
18
+ merge:
19
+ method: squash
@@ -5,7 +5,7 @@ on:
5
5
  tags:
6
6
  - v*
7
7
  jobs:
8
- build-test-lint:
8
+ deploy:
9
9
  runs-on: ubuntu-latest
10
10
  steps:
11
11
  - uses: actions/checkout@v1
data/Gemfile CHANGED
@@ -6,7 +6,7 @@ source 'https://rubygems.org'
6
6
  gemspec
7
7
 
8
8
  group :development, :test do
9
- gem 'dry-validation', '~> 1.3'
9
+ gem 'dry-validation', '~> 1.5'
10
10
  gem 'pry'
11
11
  gem 'rubocop'
12
12
  gem 'rubocop-performance'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- attr-gather (1.0.0)
4
+ attr-gather (1.2.0)
5
5
  dry-container (~> 0.7)
6
6
 
7
7
  GEM
@@ -9,80 +9,83 @@ GEM
9
9
  specs:
10
10
  addressable (2.7.0)
11
11
  public_suffix (>= 2.0.2, < 5.0)
12
- ast (2.4.0)
12
+ ast (2.4.1)
13
13
  backport (1.1.2)
14
- coderay (1.1.2)
15
- concurrent-ruby (1.1.5)
14
+ benchmark (0.1.0)
15
+ coderay (1.1.3)
16
+ concurrent-ruby (1.1.7)
16
17
  diff-lcs (1.3)
17
18
  domain_name (0.5.20190701)
18
19
  unf (>= 0.0.5, < 1.0.0)
19
- dry-configurable (0.8.3)
20
+ dry-configurable (0.11.6)
20
21
  concurrent-ruby (~> 1.0)
21
22
  dry-core (~> 0.4, >= 0.4.7)
23
+ dry-equalizer (~> 0.2)
22
24
  dry-container (0.7.2)
23
25
  concurrent-ruby (~> 1.0)
24
26
  dry-configurable (~> 0.1, >= 0.1.3)
25
27
  dry-core (0.4.9)
26
28
  concurrent-ruby (~> 1.0)
27
- dry-equalizer (0.2.2)
29
+ dry-equalizer (0.3.0)
28
30
  dry-inflector (0.2.0)
29
- dry-initializer (3.0.1)
30
- dry-logic (1.0.3)
31
+ dry-initializer (3.0.4)
32
+ dry-logic (1.0.8)
31
33
  concurrent-ruby (~> 1.0)
32
34
  dry-core (~> 0.2)
33
35
  dry-equalizer (~> 0.2)
34
- dry-schema (1.4.1)
36
+ dry-schema (1.5.5)
35
37
  concurrent-ruby (~> 1.0)
36
38
  dry-configurable (~> 0.8, >= 0.8.3)
37
39
  dry-core (~> 0.4)
38
40
  dry-equalizer (~> 0.2)
39
41
  dry-initializer (~> 3.0)
40
42
  dry-logic (~> 1.0)
41
- dry-types (~> 1.2)
42
- dry-types (1.2.0)
43
+ dry-types (~> 1.4)
44
+ dry-types (1.4.0)
43
45
  concurrent-ruby (~> 1.0)
44
46
  dry-container (~> 0.3)
45
47
  dry-core (~> 0.4, >= 0.4.4)
46
- dry-equalizer (~> 0.2, >= 0.2.2)
48
+ dry-equalizer (~> 0.3)
47
49
  dry-inflector (~> 0.1, >= 0.1.2)
48
50
  dry-logic (~> 1.0, >= 1.0.2)
49
- dry-validation (1.3.1)
51
+ dry-validation (1.5.6)
50
52
  concurrent-ruby (~> 1.0)
51
53
  dry-container (~> 0.7, >= 0.7.1)
52
54
  dry-core (~> 0.4)
53
55
  dry-equalizer (~> 0.2)
54
56
  dry-initializer (~> 3.0)
55
- dry-schema (~> 1.0, >= 1.3.1)
56
- ffi (1.11.1)
57
+ dry-schema (~> 1.5, >= 1.5.2)
58
+ e2mmap (0.1.0)
59
+ ffi (1.13.1)
57
60
  ffi-compiler (1.0.1)
58
61
  ffi (>= 1.0.0)
59
62
  rake
60
- htmlentities (4.3.4)
61
- http (4.2.0)
63
+ http (4.4.1)
62
64
  addressable (~> 2.3)
63
65
  http-cookie (~> 1.0)
64
- http-form_data (~> 2.0)
66
+ http-form_data (~> 2.2)
65
67
  http-parser (~> 1.2.0)
66
68
  http-cookie (1.0.3)
67
69
  domain_name (~> 0.5)
68
- http-form_data (2.1.1)
70
+ http-form_data (2.3.0)
69
71
  http-parser (1.2.1)
70
72
  ffi-compiler (>= 1.0, < 2.0)
71
- jaro_winkler (1.5.3)
72
- method_source (0.9.2)
73
+ jaro_winkler (1.5.4)
74
+ maruku (0.7.3)
75
+ method_source (1.0.0)
73
76
  mini_portile2 (2.4.0)
74
- nokogiri (1.10.4)
77
+ nokogiri (1.10.10)
75
78
  mini_portile2 (~> 2.4.0)
76
- parallel (1.18.0)
77
- parser (2.6.5.0)
78
- ast (~> 2.4.0)
79
- pry (0.12.2)
80
- coderay (~> 1.1.0)
81
- method_source (~> 0.9.0)
82
- public_suffix (4.0.1)
79
+ parallel (1.19.2)
80
+ parser (2.7.2.0)
81
+ ast (~> 2.4.1)
82
+ pry (0.13.1)
83
+ coderay (~> 1.1)
84
+ method_source (~> 1.0)
85
+ public_suffix (4.0.6)
83
86
  rainbow (3.0.0)
84
- rake (10.5.0)
85
- reverse_markdown (1.3.0)
87
+ rake (13.0.1)
88
+ reverse_markdown (2.0.0)
86
89
  nokogiri
87
90
  rspec (3.9.0)
88
91
  rspec-core (~> 3.9.0)
@@ -107,25 +110,27 @@ GEM
107
110
  rubocop-performance (1.5.1)
108
111
  rubocop (>= 0.71.0)
109
112
  ruby-progressbar (1.10.1)
110
- solargraph (0.37.2)
113
+ solargraph (0.39.17)
111
114
  backport (~> 1.1)
115
+ benchmark
112
116
  bundler (>= 1.17.2)
113
- htmlentities (~> 4.3, >= 4.3.4)
117
+ e2mmap
114
118
  jaro_winkler (~> 1.5)
119
+ maruku (~> 0.7, >= 0.7.3)
115
120
  nokogiri (~> 1.9, >= 1.9.1)
116
121
  parser (~> 2.3)
117
- reverse_markdown (~> 1.0, >= 1.0.5)
122
+ reverse_markdown (>= 1.0.5, < 3)
118
123
  rubocop (~> 0.52)
119
- thor (~> 0.19, >= 0.19.4)
124
+ thor (~> 1.0)
120
125
  tilt (~> 2.0)
121
- yard (~> 0.9)
122
- thor (0.20.3)
126
+ yard (~> 0.9, >= 0.9.24)
127
+ thor (1.0.1)
123
128
  tilt (2.0.10)
124
129
  unf (0.1.4)
125
130
  unf_ext
126
- unf_ext (0.0.7.6)
127
- unicode-display_width (1.6.0)
128
- yard (0.9.20)
131
+ unf_ext (0.0.7.7)
132
+ unicode-display_width (1.6.1)
133
+ yard (0.9.25)
129
134
 
130
135
  PLATFORMS
131
136
  ruby
@@ -133,10 +138,10 @@ PLATFORMS
133
138
  DEPENDENCIES
134
139
  attr-gather!
135
140
  bundler (~> 2.0)
136
- dry-validation (~> 1.3)
141
+ dry-validation (~> 1.5)
137
142
  http
138
143
  pry
139
- rake (~> 10.0)
144
+ rake (~> 13.0)
140
145
  rspec (~> 3.0)
141
146
  rubocop
142
147
  rubocop-performance
data/Rakefile CHANGED
@@ -1,13 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
- require 'rubocop/rake_task'
6
- require 'yard'
7
4
 
8
- RSpec::Core::RakeTask.new(:spec)
9
- RuboCop::RakeTask.new(:lint)
10
- YARD::Rake::YardocTask.new(:doc)
5
+ begin
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ rescue LoadError
9
+ warn 'Could not load rspec rake task'
10
+ end
11
+
12
+ begin
13
+ require 'rubocop/rake_task'
14
+ RuboCop::RakeTask.new(:lint)
15
+ rescue LoadError
16
+ warn 'Could not load rubocop rake task'
17
+ end
18
+
19
+ begin
20
+ require 'yard'
21
+ YARD::Rake::YardocTask.new(:doc)
22
+ rescue LoadError
23
+ warn 'Could not load yarddoc rake task'
24
+ end
11
25
 
12
26
  task default: %i[spec lint]
13
27
 
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.require_paths = ['lib']
32
32
 
33
33
  spec.add_development_dependency 'bundler', '~> 2.0'
34
- spec.add_development_dependency 'rake', '~> 10.0'
34
+ spec.add_development_dependency 'rake', '~> 13.0'
35
35
  spec.add_development_dependency 'rspec', '~> 3.0'
36
36
 
37
37
  spec.add_dependency 'dry-container', '~> 0.7'
@@ -15,16 +15,16 @@ module Attr
15
15
  @default = resolve(:deep_merge)
16
16
  end
17
17
 
18
- register(:deep_merge) do |*args|
18
+ register(:deep_merge) do |*args, **opts|
19
19
  require 'attr/gather/aggregators/deep_merge'
20
20
 
21
- DeepMerge.new(*args)
21
+ DeepMerge.new(*args, **opts)
22
22
  end
23
23
 
24
- register(:shallow_merge) do |*args|
24
+ register(:shallow_merge) do |*args, **opts|
25
25
  require 'attr/gather/aggregators/shallow_merge'
26
26
 
27
- ShallowMerge.new(*args)
27
+ ShallowMerge.new(*args, **opts)
28
28
  end
29
29
  end
30
30
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'attr/gather/filters/noop'
4
+
3
5
  module Attr
4
6
  module Gather
5
7
  module Aggregators
@@ -11,8 +13,14 @@ module Attr
11
13
  class Base
12
14
  attr_accessor :filter
13
15
 
16
+ NOOP_FILTER ||= Filters::Noop.new
17
+
14
18
  def initialize(**opts)
15
- @filter = opts.delete(:filter)
19
+ @filter = opts.delete(:filter) || NOOP_FILTER
20
+ end
21
+
22
+ def with(**opts)
23
+ self.class.new(filter: @filter, **opts)
16
24
  end
17
25
 
18
26
  def call(_original_input, _results_array)
@@ -21,16 +29,10 @@ module Attr
21
29
 
22
30
  private
23
31
 
24
- def wrap_result(result)
25
- Concurrent::Promise.fulfill(result)
26
- end
27
-
28
32
  def unwrap_result(res)
29
- unvalidated = res.result.value!
30
-
31
- return unvalidated if filter.nil?
33
+ return res if filter.nil?
32
34
 
33
- filter.call(unvalidated).value
35
+ filter.call(res).value
34
36
  end
35
37
  end
36
38
  end
@@ -21,16 +21,19 @@ module Attr
21
21
 
22
22
  def call(input, execution_results)
23
23
  execution_results = execution_results.reverse_each if reverse?
24
+ initial = unwrap_initial_input(input)
24
25
 
25
- result = execution_results.reduce(input.dup) do |memo, res|
26
+ execution_results.reduce(initial) do |memo, res|
26
27
  deep_merge(memo, unwrap_result(res))
27
28
  end
28
-
29
- wrap_result(result)
30
29
  end
31
30
 
32
31
  private
33
32
 
33
+ def unwrap_initial_input(input)
34
+ input
35
+ end
36
+
34
37
  def reverse?
35
38
  @reverse
36
39
  end
@@ -20,13 +20,11 @@ module Attr
20
20
  end
21
21
 
22
22
  def call(input, execution_results)
23
- items = reverse? ? execution_results.reverse_each : execution_results
23
+ execution_results = execution_results.reverse_each if reverse?
24
24
 
25
- result = items.reduce(input.dup) do |memo, res|
25
+ execution_results.reduce(input) do |memo, res|
26
26
  memo.merge(unwrap_result(res))
27
27
  end
28
-
29
- wrap_result(result)
30
28
  end
31
29
 
32
30
  private
@@ -29,13 +29,13 @@ module Attr
29
29
  # @param name [Symbol]
30
30
  #
31
31
  # @return [#call]
32
- def resolve(name, *args)
32
+ def resolve(name, *args, **opts)
33
33
  block = @__storage__.fetch(name) do
34
34
  raise NotFoundError,
35
35
  "no item with name #{name} registered"
36
36
  end
37
37
 
38
- block.call(*args)
38
+ block.call(*args, **opts)
39
39
  end
40
40
 
41
41
  # @api private
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Attr
4
4
  module Gather
5
- VERSION = '1.0.0'
5
+ VERSION = '1.2.0'
6
6
  end
7
7
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'attr/gather/workflow/task_executor'
4
- require 'attr/gather/workflow/async_task_executor'
5
-
6
3
  module Attr
7
4
  module Gather
8
5
  module Workflow
@@ -21,42 +18,39 @@ module Attr
21
18
  #
22
19
  # @param input [Hash]
23
20
  #
24
- # @return [Concurrent::Promise]
21
+ # @return [Concurrent::Promise<Hash>]
25
22
  #
26
23
  # @note For more information, check out {https://dry-rb.org/gems/dry-monads/1.0/result}
27
24
  #
28
25
  # @api public
29
26
  def call(input)
30
- final_results = []
27
+ task_promises = {}
31
28
 
32
- each_task_batch.reduce(input.dup) do |aggregated_input, batch|
33
- executor_results = execute_batch(aggregated_input, batch)
34
- final_results << executor_results
35
- aggregator.call(aggregated_input, executor_results).value!
29
+ final_results = self.class.tasks.to_a.map do |task|
30
+ task_promises[task] = execute_task(input, task, task_promises)
36
31
  end
37
32
 
38
- aggregator.call(input.dup, final_results.flatten(1))
33
+ Concurrent::Promise.zip(*final_results).then do |results|
34
+ aggregator.call(input, results)
35
+ end
39
36
  end
40
37
 
41
38
  private
42
39
 
43
- # Enumator for task batches
44
- #
45
- # @return [Enumerator]
46
- #
47
- # @api private
48
- def each_task_batch
49
- self.class.tasks.each_batch
50
- end
51
-
52
40
  # Executes a batch of tasks
53
41
  #
54
42
  # @return [Array<TaskExecutionResult>]
55
43
  #
56
44
  # @api private
57
- def execute_batch(aggregated_input, batch)
58
- executor = AsyncTaskExecutor.new(batch, container: container)
59
- executor.call(aggregated_input)
45
+ def execute_task(initial_input, task, task_promises)
46
+ task_proc = container.resolve(task.name)
47
+ dep_promises = task.depends_on.map { |t| task_promises[t] }
48
+ input_promise = Concurrent::Promise.zip(*dep_promises)
49
+
50
+ input_promise.then do |results|
51
+ dep_input = aggregator.call(initial_input, results)
52
+ task_proc.call(dep_input)
53
+ end
60
54
  end
61
55
 
62
56
  # @api private
@@ -36,9 +36,9 @@ module Attr
36
36
  #
37
37
  # @api public
38
38
  def task(task_name, opts = EMPTY_HASH)
39
- task = Task.new(name: task_name, **opts)
40
- yield task
41
- tasks << task
39
+ conf = OpenStruct.new
40
+ yield conf
41
+ tasks << Hash[name: task_name, **opts, **conf.to_h]
42
42
  self
43
43
  end
44
44
 
@@ -88,13 +88,13 @@ module Attr
88
88
  #
89
89
  # @api public
90
90
  def aggregator(agg = nil, opts = EMPTY_HASH)
91
- if agg.nil? && !defined?(@aggregator)
92
- @aggregator = Aggregators.default
93
- return @aggregator
94
- end
95
-
96
- @aggregator = Aggregators.resolve(agg, filter: filter, **opts) if agg
97
- @aggregator
91
+ @aggregator = if agg.nil? && !defined?(@aggregator)
92
+ Aggregators.default
93
+ elsif agg
94
+ Aggregators.resolve(agg, filter: filter, **opts)
95
+ else
96
+ @aggregator
97
+ end
98
98
  end
99
99
 
100
100
  # Defines a filter for filtering out invalid values
@@ -130,12 +130,16 @@ module Attr
130
130
  # @param args [Array<Object>] arguments for initializing the filter
131
131
  #
132
132
  # @api public
133
- def filter(filt = Undefined, *args)
134
- if filt == Undefined && !defined?(@filter)
135
- @filter = Filters.default
136
- elsif filt != Undefined
137
- @filter = Filters.resolve(filt, *args)
138
- end
133
+ def filter(filt = nil, *args, **opts)
134
+ @filter = if filt.nil? && !defined?(@filter)
135
+ Filters.default
136
+ elsif filt
137
+ Filters.resolve(filt, *args, **opts)
138
+ else
139
+ @filter
140
+ end
141
+
142
+ aggregator.filter = @filter
139
143
 
140
144
  @filter
141
145
  end
@@ -169,7 +173,7 @@ module Attr
169
173
  # @api public
170
174
  def filter_with_contract(arg = nil, &blk)
171
175
  contract = block_given? ? build_inline_contract_filter(&blk) : arg
172
- @filter = Filters.resolve(:contract, contract)
176
+ filter(:contract, contract)
173
177
  end
174
178
 
175
179
  private
@@ -1,19 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'dry-equalizer'
4
+
3
5
  module Attr
4
6
  module Gather
5
7
  module Workflow
6
8
  # @api private
7
9
  class Task
8
- attr_accessor :depends_on, :name
10
+ send :include, Dry::Equalizer(:name, :depends_on)
11
+
12
+ attr_accessor :name, :depends_on
9
13
 
14
+ # Initialize a new DeepMerge aggregator
15
+ #
16
+ # @param name [String] name of the task
17
+ # @param depends_on [Array<Task>] tasks needed before running this task
18
+ #
19
+ # @api private
10
20
  def initialize(name:, depends_on: [])
11
21
  @name = name
12
22
  @depends_on = depends_on
13
23
  end
14
24
 
25
+ # Check if this task depends on a given task
26
+ #
27
+ # @param other_task [Task] task to check
15
28
  def depends_on?(other_task)
16
- depends_on.include?(other_task.name)
29
+ depends_on.include?(other_task)
17
30
  end
18
31
 
19
32
  def fullfilled_given_remaining_tasks?(task_list)
@@ -20,7 +20,9 @@ module Attr
20
20
  tasks.each { |t| self << t }
21
21
  end
22
22
 
23
- def <<(task)
23
+ def <<(hash)
24
+ name, depends_on = hash.values_at :name, :depends_on
25
+ task = build_task(name, depends_on)
24
26
  validate_for_insert!(task)
25
27
 
26
28
  registered_tasks.each do |t|
@@ -68,6 +70,16 @@ module Attr
68
70
 
69
71
  private
70
72
 
73
+ def build_task(name, depends_on)
74
+ deps = depends_on.map do |dep_name|
75
+ registered_tasks.find do |task|
76
+ task.name == dep_name
77
+ end
78
+ end
79
+
80
+ Task.new(name: name, depends_on: deps)
81
+ end
82
+
71
83
  def tsort_each_child(node, &blk)
72
84
  to_h[node].each(&blk)
73
85
  end
@@ -99,7 +111,7 @@ module Attr
99
111
  end
100
112
 
101
113
  def depended_on_tasks_exist?(task)
102
- task.depends_on.all? { |t| registered_tasks.map(&:name).include?(t) }
114
+ task.depends_on.all? { |t| registered_tasks.include?(t) }
103
115
  end
104
116
  end
105
117
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attr-gather
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Ker-Seymer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-20 00:00:00.000000000 Z
11
+ date: 2020-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '13.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -73,6 +73,8 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - ".github/dependabot.yml"
77
+ - ".github/mergify.yml"
76
78
  - ".github/workflows/deploy.yml"
77
79
  - ".github/workflows/doc.yml"
78
80
  - ".github/workflows/ruby.yml"
@@ -113,14 +115,11 @@ files:
113
115
  - lib/attr/gather/filters/result.rb
114
116
  - lib/attr/gather/version.rb
115
117
  - lib/attr/gather/workflow.rb
116
- - lib/attr/gather/workflow/async_task_executor.rb
117
118
  - lib/attr/gather/workflow/callable.rb
118
119
  - lib/attr/gather/workflow/dot_serializer.rb
119
120
  - lib/attr/gather/workflow/dsl.rb
120
121
  - lib/attr/gather/workflow/graphable.rb
121
122
  - lib/attr/gather/workflow/task.rb
122
- - lib/attr/gather/workflow/task_execution_result.rb
123
- - lib/attr/gather/workflow/task_executor.rb
124
123
  - lib/attr/gather/workflow/task_graph.rb
125
124
  homepage: https://github.com/ianks/attr-gather
126
125
  licenses:
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'attr/gather/workflow/task_executor'
4
-
5
- module Attr
6
- module Gather
7
- module Workflow
8
- # @api private
9
- class AsyncTaskExecutor < TaskExecutor
10
- def initialize(*)
11
- super
12
- @executor = :io
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Attr
4
- module Gather
5
- module Workflow
6
- # A wrapper containing information and results of a task execution
7
- #
8
- # @!attribute [r] started_at
9
- # @return [Time] time which the execution occured
10
- #
11
- # @!attribute [r] task
12
- # @return [Attr::Gather::Workflow::Task] task that was run
13
- #
14
- # @!attribute [r] result
15
- # @return [Concurrent::Promise] the result promise of the the task
16
- #
17
- # @api public
18
- class TaskExecutionResult
19
- include Concerns::Identifiable
20
-
21
- attr_reader :task, :result, :started_at, :uuid
22
-
23
- def initialize(task, result)
24
- @started_at = Time.now
25
- @uuid = SecureRandom.uuid
26
- @task = task
27
- @result = result
28
- end
29
-
30
- # @!attribute [r] state
31
- # @return [:unscheduled, :pending, :processing, :rejected, :fulfilled]
32
- def state
33
- result.state
34
- end
35
-
36
- # Extracts the result, this is an unsafe operation that blocks the
37
- # operation, and returns either the value or an exception.
38
- #
39
- # @note For more information, check out {https://ruby-concurrency.github.io/concurrent-ruby/1.1.5/Concurrent/Concern/Obligation.html#value!-instance_method}
40
- def value!
41
- result.value!
42
- end
43
-
44
- # Represents the TaskExecutionResult as a hash
45
- #
46
- # @return [Hash]
47
- def as_json
48
- value = result.value
49
-
50
- { started_at: started_at,
51
- task: task.as_json,
52
- state: state,
53
- value: value }
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'concurrent'
4
- require 'attr/gather/workflow/task_execution_result'
5
-
6
- module Attr
7
- module Gather
8
- module Workflow
9
- # @api private
10
- class TaskExecutor
11
- attr_reader :batch, :container, :executor
12
-
13
- def initialize(batch, container:)
14
- @batch = batch
15
- @container = container
16
- @executor = :immediate
17
- end
18
-
19
- def call(input)
20
- batch.map do |task|
21
- task_proc = container.resolve(task.name)
22
- result = Concurrent::Promise.execute(executor: executor) do
23
- task_proc.call(input)
24
- end
25
- TaskExecutionResult.new(task, result)
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end