dry-effects 0.1.0.alpha2 → 0.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -4
  3. data/examples/{amb.rb → cmp.rb} +8 -8
  4. data/lib/dry/effects.rb +33 -2
  5. data/lib/dry/effects/all.rb +3 -2
  6. data/lib/dry/effects/constructors.rb +4 -0
  7. data/lib/dry/effects/effects/{amb.rb → cmp.rb} +3 -3
  8. data/lib/dry/effects/effects/current_time.rb +9 -0
  9. data/lib/dry/effects/effects/resolve.rb +1 -3
  10. data/lib/dry/effects/effects/retry.rb +7 -2
  11. data/lib/dry/effects/effects/state.rb +12 -3
  12. data/lib/dry/effects/effects/timeout.rb +31 -0
  13. data/lib/dry/effects/errors.rb +19 -0
  14. data/lib/dry/effects/frame.rb +80 -0
  15. data/lib/dry/effects/handler.rb +11 -44
  16. data/lib/dry/effects/provider.rb +19 -0
  17. data/lib/dry/effects/provider/class_interface.rb +4 -3
  18. data/lib/dry/effects/providers/async.rb +4 -1
  19. data/lib/dry/effects/providers/cache.rb +8 -0
  20. data/lib/dry/effects/providers/cmp.rb +50 -0
  21. data/lib/dry/effects/providers/current_time.rb +38 -21
  22. data/lib/dry/effects/providers/defer.rb +8 -3
  23. data/lib/dry/effects/providers/env.rb +10 -0
  24. data/lib/dry/effects/providers/fork.rb +1 -1
  25. data/lib/dry/effects/providers/implicit.rb +6 -0
  26. data/lib/dry/effects/providers/interrupt.rb +10 -2
  27. data/lib/dry/effects/providers/lock.rb +7 -0
  28. data/lib/dry/effects/providers/parallel.rb +4 -1
  29. data/lib/dry/effects/providers/reader.rb +8 -1
  30. data/lib/dry/effects/providers/resolve.rb +17 -0
  31. data/lib/dry/effects/providers/retry.rb +6 -1
  32. data/lib/dry/effects/providers/state.rb +6 -0
  33. data/lib/dry/effects/providers/timeout.rb +47 -0
  34. data/lib/dry/effects/providers/timestamp.rb +27 -16
  35. data/lib/dry/effects/version.rb +1 -1
  36. metadata +11 -8
  37. data/lib/dry/effects/providers/amb.rb +0 -36
@@ -78,10 +78,17 @@ module Dry
78
78
  backend.meta(key)
79
79
  end
80
80
 
81
+ # Locate handler in the stack
82
+ #
83
+ # @return [Provider]
84
+ # @api private
81
85
  def locate
82
86
  self
83
87
  end
84
88
 
89
+ # Yield the block with the handler installed
90
+ #
91
+ # @api private
85
92
  def call(stack, backend = Undefined)
86
93
  backend_replace = Undefined.default(backend) do
87
94
  parent = ::Dry::Effects.yield(Locate) { Undefined }
@@ -15,7 +15,7 @@ module Dry
15
15
  stack = self.stack.dup
16
16
  proc do |&block|
17
17
  ::Concurrent::Promise.execute(executor: executor) do
18
- Handler.spawn_fiber(stack, &block)
18
+ Frame.spawn_fiber(stack, &block)
19
19
  end
20
20
  end
21
21
  end
@@ -24,6 +24,9 @@ module Dry
24
24
  xs.map(&:value!)
25
25
  end
26
26
 
27
+ # Yield the block with the handler installed
28
+ #
29
+ # @api private
27
30
  def call(stack)
28
31
  @stack = stack
29
32
  super
@@ -34,6 +34,9 @@ module Dry
34
34
  state
35
35
  end
36
36
 
37
+ # Yield the block with the handler installed
38
+ #
39
+ # @api private
37
40
  def call(stack, state)
38
41
  case state
39
42
  when state_type
@@ -44,14 +47,18 @@ module Dry
44
47
  end
45
48
  end
46
49
 
50
+ # @return [String]
51
+ # @api public
47
52
  def represent
48
53
  if Undefined.equal?(state)
49
- "#{type}[#{scope} unset]"
54
+ "#{type}[#{scope} not set]"
50
55
  else
51
56
  "#{type}[#{scope} set]"
52
57
  end
53
58
  end
54
59
 
60
+ # @return [Boolean]
61
+ # @api public
55
62
  def provide?(effect)
56
63
  effect.type.equal?(:state) && effect.name.equal?(:read) && scope.equal?(effect.scope)
57
64
  end
@@ -38,10 +38,17 @@ module Dry
38
38
  end
39
39
  end
40
40
 
41
+ # Locate handler in the stack
42
+ #
43
+ # @return [Provider]
44
+ # @api private
41
45
  def locate
42
46
  self
43
47
  end
44
48
 
49
+ # Yield the block with the handler installed
50
+ #
51
+ # @api private
45
52
  def call(stack, dynamic = EMPTY_HASH, options = EMPTY_HASH)
46
53
  @dynamic = dynamic
47
54
 
@@ -56,6 +63,9 @@ module Dry
56
63
  @dynamic = EMPTY_HASH
57
64
  end
58
65
 
66
+ # @param [Effect] effect
67
+ # @return [Boolean]
68
+ # @api public
59
69
  def provide?(effect)
60
70
  if super
61
71
  !effect.name.equal?(:resolve) || key?(effect.payload[0])
@@ -64,15 +74,22 @@ module Dry
64
74
  end
65
75
  end
66
76
 
77
+ # @param [Symbol,String] key Dependency key
78
+ # @return [Boolean]
79
+ # @api public
67
80
  def key?(key)
68
81
  static.key?(key) || dynamic.key?(key) || parent&.key?(key)
69
82
  end
70
83
 
84
+ # @return [String]
85
+ # @api public
71
86
  def represent
72
87
  containers = [represent_container(static), represent_container(dynamic)].compact.join('+')
73
88
  "resolve[#{containers.empty? ? 'empty' : containers}]"
74
89
  end
75
90
 
91
+ # @return [String]
92
+ # @api private
76
93
  def represent_container(container)
77
94
  if container.is_a?(::Hash)
78
95
  container.empty? ? nil : 'hash'
@@ -15,6 +15,9 @@ module Dry
15
15
 
16
16
  attr_reader :limit
17
17
 
18
+ # Yield the block with the handler installed
19
+ #
20
+ # @api private
18
21
  def call(_, limit)
19
22
  @limit = limit
20
23
  @attempts = 0
@@ -27,7 +30,7 @@ module Dry
27
30
  end
28
31
  end
29
32
 
30
- def repeat
33
+ def retry
31
34
  Instructions.Raise(halt.new)
32
35
  end
33
36
 
@@ -52,6 +55,8 @@ module Dry
52
55
  super && scope.equal?(effect.scope)
53
56
  end
54
57
 
58
+ # @return [String]
59
+ # @api public
55
60
  def represent
56
61
  "retry[#{scope} #{attempts}/#{limit}]"
57
62
  end
@@ -16,11 +16,17 @@ module Dry
16
16
  end
17
17
  end
18
18
 
19
+ # Yield the block with the handler installed
20
+ #
21
+ # @api private
19
22
  def call(stack, state = Undefined)
20
23
  r = super
21
24
  [self.state, r]
22
25
  end
23
26
 
27
+ # @param [Effect] effect
28
+ # @return [Boolean]
29
+ # @api public
24
30
  def provide?(effect)
25
31
  effect.type.equal?(:state) && scope.equal?(effect.scope)
26
32
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/effects/provider'
4
+
5
+ module Dry
6
+ module Effects
7
+ module Providers
8
+ class Timeout < Provider[:timeout]
9
+ def self.handle_method(scope, as: Undefined, **)
10
+ Undefined.default(as) { :with_timeout }
11
+ end
12
+
13
+ param :scope
14
+
15
+ def timeout
16
+ left = @time_out_at - read_clock
17
+
18
+ if left <= 0
19
+ 0.0
20
+ else
21
+ left
22
+ end
23
+ end
24
+
25
+ # Yield the block with the handler installed
26
+ #
27
+ # @api private
28
+ def call(stack, timeout)
29
+ @time_out_at = read_clock + timeout
30
+
31
+ super(stack)
32
+ end
33
+
34
+ # @param [Effect] effect
35
+ # @return [Boolean]
36
+ # @api public
37
+ def provide?(effect)
38
+ effect.type.equal?(:timeout) && scope.equal?(effect.scope)
39
+ end
40
+
41
+ def read_clock
42
+ ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -16,11 +16,38 @@ module Dry
16
16
 
17
17
  attr_reader :generator
18
18
 
19
+ # Yield the block with the handler installed
20
+ #
21
+ # @api private
19
22
  def call(stack, generator = Undefined, **options)
20
23
  @generator = build_generator(generator, **options)
21
24
  super(stack)
22
25
  end
23
26
 
27
+ def timestamp(round_to: Undefined, **options)
28
+ time = generator.(**options)
29
+
30
+ round = Undefined.coalesce(round_to, self.round)
31
+
32
+ if Undefined.equal?(round)
33
+ time
34
+ else
35
+ time.round(round)
36
+ end
37
+ end
38
+
39
+ # Locate handler in the stack
40
+ #
41
+ # @return [Provider]
42
+ # @api private
43
+ def locate
44
+ self
45
+ end
46
+
47
+ private
48
+
49
+ # @return [Proc] time generator
50
+ # @api private
24
51
  def build_generator(generator, step: Undefined, initial: Undefined, overridable: false)
25
52
  if overridable
26
53
  parent = ::Dry::Effects.yield(Locate) { nil }
@@ -38,22 +65,6 @@ module Dry
38
65
  RunningTimeGenerator.()
39
66
  end
40
67
  end
41
-
42
- def timestamp(round_to: Undefined, **options)
43
- time = generator.(**options)
44
-
45
- round = Undefined.coalesce(round_to, self.round)
46
-
47
- if Undefined.equal?(round)
48
- time
49
- else
50
- time.round(round)
51
- end
52
- end
53
-
54
- def locate
55
- self
56
- end
57
68
  end
58
69
  end
59
70
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Effects
5
- VERSION = '0.1.0.alpha2'
5
+ VERSION = '0.1.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-effects
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.alpha2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Shilnikov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-22 00:00:00.000000000 Z
11
+ date: 2019-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -179,16 +179,16 @@ files:
179
179
  - README.md
180
180
  - Rakefile
181
181
  - dry-effects.gemspec
182
- - examples/amb.rb
182
+ - examples/cmp.rb
183
183
  - examples/state.rb
184
184
  - lib/dry/effects.rb
185
185
  - lib/dry/effects/all.rb
186
186
  - lib/dry/effects/constructors.rb
187
187
  - lib/dry/effects/container.rb
188
188
  - lib/dry/effects/effect.rb
189
- - lib/dry/effects/effects/amb.rb
190
189
  - lib/dry/effects/effects/async.rb
191
190
  - lib/dry/effects/effects/cache.rb
191
+ - lib/dry/effects/effects/cmp.rb
192
192
  - lib/dry/effects/effects/current_time.rb
193
193
  - lib/dry/effects/effects/defer.rb
194
194
  - lib/dry/effects/effects/env.rb
@@ -202,11 +202,13 @@ files:
202
202
  - lib/dry/effects/effects/resolve.rb
203
203
  - lib/dry/effects/effects/retry.rb
204
204
  - lib/dry/effects/effects/state.rb
205
+ - lib/dry/effects/effects/timeout.rb
205
206
  - lib/dry/effects/effects/timestamp.rb
206
207
  - lib/dry/effects/errors.rb
207
208
  - lib/dry/effects/extensions.rb
208
209
  - lib/dry/effects/extensions/auto_inject.rb
209
210
  - lib/dry/effects/extensions/system.rb
211
+ - lib/dry/effects/frame.rb
210
212
  - lib/dry/effects/halt.rb
211
213
  - lib/dry/effects/handler.rb
212
214
  - lib/dry/effects/inflector.rb
@@ -216,9 +218,9 @@ files:
216
218
  - lib/dry/effects/instructions/raise.rb
217
219
  - lib/dry/effects/provider.rb
218
220
  - lib/dry/effects/provider/class_interface.rb
219
- - lib/dry/effects/providers/amb.rb
220
221
  - lib/dry/effects/providers/async.rb
221
222
  - lib/dry/effects/providers/cache.rb
223
+ - lib/dry/effects/providers/cmp.rb
222
224
  - lib/dry/effects/providers/current_time.rb
223
225
  - lib/dry/effects/providers/current_time/time_generators.rb
224
226
  - lib/dry/effects/providers/defer.rb
@@ -233,6 +235,7 @@ files:
233
235
  - lib/dry/effects/providers/resolve.rb
234
236
  - lib/dry/effects/providers/retry.rb
235
237
  - lib/dry/effects/providers/state.rb
238
+ - lib/dry/effects/providers/timeout.rb
236
239
  - lib/dry/effects/providers/timestamp.rb
237
240
  - lib/dry/effects/stack.rb
238
241
  - lib/dry/effects/version.rb
@@ -255,11 +258,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
255
258
  version: '2.4'
256
259
  required_rubygems_version: !ruby/object:Gem::Requirement
257
260
  requirements:
258
- - - ">"
261
+ - - ">="
259
262
  - !ruby/object:Gem::Version
260
- version: 1.3.1
263
+ version: '0'
261
264
  requirements: []
262
- rubygems_version: 3.0.3
265
+ rubygems_version: 3.0.6
263
266
  signing_key:
264
267
  specification_version: 4
265
268
  summary: Algebraic effects.
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'dry/effects/provider'
4
-
5
- module Dry
6
- module Effects
7
- module Providers
8
- class Amb < Provider[:amb]
9
- include Dry::Equalizer(:id, :value)
10
-
11
- attr_reader :value
12
-
13
- param :id
14
-
15
- def get
16
- value
17
- end
18
-
19
- def call(_)
20
- @value = false
21
- first = yield
22
- @value = true
23
- [first, yield]
24
- end
25
-
26
- def provide?(effect)
27
- super && id.equal?(effect.id)
28
- end
29
-
30
- def represent
31
- "amb[#{id}=#{@value}]"
32
- end
33
- end
34
- end
35
- end
36
- end