grumlin 0.22.4 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.rubocop.yml +9 -9
- data/Gemfile.lock +10 -8
- data/README.md +102 -141
- data/Rakefile +1 -1
- data/bin/console +18 -3
- data/doc/middlewares.md +97 -0
- data/grumlin.gemspec +1 -0
- data/lib/async/channel.rb +54 -56
- data/lib/grumlin/benchmark/repository.rb +10 -14
- data/lib/grumlin/client.rb +92 -112
- data/lib/grumlin/config.rb +30 -15
- data/lib/grumlin/dummy_transaction.rb +13 -15
- data/lib/grumlin/edge.rb +18 -20
- data/lib/grumlin/expressions/cardinality.rb +5 -9
- data/lib/grumlin/expressions/column.rb +5 -9
- data/lib/grumlin/expressions/expression.rb +7 -11
- data/lib/grumlin/expressions/operator.rb +5 -9
- data/lib/grumlin/expressions/order.rb +5 -9
- data/lib/grumlin/expressions/p.rb +27 -31
- data/lib/grumlin/expressions/pop.rb +5 -9
- data/lib/grumlin/expressions/scope.rb +5 -9
- data/lib/grumlin/expressions/t.rb +5 -9
- data/lib/grumlin/expressions/text_p.rb +5 -9
- data/lib/grumlin/expressions/with_options.rb +17 -21
- data/lib/grumlin/features/feature_list.rb +8 -12
- data/lib/grumlin/features/neptune_features.rb +5 -9
- data/lib/grumlin/features/tinkergraph_features.rb +5 -9
- data/lib/grumlin/features.rb +8 -10
- data/lib/grumlin/middlewares/apply_shortcuts.rb +8 -0
- data/lib/grumlin/middlewares/build_query.rb +20 -0
- data/lib/grumlin/middlewares/builder.rb +15 -0
- data/lib/grumlin/middlewares/cast_results.rb +7 -0
- data/lib/grumlin/middlewares/find_blocklisted_steps.rb +14 -0
- data/lib/grumlin/middlewares/find_mutating_steps.rb +9 -0
- data/lib/grumlin/middlewares/middleware.rb +11 -0
- data/lib/grumlin/middlewares/run_query.rb +7 -0
- data/lib/grumlin/middlewares/serialize_to_bytecode.rb +9 -0
- data/lib/grumlin/middlewares/serialize_to_steps.rb +8 -0
- data/lib/grumlin/path.rb +11 -13
- data/lib/grumlin/property.rb +14 -16
- data/lib/grumlin/query_validators/blocklisted_steps_validator.rb +22 -0
- data/lib/grumlin/query_validators/validator.rb +36 -0
- data/lib/grumlin/repository/error_handling_strategy.rb +36 -40
- data/lib/grumlin/repository/instance_methods.rb +115 -118
- data/lib/grumlin/repository.rb +82 -58
- data/lib/grumlin/request_dispatcher.rb +55 -57
- data/lib/grumlin/request_error_factory.rb +53 -55
- data/lib/grumlin/shortcut.rb +19 -21
- data/lib/grumlin/shortcuts/properties.rb +12 -16
- data/lib/grumlin/shortcuts/storage.rb +67 -74
- data/lib/grumlin/shortcuts/upserts.rb +18 -22
- data/lib/grumlin/shortcuts.rb +23 -25
- data/lib/grumlin/shortcuts_applyer.rb +27 -29
- data/lib/grumlin/step.rb +92 -0
- data/lib/grumlin/step_data.rb +12 -14
- data/lib/grumlin/steppable.rb +24 -22
- data/lib/grumlin/steps.rb +51 -54
- data/lib/grumlin/steps_serializers/bytecode.rb +53 -56
- data/lib/grumlin/steps_serializers/human_readable_bytecode.rb +17 -21
- data/lib/grumlin/steps_serializers/serializer.rb +7 -11
- data/lib/grumlin/steps_serializers/string.rb +26 -30
- data/lib/grumlin/test/rspec/db_cleaner_context.rb +8 -12
- data/lib/grumlin/test/rspec/gremlin_context.rb +18 -16
- data/lib/grumlin/test/rspec.rb +1 -5
- data/lib/grumlin/transaction.rb +26 -27
- data/lib/grumlin/transport.rb +71 -73
- data/lib/grumlin/traversal_start.rb +31 -33
- data/lib/grumlin/traversal_strategies/options_strategy.rb +3 -7
- data/lib/grumlin/traverser.rb +5 -7
- data/lib/grumlin/typed_value.rb +11 -13
- data/lib/grumlin/typing.rb +70 -72
- data/lib/grumlin/version.rb +1 -1
- data/lib/grumlin/vertex.rb +14 -16
- data/lib/grumlin/vertex_property.rb +14 -16
- data/lib/grumlin/with_extension.rb +17 -19
- data/lib/grumlin.rb +23 -19
- metadata +32 -6
- data/lib/grumlin/action.rb +0 -92
- data/lib/grumlin/sugar.rb +0 -15
@@ -1,39 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
class Predicate
|
7
|
-
attr_reader :namespace, :name, :value, :type
|
3
|
+
class Grumlin::Expressions::P
|
4
|
+
class Predicate
|
5
|
+
attr_reader :namespace, :name, :value, :type
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
def initialize(namespace, name, value:, type: nil)
|
8
|
+
@namespace = namespace
|
9
|
+
@name = name
|
10
|
+
@value = value
|
11
|
+
@type = type
|
12
|
+
end
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
class << self
|
16
|
+
# TODO: support more predicates
|
17
|
+
[:eq, :gt, :lt, :neq].each do |predicate|
|
18
|
+
define_method predicate do |*args|
|
19
|
+
Predicate.new("P", predicate, value: args[0])
|
20
|
+
end
|
21
|
+
end
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
23
|
+
[:within, :without].each do |predicate|
|
24
|
+
define_method predicate do |*args|
|
25
|
+
args = if args.count == 1 && args[0].is_a?(Array)
|
26
|
+
args[0]
|
27
|
+
elsif args.count == 1 && args[0].is_a?(Set)
|
28
|
+
args[0].to_a
|
29
|
+
else
|
30
|
+
args.to_a
|
31
|
+
end
|
32
|
+
Predicate.new("P", predicate, value: args, type: "List")
|
37
33
|
end
|
38
34
|
end
|
39
35
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
module Pop
|
6
|
-
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :pop).map(&:to_sym).freeze
|
3
|
+
module Grumlin::Expressions::Pop
|
4
|
+
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :pop).map(&:to_sym).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
extend Grumlin::Expressions::Expression
|
10
8
|
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
9
|
+
define_steps(SUPPORTED_STEPS, "Pop")
|
14
10
|
end
|
15
11
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
module Scope
|
6
|
-
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :scope).map(&:to_sym).freeze
|
3
|
+
module Grumlin::Expressions::Scope
|
4
|
+
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :scope).map(&:to_sym).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
extend Grumlin::Expressions::Expression
|
10
8
|
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
9
|
+
define_steps(SUPPORTED_STEPS, "Scope")
|
14
10
|
end
|
15
11
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
module T
|
6
|
-
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :t).map(&:to_sym).freeze
|
3
|
+
module Grumlin::Expressions::T
|
4
|
+
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :t).map(&:to_sym).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
extend Grumlin::Expressions::Expression
|
10
8
|
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
9
|
+
define_steps(SUPPORTED_STEPS, "T")
|
14
10
|
end
|
15
11
|
end
|
@@ -1,14 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
define_method predicate do |*args|
|
9
|
-
P::Predicate.new("TextP", predicate, value: args[0])
|
10
|
-
end
|
11
|
-
end
|
3
|
+
class Grumlin::Expressions::TextP < Grumlin::Expressions::P
|
4
|
+
class << self
|
5
|
+
[:containing, :endingWith, :notContaining, :notEndingWith, :notStartingWith, :startingWith].each do |predicate|
|
6
|
+
define_method predicate do |*args|
|
7
|
+
P::Predicate.new("TextP", predicate, value: args[0])
|
12
8
|
end
|
13
9
|
end
|
14
10
|
end
|
@@ -1,31 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
class WithOptions
|
6
|
-
WITH_OPTIONS = Grumlin.definitions.dig(:expressions, :with_options).freeze
|
3
|
+
class Grumlin::Expressions::WithOptions
|
4
|
+
WITH_OPTIONS = Grumlin.definitions.dig(:expressions, :with_options).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
class << self
|
7
|
+
WITH_OPTIONS.each do |k, v|
|
8
|
+
define_method k do
|
9
|
+
name = "@#{k}"
|
10
|
+
return instance_variable_get(name) if instance_variable_defined?(name)
|
13
11
|
|
14
|
-
|
15
|
-
end
|
16
|
-
end
|
12
|
+
instance_variable_set(name, WithOptions.new(k, v))
|
17
13
|
end
|
14
|
+
end
|
15
|
+
end
|
18
16
|
|
19
|
-
|
17
|
+
attr_reader :name, :value
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
def initialize(name, value)
|
20
|
+
@name = name
|
21
|
+
@value = value
|
22
|
+
end
|
25
23
|
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
24
|
+
def to_s
|
25
|
+
"WithOptions.#{@name}"
|
30
26
|
end
|
31
27
|
end
|
@@ -1,19 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
def user_supplied_ids?
|
7
|
-
raise(NotImplementedError) if @user_supplied_ids.nil?
|
3
|
+
class Grumlin::Features::FeatureList
|
4
|
+
def user_supplied_ids?
|
5
|
+
raise(NotImplementedError) if @user_supplied_ids.nil?
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
@user_supplied_ids
|
8
|
+
end
|
11
9
|
|
12
|
-
|
13
|
-
|
10
|
+
def supports_transactions?
|
11
|
+
raise(NotImplementedError) if @supports_transactions.nil?
|
14
12
|
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
13
|
+
@supports_transactions
|
18
14
|
end
|
19
15
|
end
|
@@ -1,13 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@user_supplied_ids = true
|
9
|
-
@supports_transactions = true
|
10
|
-
end
|
11
|
-
end
|
3
|
+
class Grumlin::Features::NeptuneFeatures < Grumlin::Features::FeatureList
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
@user_supplied_ids = true
|
7
|
+
@supports_transactions = true
|
12
8
|
end
|
13
9
|
end
|
@@ -1,13 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@user_supplied_ids = true
|
9
|
-
@supports_transactions = false
|
10
|
-
end
|
11
|
-
end
|
3
|
+
class Grumlin::Features::TinkergraphFeatures < Grumlin::Features::FeatureList
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
@user_supplied_ids = true
|
7
|
+
@supports_transactions = false
|
12
8
|
end
|
13
9
|
end
|
data/lib/grumlin/features.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
}.freeze
|
3
|
+
module Grumlin::Features
|
4
|
+
class << self
|
5
|
+
FEATURES = {
|
6
|
+
neptune: NeptuneFeatures.new,
|
7
|
+
tinkergraph: TinkergraphFeatures.new
|
8
|
+
}.freeze
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
end
|
10
|
+
def for(provider)
|
11
|
+
FEATURES[provider]
|
14
12
|
end
|
15
13
|
end
|
16
14
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Grumlin::Middlewares::BuildQuery < Grumlin::Middlewares::Middleware
|
4
|
+
def call(env)
|
5
|
+
env[:query] = {
|
6
|
+
requestId: SecureRandom.uuid,
|
7
|
+
op: :bytecode,
|
8
|
+
processor: env[:session_id] ? :session : :traversal,
|
9
|
+
args: {
|
10
|
+
gremlin: {
|
11
|
+
:@type => "g:Bytecode",
|
12
|
+
:@value => env[:bytecode]
|
13
|
+
},
|
14
|
+
aliases: { g: :g },
|
15
|
+
session: env[:session_id]
|
16
|
+
}.compact
|
17
|
+
}
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Grumlin::Middlewares::Builder < ::Middleware::Builder
|
4
|
+
def similar?(other)
|
5
|
+
stack == other.stack
|
6
|
+
end
|
7
|
+
|
8
|
+
def include?(middleware)
|
9
|
+
stack.any? { |m| m.first == middleware }
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_app
|
13
|
+
@to_app ||= super
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Grumlin::Middlewares::FindBlocklistedSteps < Grumlin::Middlewares::Middleware
|
4
|
+
def initialize(app, *steps)
|
5
|
+
super(app)
|
6
|
+
@validator = Grumlin::QueryValidators::BlocklistedStepsValidator.new(*steps)
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
@validator.validate!(env[:steps_without_shortcuts])
|
11
|
+
@app.call(env)
|
12
|
+
env[:parsed_results] = @app.call(env).flat_map { |item| Grumlin::Typing.cast(item) }
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Grumlin::Middlewares::SerializeToBytecode < Grumlin::Middlewares::Middleware
|
4
|
+
def call(env)
|
5
|
+
env[:bytecode] = Grumlin::StepsSerializers::Bytecode.new(env[:steps_without_shortcuts],
|
6
|
+
no_return: !env[:need_results]).serialize
|
7
|
+
@app.call(env)
|
8
|
+
end
|
9
|
+
end
|
data/lib/grumlin/path.rb
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
attr_reader :objects
|
3
|
+
class Grumlin::Path
|
4
|
+
attr_reader :objects
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
def initialize(path)
|
7
|
+
@labels = Grumlin::Typing.cast(path[:labels])
|
8
|
+
@objects = Grumlin::Typing.cast(path[:objects])
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def inspect
|
12
|
+
"p[#{@objects}]"
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
end
|
15
|
+
def to_s
|
16
|
+
inspect
|
19
17
|
end
|
20
18
|
end
|
data/lib/grumlin/property.rb
CHANGED
@@ -1,24 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
attr_reader :key, :value
|
3
|
+
class Grumlin::Property
|
4
|
+
attr_reader :key, :value
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
def initialize(value)
|
7
|
+
@key = value[:key]
|
8
|
+
@value = Grumlin::Typing.cast(value[:value])
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def inspect
|
12
|
+
"p[#{key}->#{value}]"
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
def to_s
|
16
|
+
inspect
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
19
|
+
def ==(other)
|
20
|
+
self.class == other.class && @key == other.key && @value == other.value
|
23
21
|
end
|
24
22
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Grumlin::QueryValidators::BlocklistedStepsValidator < Grumlin::QueryValidators::Validator
|
4
|
+
def initialize(*names)
|
5
|
+
super()
|
6
|
+
@names = names.to_set
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def validate(steps, errors)
|
12
|
+
(steps.configuration_steps + steps.steps).each do |step|
|
13
|
+
if @names.include?(step.name)
|
14
|
+
errors[:blocklisted_steps] ||= []
|
15
|
+
errors[:blocklisted_steps] << step.name
|
16
|
+
end
|
17
|
+
step.args.each do |arg|
|
18
|
+
validate(arg, errors) if arg.is_a?(Grumlin::Steps)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Grumlin::QueryValidators::Validator
|
4
|
+
class ValidationError < Grumlin::Error
|
5
|
+
attr_reader :errors, :steps
|
6
|
+
|
7
|
+
def initialize(steps, errors)
|
8
|
+
super("Query is invalid: #{errors}")
|
9
|
+
@steps = steps
|
10
|
+
@errors = errors
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# steps is an instance of `Steps` after shortcuts applied
|
15
|
+
def validate!(steps)
|
16
|
+
return unless (err = errors(steps)).any?
|
17
|
+
|
18
|
+
raise ValidationError.new(steps, err)
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid?(steps)
|
22
|
+
errors(steps).empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def errors(steps)
|
28
|
+
{}.tap do |errors|
|
29
|
+
validate(steps, errors)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate(steps, errors)
|
34
|
+
raise NotImplementedError
|
35
|
+
end
|
36
|
+
end
|
@@ -1,44 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
def retry_errors!(&block)
|
40
|
-
Retryable.retryable(**@params, &block)
|
41
|
-
end
|
42
|
-
end
|
3
|
+
class Grumlin::Repository::ErrorHandlingStrategy
|
4
|
+
def initialize(mode: :retry, **params)
|
5
|
+
@mode = mode
|
6
|
+
@params = params
|
7
|
+
@on_exceptions = params[:on]
|
8
|
+
end
|
9
|
+
|
10
|
+
def raise?
|
11
|
+
@mode == :raise
|
12
|
+
end
|
13
|
+
|
14
|
+
def ignore?
|
15
|
+
@mode == :ignore
|
16
|
+
end
|
17
|
+
|
18
|
+
def retry?
|
19
|
+
@mode == :retry
|
20
|
+
end
|
21
|
+
|
22
|
+
def apply!(&block)
|
23
|
+
return yield if raise?
|
24
|
+
return ignore_errors!(&block) if ignore?
|
25
|
+
|
26
|
+
retry_errors!(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def ignore_errors!
|
32
|
+
yield
|
33
|
+
rescue *@on_exceptions
|
34
|
+
# ignore errors
|
35
|
+
end
|
36
|
+
|
37
|
+
def retry_errors!(&block)
|
38
|
+
Retryable.retryable(**@params, &block)
|
43
39
|
end
|
44
40
|
end
|