dry-effects 0.1.2 → 0.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 +4 -4
- data/CHANGELOG.md +57 -5
- data/LICENSE +1 -1
- data/README.md +19 -11
- data/dry-effects.gemspec +33 -41
- data/lib/dry/effects/all.rb +4 -4
- data/lib/dry/effects/container.rb +1 -1
- data/lib/dry/effects/effect.rb +2 -2
- data/lib/dry/effects/effects/async.rb +3 -1
- data/lib/dry/effects/effects/cache.rb +13 -9
- data/lib/dry/effects/effects/cmp.rb +3 -1
- data/lib/dry/effects/effects/current_time.rb +4 -2
- data/lib/dry/effects/effects/defer.rb +3 -1
- data/lib/dry/effects/effects/env.rb +4 -2
- data/lib/dry/effects/effects/fork.rb +3 -1
- data/lib/dry/effects/effects/implicit.rb +4 -2
- data/lib/dry/effects/effects/interrupt.rb +4 -2
- data/lib/dry/effects/effects/lock.rb +8 -6
- data/lib/dry/effects/effects/parallel.rb +4 -2
- data/lib/dry/effects/effects/random.rb +5 -3
- data/lib/dry/effects/effects/reader.rb +1 -1
- data/lib/dry/effects/effects/resolve.rb +23 -3
- data/lib/dry/effects/effects/retry.rb +4 -2
- data/lib/dry/effects/effects/state.rb +4 -2
- data/lib/dry/effects/effects/timeout.rb +3 -1
- data/lib/dry/effects/effects/timestamp.rb +3 -1
- data/lib/dry/effects/errors.rb +4 -4
- data/lib/dry/effects/extensions/active_support/tagged_logging.rb +13 -0
- data/lib/dry/effects/extensions/auto_inject.rb +5 -5
- data/lib/dry/effects/extensions/system.rb +8 -7
- data/lib/dry/effects/extensions.rb +12 -4
- data/lib/dry/effects/frame.rb +30 -9
- data/lib/dry/effects/halt.rb +3 -3
- data/lib/dry/effects/handler.rb +1 -1
- data/lib/dry/effects/inflector.rb +1 -1
- data/lib/dry/effects/initializer.rb +17 -16
- data/lib/dry/effects/instruction.rb +1 -1
- data/lib/dry/effects/instructions/execute.rb +2 -1
- data/lib/dry/effects/instructions/raise.rb +2 -1
- data/lib/dry/effects/provider/class_interface.rb +2 -2
- data/lib/dry/effects/provider.rb +2 -2
- data/lib/dry/effects/providers/async.rb +2 -2
- data/lib/dry/effects/providers/cache.rb +2 -2
- data/lib/dry/effects/providers/cmp.rb +1 -1
- data/lib/dry/effects/providers/current_time/time_generators.rb +1 -1
- data/lib/dry/effects/providers/current_time.rb +5 -5
- data/lib/dry/effects/providers/defer.rb +6 -6
- data/lib/dry/effects/providers/env.rb +2 -2
- data/lib/dry/effects/providers/fork.rb +2 -2
- data/lib/dry/effects/providers/implicit.rb +1 -1
- data/lib/dry/effects/providers/interrupt.rb +3 -3
- data/lib/dry/effects/providers/lock.rb +6 -8
- data/lib/dry/effects/providers/parallel.rb +3 -3
- data/lib/dry/effects/providers/random.rb +74 -2
- data/lib/dry/effects/providers/reader.rb +1 -1
- data/lib/dry/effects/providers/resolve.rb +8 -7
- data/lib/dry/effects/providers/retry.rb +5 -7
- data/lib/dry/effects/providers/state.rb +2 -2
- data/lib/dry/effects/providers/timeout.rb +2 -2
- data/lib/dry/effects/providers/timestamp.rb +2 -2
- data/lib/dry/effects/stack.rb +6 -6
- data/lib/dry/effects/version.rb +1 -1
- data/lib/dry/effects.rb +7 -7
- metadata +22 -69
- data/.codeclimate.yml +0 -12
- data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
- data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -30
- data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
- data/.github/workflows/ci.yml +0 -74
- data/.github/workflows/docsite.yml +0 -34
- data/.github/workflows/sync_configs.yml +0 -34
- data/.gitignore +0 -12
- data/.rspec +0 -4
- data/.rubocop.yml +0 -95
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -23
- data/Rakefile +0 -8
- data/docsite/source/effects/cache.html.md +0 -84
- data/docsite/source/effects/current_time.html.md +0 -186
- data/docsite/source/effects/defer.html.md +0 -130
- data/docsite/source/effects/env.html.md +0 -144
- data/docsite/source/effects/interrupt.html.md +0 -109
- data/docsite/source/effects/parallel.html.md +0 -25
- data/docsite/source/effects/reader.html.md +0 -126
- data/docsite/source/effects/resolve.html.md +0 -188
- data/docsite/source/effects/state.html.md +0 -178
- data/docsite/source/effects/timeout.html.md +0 -42
- data/docsite/source/effects.html.md +0 -29
- data/docsite/source/index.html.md +0 -212
- data/examples/cmp.rb +0 -51
- data/examples/state.rb +0 -29
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/effects/effect"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Effects
|
@@ -11,6 +11,8 @@ module Dry
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def initialize(scope = :default)
|
14
|
+
super()
|
15
|
+
|
14
16
|
interrupt = InterruptEffect.new(type: :interrupt, scope: scope)
|
15
17
|
|
16
18
|
module_eval do
|
@@ -18,7 +20,7 @@ module Dry
|
|
18
20
|
if Undefined.equal?(payload)
|
19
21
|
::Dry::Effects.yield(interrupt)
|
20
22
|
else
|
21
|
-
::Dry::Effects.yield(interrupt.(payload))
|
23
|
+
::Dry::Effects.yield(interrupt.payload(payload))
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/effects/effect"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Effects
|
@@ -12,17 +12,19 @@ module Dry
|
|
12
12
|
Locked = Effect.new(type: :lock, name: :locked?)
|
13
13
|
|
14
14
|
def initialize
|
15
|
+
super
|
16
|
+
|
15
17
|
module_eval do
|
16
18
|
define_method(:lock) do |key, meta: Undefined, &block|
|
17
19
|
if block
|
18
20
|
begin
|
19
|
-
handle = ::Dry::Effects.yield(Lock.(key, meta))
|
21
|
+
handle = ::Dry::Effects.yield(Lock.payload(key, meta))
|
20
22
|
block.(!handle.nil?)
|
21
23
|
ensure
|
22
|
-
::Dry::Effects.yield(Unlock.(handle)) if handle
|
24
|
+
::Dry::Effects.yield(Unlock.payload(handle)) if handle
|
23
25
|
end
|
24
26
|
else
|
25
|
-
::Dry::Effects.yield(Lock.(key, meta))
|
27
|
+
::Dry::Effects.yield(Lock.payload(key, meta))
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
@@ -31,11 +33,11 @@ module Dry
|
|
31
33
|
end
|
32
34
|
|
33
35
|
define_method(:locked?) do |key|
|
34
|
-
::Dry::Effects.yield(Locked.(key))
|
36
|
+
::Dry::Effects.yield(Locked.payload(key))
|
35
37
|
end
|
36
38
|
|
37
39
|
define_method(:lock_meta) do |key|
|
38
|
-
::Dry::Effects.yield(Meta.(key))
|
40
|
+
::Dry::Effects.yield(Meta.payload(key))
|
39
41
|
end
|
40
42
|
end
|
41
43
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/effects/effect"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Effects
|
@@ -10,8 +10,10 @@ module Dry
|
|
10
10
|
Join = Effect.new(type: :parallel, name: :join)
|
11
11
|
|
12
12
|
def initialize
|
13
|
+
super
|
14
|
+
|
13
15
|
define_method(:par) { |&block| ::Dry::Effects.yield(Par).(&block) }
|
14
|
-
define_method(:join) { |xs| ::Dry::Effects.yield(Join.(xs)) }
|
16
|
+
define_method(:join) { |xs| ::Dry::Effects.yield(Join.payload(xs)) }
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -1,16 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/effects/effect"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Effects
|
7
7
|
module Effects
|
8
8
|
class Random < ::Module
|
9
|
-
|
9
|
+
Rand = Effect.new(type: :random, name: :rand)
|
10
10
|
|
11
11
|
def initialize
|
12
|
+
super
|
13
|
+
|
12
14
|
module_eval do
|
13
|
-
define_method(:rand) { |n| ::Dry::Effects.yield(
|
15
|
+
define_method(:rand) { |n = nil| ::Dry::Effects.yield(Rand.payload(n)) }
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -1,23 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/effects/effect"
|
4
|
+
require "dry/effects/constructors"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Effects
|
8
8
|
module Effects
|
9
9
|
class Resolve < ::Module
|
10
|
+
DependencyNameInvalid = Class.new(StandardError)
|
11
|
+
|
12
|
+
VALID_NAME = /([a-z_][a-zA-Z_0-9]*)$/.freeze
|
13
|
+
|
10
14
|
Resolve = Effect.new(type: :resolve)
|
11
15
|
|
12
16
|
Constructors.register(:Resolve) { |key| Resolve.(key) }
|
13
17
|
|
14
18
|
def initialize(*keys, **aliases)
|
19
|
+
super()
|
20
|
+
|
21
|
+
keys_aliased = keys.map { |k| name_for(k) }.zip(keys)
|
15
22
|
module_eval do
|
16
|
-
(
|
23
|
+
(keys_aliased + aliases.to_a).each do |name, key|
|
17
24
|
define_method(name) { |&block| ::Dry::Effects.yield(Resolve.(key), &block) }
|
18
25
|
end
|
19
26
|
end
|
20
27
|
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# similar approach in dry-auto_inject https://github.com/dry-rb/dry-auto_inject/blob/master/lib/dry/auto_inject/dependency_map.rb#L42
|
32
|
+
def name_for(identifier)
|
33
|
+
matched = VALID_NAME.match(identifier.to_s)
|
34
|
+
unless matched
|
35
|
+
raise DependencyNameInvalid,
|
36
|
+
"name +#{identifier}+ is not a valid Ruby identifier"
|
37
|
+
end
|
38
|
+
|
39
|
+
matched[0]
|
40
|
+
end
|
21
41
|
end
|
22
42
|
end
|
23
43
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/effects/effect"
|
4
|
+
require "dry/effects/constructors"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Effects
|
@@ -18,6 +18,8 @@ module Dry
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def initialize
|
21
|
+
super
|
22
|
+
|
21
23
|
module_eval do
|
22
24
|
define_method(:repeat) do |scope|
|
23
25
|
effect = Retry.new(type: :retry, scope: scope)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/effects/effect"
|
4
|
+
require "dry/effects/constructors"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module Effects
|
@@ -22,6 +22,8 @@ module Dry
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def initialize(scope, default: Undefined, writer: true, as: scope)
|
25
|
+
super()
|
26
|
+
|
25
27
|
read = State.new(type: :state, name: :read, scope: scope)
|
26
28
|
write = State.new(type: :state, name: :write, scope: scope)
|
27
29
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/effects/effect"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Effects
|
@@ -13,6 +13,8 @@ module Dry
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def initialize(scope)
|
16
|
+
super()
|
17
|
+
|
16
18
|
timeout = TimeoutEffect.new(type: :timeout, name: :timeout, scope: scope)
|
17
19
|
|
18
20
|
module_eval do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/effects/effect"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Effects
|
@@ -9,6 +9,8 @@ module Dry
|
|
9
9
|
Timestamp = Effect.new(type: :timestamp)
|
10
10
|
|
11
11
|
def initialize(options = EMPTY_HASH)
|
12
|
+
super()
|
13
|
+
|
12
14
|
module_eval do
|
13
15
|
define_method(:timestamp) do |round: Undefined|
|
14
16
|
round_to = Undefined.coalesce(round, options.fetch(:round, Undefined))
|
data/lib/dry/effects/errors.rb
CHANGED
@@ -20,7 +20,7 @@ module Dry
|
|
20
20
|
super(
|
21
21
|
Undefined.default(message) {
|
22
22
|
"Effect #{effect.inspect} not handled. "\
|
23
|
-
|
23
|
+
"Effects must be wrapped with corresponding handlers"
|
24
24
|
}
|
25
25
|
)
|
26
26
|
end
|
@@ -32,7 +32,7 @@ module Dry
|
|
32
32
|
class MissingStateError < UnhandledEffectError
|
33
33
|
def initialize(effect)
|
34
34
|
message = "Value of +#{effect.scope}+ is not set, "\
|
35
|
-
|
35
|
+
"you need to provide value with an effect handler"
|
36
36
|
|
37
37
|
super(effect, message)
|
38
38
|
end
|
@@ -46,8 +46,8 @@ module Dry
|
|
46
46
|
|
47
47
|
def initialize(effect)
|
48
48
|
message = "+#{effect.scope}+ is not defined, you need to assign it first "\
|
49
|
-
|
50
|
-
|
49
|
+
"by using a writer, passing initial value to the handler, or "\
|
50
|
+
"providing a fallback value"
|
51
51
|
|
52
52
|
super(message)
|
53
53
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/tagged_logging"
|
4
|
+
|
5
|
+
ActiveSupport::TaggedLogging::Formatter.prepend(Module.new {
|
6
|
+
def current_tags
|
7
|
+
thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}"
|
8
|
+
unless Thread.current.thread_variable_get(thread_key)
|
9
|
+
Thread.current.thread_variable_set(thread_key, [])
|
10
|
+
end
|
11
|
+
Thread.current.thread_variable_get(thread_key)
|
12
|
+
end
|
13
|
+
})
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "concurrent/map"
|
4
|
+
require "dry/auto_inject/strategies/constructor"
|
5
|
+
require "dry/effects/effects/resolve"
|
6
6
|
|
7
7
|
module Dry
|
8
8
|
module Effects
|
@@ -24,7 +24,7 @@ module Dry
|
|
24
24
|
class Static < Base
|
25
25
|
private
|
26
26
|
|
27
|
-
def define_readers(dynamic = false)
|
27
|
+
def define_readers(dynamic = false) # rubocop:disable Style/OptionalBooleanParameter
|
28
28
|
map = dependency_map.to_h
|
29
29
|
cache = ::Concurrent::Map.new
|
30
30
|
instance_mod.class_exec do
|
@@ -49,7 +49,7 @@ module Dry
|
|
49
49
|
class Dynamic < Static
|
50
50
|
private
|
51
51
|
|
52
|
-
def define_readers(dynamic = true)
|
52
|
+
def define_readers(dynamic = true) # rubocop:disable Style/OptionalBooleanParameter
|
53
53
|
super
|
54
54
|
end
|
55
55
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/system/container"
|
4
4
|
|
5
5
|
Dry::Effects.load_extensions(:auto_inject)
|
6
6
|
|
@@ -8,17 +8,18 @@ module Dry
|
|
8
8
|
module Effects
|
9
9
|
module System
|
10
10
|
class AutoRegistrar < ::Dry::System::AutoRegistrar
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
# Always memoize and freeze registered components
|
12
|
+
def call(component_dir)
|
13
|
+
components(component_dir).each do |component|
|
14
|
+
next unless register_component?(component)
|
15
|
+
|
16
|
+
container.register(component.key, memoize: true) { component.instance.freeze }
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
21
|
class Container < ::Dry::System::Container
|
21
|
-
|
22
|
+
config.auto_registrar = AutoRegistrar
|
22
23
|
|
23
24
|
def self.injector(effects: true, **kwargs)
|
24
25
|
if effects
|
@@ -1,17 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/core/extensions"
|
4
4
|
|
5
5
|
Dry::Effects.extend(Dry::Core::Extensions)
|
6
6
|
|
7
7
|
Dry::Effects.register_extension(:auto_inject) do
|
8
|
-
require
|
8
|
+
require "dry/effects/extensions/auto_inject"
|
9
9
|
end
|
10
10
|
|
11
11
|
Dry::Effects.register_extension(:system) do
|
12
|
-
require
|
12
|
+
require "dry/effects/extensions/system"
|
13
13
|
end
|
14
14
|
|
15
15
|
Dry::Effects.register_extension(:rspec) do
|
16
|
-
require
|
16
|
+
require "dry/effects/extensions/rspec"
|
17
|
+
end
|
18
|
+
|
19
|
+
Dry::Effects.register_extension(:active_support_tagged_logging) do
|
20
|
+
require "dry/effects/extensions/active_support/tagged_logging"
|
21
|
+
end
|
22
|
+
|
23
|
+
Dry::Effects.register_extension(:active_support) do
|
24
|
+
Dry::Effects.load_extensions(:active_support_tagged_logging)
|
17
25
|
end
|
data/lib/dry/effects/frame.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
3
|
+
require "fiber"
|
4
|
+
require "dry/effects/initializer"
|
5
|
+
require "dry/effects/effect"
|
6
|
+
require "dry/effects/errors"
|
7
|
+
require "dry/effects/stack"
|
8
|
+
require "dry/effects/instructions/raise"
|
9
9
|
|
10
10
|
module Dry
|
11
11
|
module Effects
|
@@ -41,15 +41,36 @@ module Dry
|
|
41
41
|
result = fiber.resume
|
42
42
|
|
43
43
|
loop do
|
44
|
+
error = false
|
44
45
|
break result unless fiber.alive?
|
45
46
|
|
46
47
|
provided = stack.(result) do
|
47
|
-
::Dry::Effects.yield(result) do |_,
|
48
|
-
|
48
|
+
::Dry::Effects.yield(result) do |_, e|
|
49
|
+
error = true
|
50
|
+
e
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
52
|
-
result =
|
54
|
+
result =
|
55
|
+
if error
|
56
|
+
raise_in_fiber(fiber, provided)
|
57
|
+
else
|
58
|
+
fiber.resume(provided)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
if RUBY_VERSION >= "2.7"
|
66
|
+
# @api private
|
67
|
+
def raise_in_fiber(fiber, error)
|
68
|
+
fiber.raise(error)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
# @api private
|
72
|
+
def raise_in_fiber(fiber, error)
|
73
|
+
fiber.resume(Instructions.Raise(error))
|
53
74
|
end
|
54
75
|
end
|
55
76
|
end
|
data/lib/dry/effects/halt.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "concurrent/map"
|
4
|
+
require "dry/core/class_attributes"
|
5
|
+
require "dry/effects/inflector"
|
6
6
|
|
7
7
|
module Dry
|
8
8
|
module Effects
|