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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -4
- data/examples/{amb.rb → cmp.rb} +8 -8
- data/lib/dry/effects.rb +33 -2
- data/lib/dry/effects/all.rb +3 -2
- data/lib/dry/effects/constructors.rb +4 -0
- data/lib/dry/effects/effects/{amb.rb → cmp.rb} +3 -3
- data/lib/dry/effects/effects/current_time.rb +9 -0
- data/lib/dry/effects/effects/resolve.rb +1 -3
- data/lib/dry/effects/effects/retry.rb +7 -2
- data/lib/dry/effects/effects/state.rb +12 -3
- data/lib/dry/effects/effects/timeout.rb +31 -0
- data/lib/dry/effects/errors.rb +19 -0
- data/lib/dry/effects/frame.rb +80 -0
- data/lib/dry/effects/handler.rb +11 -44
- data/lib/dry/effects/provider.rb +19 -0
- data/lib/dry/effects/provider/class_interface.rb +4 -3
- data/lib/dry/effects/providers/async.rb +4 -1
- data/lib/dry/effects/providers/cache.rb +8 -0
- data/lib/dry/effects/providers/cmp.rb +50 -0
- data/lib/dry/effects/providers/current_time.rb +38 -21
- data/lib/dry/effects/providers/defer.rb +8 -3
- data/lib/dry/effects/providers/env.rb +10 -0
- data/lib/dry/effects/providers/fork.rb +1 -1
- data/lib/dry/effects/providers/implicit.rb +6 -0
- data/lib/dry/effects/providers/interrupt.rb +10 -2
- data/lib/dry/effects/providers/lock.rb +7 -0
- data/lib/dry/effects/providers/parallel.rb +4 -1
- data/lib/dry/effects/providers/reader.rb +8 -1
- data/lib/dry/effects/providers/resolve.rb +17 -0
- data/lib/dry/effects/providers/retry.rb +6 -1
- data/lib/dry/effects/providers/state.rb +6 -0
- data/lib/dry/effects/providers/timeout.rb +47 -0
- data/lib/dry/effects/providers/timestamp.rb +27 -16
- data/lib/dry/effects/version.rb +1 -1
- metadata +11 -8
- 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
|
-
|
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}
|
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
|
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
|
data/lib/dry/effects/version.rb
CHANGED
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
|
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-
|
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/
|
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:
|
263
|
+
version: '0'
|
261
264
|
requirements: []
|
262
|
-
rubygems_version: 3.0.
|
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
|