attr-gather 1.0.0 → 1.2.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: 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