DEV: Follow-up to the lock step for services

This patch adds two things:

1. An outcome matcher (`on_lock_not_acquired`), allowing to react when
   there was a problem with the lock.
2. Compatibility with the steps inspector, allowing to display properly
   the steps of a service containing locks.
This commit is contained in:
Loïc Guitaut
2025-01-31 16:38:24 +01:00
committed by Loïc Guitaut
parent 997a9e3de9
commit f057c71fc8
5 changed files with 140 additions and 95 deletions

View File

@ -265,10 +265,11 @@ module Service
class LockStep < Step
include StepsHelpers
attr_reader :steps
attr_reader :steps, :keys
def initialize(*keys, &block)
@keys = keys
@name = keys.join(":")
@steps = []
instance_exec(&block)
end
@ -290,10 +291,12 @@ module Service
end
end
private
def lock_name
[
context.__service_class__.to_s.underscore,
*@keys.flat_map { |key| [key, context[:params].send(key)] },
*keys.flat_map { |key| [key, context[:params].public_send(key)] },
].join(":")
end
end

View File

@ -25,6 +25,8 @@
# * +on_exceptions(*exceptions)+: will execute the provided block if any
# exceptions were caught by the `try` block. One or more exception classes
# can be provided to specifically handle those exceptions.
# * +on_lock_not_acquired(*keys)+: will execute the provided block if the lock
# using `keys` wasn’t acquired successfully.
#
# All the specialized steps receive the failing step result object as an
# argument to their block. `on_model_errors` receives the actual model so it’s
@ -105,6 +107,10 @@ class Service::Runner
name: "default",
property: :exception,
},
on_lock_not_acquired: {
condition: ->(*keys) { failure_for?("result.lock.#{keys.join(":")}") },
key: [],
},
}.with_indifferent_access.freeze
# @!visibility private

View File

@ -123,6 +123,17 @@ class Service::StepsInspector
end
end
# @!visibility private
class Lock < Transaction
def inspect
"#{" " * nesting_level}[#{inspect_type}] #{name}#{runtime} #{emoji}".rstrip
end
def error
"Lock '#{name}' was not acquired."
end
end
attr_reader :steps, :result
def initialize(result)