lyber-core 7.5.0 → 7.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e631494dfd0e92ddb58b8a92f9414d6ab8b3861d7cb831dc0a2166cc0a097e1
4
- data.tar.gz: c0177b4b844a61a15eed8ab50ab16264dd28faecd13eaa15c0afaadab05d256a
3
+ metadata.gz: 06b40bbb06d992835959637eaab8a0319a8ea093cc9b8c883b39a6a0df6a1e70
4
+ data.tar.gz: d2ca21bec9e898cf98f72db0c21637d6f33fd48bc8e69fcc571d9b621679e802
5
5
  SHA512:
6
- metadata.gz: 1197fbc8f99343df897746a9289e1eeabf56e80d43d7a37ff861fb5997fe8a57774ca7149b34f12ad38b4172a7f1f9fc891e85b9fbbdba84a7f02b236ef2ba8d
7
- data.tar.gz: 32d345176540a0e35bed7f41309cb481ead4e0d40d7d068ed4b9b3ce20610cb5258d89201f4f228e0d01eb2c0578140525a170ccea60a20b2fb85d61e17c8328
6
+ metadata.gz: 796bb15551fa5bd9995237781b73dd78ff81ea0d9db36afa92ad7ebd4aa56a2552cc436d5759ca4d9c95ce66fb3a6e4cef3098ef3ec227e2430ddd93517999d0
7
+ data.tar.gz: a84a27a79cc73bd1e368352eae2a4412acc35d9d7951db5c61cfcf2e61b1760e641a7c8d7529acc5805df79d2a78830f35f91bc919fdcd18f332ea2302893b79
data/README.md CHANGED
@@ -26,9 +26,7 @@ module Robots
26
26
  def perform_work
27
27
  cocina_object.shelve
28
28
  end
29
-
30
29
  end
31
-
32
30
  end
33
31
  end
34
32
  end
@@ -59,9 +57,27 @@ module Robots
59
57
  # return LyberCore::ReturnState.new(status: 'skipped', note: 'some custom note to pass back to workflow') # set the final state to skipped with a custom note
60
58
  end
61
59
  end
62
-
63
60
  end
61
+ end
62
+ end
63
+ end
64
+ ```
65
+
66
+ By default, a robot will not retry. To enable retries for specific errors:
67
+ ```ruby
68
+ module Robots
69
+ module DorRepo
70
+ module Accession
71
+
72
+ class Shelve < LyberCore::Robot
73
+ def initialize
74
+ super('accessionWF', 'shelve', retriable_exceptions: [Dor::Services::Client::Error])
75
+ end
64
76
 
77
+ def perform_work
78
+ cocina_object.shelve
79
+ end
80
+ end
65
81
  end
66
82
  end
67
83
  end
@@ -3,19 +3,32 @@
3
3
  module LyberCore
4
4
  # Base class for all robots.
5
5
  # Subclasses should implement the #perform_work method.
6
+ # To enable retries provide the retriable exceptions in the initializer.
6
7
  class Robot
7
8
  include Sidekiq::Job
8
- sidekiq_options retry: 0
9
+ # Setting sidekiq_options here won't work.
10
+ # Instead pass options when enqueueing the job with Sidekiq::Client.push. (Currently in Workflow's QueueService.)
11
+
12
+ sidekiq_retries_exhausted do |job, ex|
13
+ # When all the retries are exhausted, update the workflow to error.
14
+ robot = job['class'].constantize.new
15
+ workflow = Workflow.new(workflow_service: WorkflowClientFactory.build,
16
+ druid: job['args'].first,
17
+ workflow_name: robot.workflow_name,
18
+ process: robot.process)
19
+ workflow.error!(ex.message, Socket.gethostname)
20
+ end
9
21
 
10
- attr_reader :workflow_name, :process, :druid
22
+ attr_reader :workflow_name, :process, :druid, :retriable_exceptions
11
23
  attr_accessor :check_queued_status
12
24
 
13
25
  delegate :lane_id, to: :workflow
14
26
 
15
- def initialize(workflow_name, process, check_queued_status: true)
27
+ def initialize(workflow_name, process, check_queued_status: true, retriable_exceptions: [])
16
28
  @workflow_name = workflow_name
17
29
  @process = process
18
30
  @check_queued_status = check_queued_status
31
+ @retriable_exceptions = retriable_exceptions
19
32
  end
20
33
 
21
34
  def workflow_service
@@ -43,7 +56,7 @@ module LyberCore
43
56
  Honeybadger.context(druid:, process:, workflow_name:)
44
57
 
45
58
  logger.info "#{druid} processing #{process} (#{workflow_name})"
46
- return unless check_item_queued?
59
+ return unless check_item_queued_or_retry?
47
60
 
48
61
  # this is the default note to pass back to workflow service,
49
62
  # but it can be overriden by a robot that uses the Robots::ReturnState
@@ -73,8 +86,13 @@ module LyberCore
73
86
  workflow.complete!(workflow_state, elapsed, note) unless workflow_state == 'noop'
74
87
 
75
88
  logger.info "Finished #{druid} in #{format('%0.4f', elapsed)}s"
89
+ rescue *retriable_exceptions => e
90
+ handle_error(e)
91
+ workflow.retrying!
92
+ raise
76
93
  rescue StandardError => e
77
94
  handle_error(e)
95
+ workflow.error!(e.message, Socket.gethostname)
78
96
  end
79
97
  # rubocop:enable Metrics/AbcSize
80
98
  # rubocop:enable Metrics/MethodLength
@@ -91,16 +109,10 @@ module LyberCore
91
109
 
92
110
  private
93
111
 
94
- # rubocop:disable Metrics/AbcSize
95
112
  def handle_error(error)
96
113
  Honeybadger.notify(error)
97
114
  logger.error "#{error.message}\n#{error.backtrace.join("\n")}"
98
- workflow.error!(error.message, Socket.gethostname)
99
- rescue StandardError => e
100
- logger.error "Cannot set #{druid} to status='error'\n#{e.message}\n#{e.backtrace.join("\n")}"
101
- raise e # send exception to Sidekiq failed queue
102
115
  end
103
- # rubocop:enable Metrics/AbcSize
104
116
 
105
117
  def workflow
106
118
  @workflow ||= Workflow.new(workflow_service:,
@@ -109,10 +121,11 @@ module LyberCore
109
121
  process:)
110
122
  end
111
123
 
112
- def check_item_queued?
124
+ def check_item_queued_or_retry?
113
125
  return true unless check_queued_status
114
126
 
115
127
  return true if /queued/i.match?(workflow.status)
128
+ return true if /retrying/i.match?(workflow.status)
116
129
 
117
130
  msg = "Item #{druid} is not queued for #{process} (#{workflow_name}), " \
118
131
  "but has status of '#{workflow.status}'. Will skip processing"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LyberCore
4
- VERSION = '7.5.0'
4
+ VERSION = '7.7.0'
5
5
  end
@@ -28,6 +28,15 @@ module LyberCore
28
28
  note:)
29
29
  end
30
30
 
31
+ def retrying!
32
+ workflow_service.update_status(druid:,
33
+ workflow: workflow_name,
34
+ process:,
35
+ status: 'retrying',
36
+ elapsed: 1.0,
37
+ note: nil)
38
+ end
39
+
31
40
  def error!(error_msg, error_text)
32
41
  workflow_service.update_error_status(druid:,
33
42
  workflow: workflow_name,
@@ -3,7 +3,7 @@
3
3
  module LyberCore
4
4
  # Factory for creating a workflow client
5
5
  class WorkflowClientFactory
6
- def self.build(logger:)
6
+ def self.build(logger: Sidekiq.logger)
7
7
  Dor::Workflow::Client.new(url: Settings.workflow.url, logger:, timeout: Settings.workflow.timeout)
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lyber-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.5.0
4
+ version: 7.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alpana Pande
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
- date: 2024-05-06 00:00:00.000000000 Z
19
+ date: 2024-10-31 00:00:00.000000000 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: activesupport
@@ -50,30 +50,30 @@ dependencies:
50
50
  name: dor-services-client
51
51
  requirement: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - "~>"
53
+ - - ">="
54
54
  - !ruby/object:Gem::Version
55
- version: '14.0'
55
+ version: '0'
56
56
  type: :runtime
57
57
  prerelease: false
58
58
  version_requirements: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - "~>"
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
- version: '14.0'
62
+ version: '0'
63
63
  - !ruby/object:Gem::Dependency
64
64
  name: dor-workflow-client
65
65
  requirement: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: '7.4'
69
+ version: '7.6'
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - ">="
75
75
  - !ruby/object:Gem::Version
76
- version: '7.4'
76
+ version: '7.6'
77
77
  - !ruby/object:Gem::Dependency
78
78
  name: druid-tools
79
79
  requirement: !ruby/object:Gem::Requirement
@@ -172,6 +172,34 @@ dependencies:
172
172
  - - "~>"
173
173
  - !ruby/object:Gem::Version
174
174
  version: '1.24'
175
+ - !ruby/object:Gem::Dependency
176
+ name: rubocop-capybara
177
+ requirement: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ - !ruby/object:Gem::Dependency
190
+ name: rubocop-factory_bot
191
+ requirement: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ type: :development
197
+ prerelease: false
198
+ version_requirements: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
175
203
  - !ruby/object:Gem::Dependency
176
204
  name: rubocop-rspec
177
205
  requirement: !ruby/object:Gem::Requirement
@@ -186,6 +214,20 @@ dependencies:
186
214
  - - ">="
187
215
  - !ruby/object:Gem::Version
188
216
  version: '0'
217
+ - !ruby/object:Gem::Dependency
218
+ name: rubocop-rspec_rails
219
+ requirement: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
224
+ type: :development
225
+ prerelease: false
226
+ version_requirements: !ruby/object:Gem::Requirement
227
+ requirements:
228
+ - - ">="
229
+ - !ruby/object:Gem::Version
230
+ version: '0'
189
231
  - !ruby/object:Gem::Dependency
190
232
  name: simplecov
191
233
  requirement: !ruby/object:Gem::Requirement
@@ -223,7 +265,8 @@ files:
223
265
  homepage: http://github.com/sul-dlss/lyber-core
224
266
  licenses:
225
267
  - Apache-2.0
226
- metadata: {}
268
+ metadata:
269
+ rubygems_mfa_required: 'true'
227
270
  post_install_message:
228
271
  rdoc_options: []
229
272
  require_paths:
@@ -239,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
239
282
  - !ruby/object:Gem::Version
240
283
  version: 1.3.6
241
284
  requirements: []
242
- rubygems_version: 3.5.9
285
+ rubygems_version: 3.5.11
243
286
  signing_key:
244
287
  specification_version: 4
245
288
  summary: Core services used by the SUL Digital Library