atlas_rb 1.10.0 → 1.10.1
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/.version +1 -1
- data/CHANGELOG.md +40 -0
- data/Gemfile.lock +1 -1
- data/README.md +22 -0
- data/lib/atlas_rb/work.rb +93 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d8edc13167cb16fb5482d6a5cd19760bf323f67bf1a23f00a9508f8320bf798
|
|
4
|
+
data.tar.gz: e86459ce460b8eb30cffcfaaed75b06c750649aa57559e33d5ea277ce0bd2d8c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 06a66bf273c655ae075c821d158555139094714e3b5d0f3ca15296657afe067267ef781190c4804d5a97d3576237a11d664141f28256702df4151fefde515255
|
|
7
|
+
data.tar.gz: dfd113525542142a75e0789a5e9ed34424485e1ac69359f5e4c505e24d3752e9eda54e756804f13f195588f6079d0c828426e0a5b937d8ad53c2ef8708eaff00
|
data/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.10.
|
|
1
|
+
1.10.1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.10.1
|
|
4
|
+
|
|
5
|
+
### Added — `Work.mark_incomplete` / `Work.clear_incomplete`
|
|
6
|
+
|
|
7
|
+
A Work can now carry a second lifecycle state. `complete` says the deposit
|
|
8
|
+
finished; `incomplete` says something downstream of it gave up. Before this
|
|
9
|
+
there was no way to record that at all: every give-up handler wrote a
|
|
10
|
+
`Rails.logger.warn` and nothing else, so a deposit whose PDF rendition
|
|
11
|
+
exhausted its retries ended up with no rendition and no thumbnail, the
|
|
12
|
+
depositor was not told, and no surface listed it.
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
AtlasRb::Work.mark_incomplete(work_id, reason: "pdf_rendition_gave_up")
|
|
16
|
+
AtlasRb::Work.clear_incomplete(work_id)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`reason` is a machine token, one per give-up handler. Atlas holds it as an
|
|
20
|
+
opaque string and does **not** validate it against a list, so the vocabulary
|
|
21
|
+
belongs to the caller and a new token needs no Atlas release. Map it to display
|
|
22
|
+
text at the point of use, with a fallback for a token the view has not been
|
|
23
|
+
taught.
|
|
24
|
+
|
|
25
|
+
The flag **never hides** the Work. A record with its file, title and metadata
|
|
26
|
+
but one missing derivative is degraded, not broken, and stays readable.
|
|
27
|
+
|
|
28
|
+
Both bindings return the updated Work. `mark_incomplete` is idempotent and the
|
|
29
|
+
last reason wins; `clear_incomplete` is idempotent too, and clears the flag and
|
|
30
|
+
the reason together. Call it when a later run of the same job succeeds, which
|
|
31
|
+
makes the state self-healing.
|
|
32
|
+
|
|
33
|
+
### Added — `incomplete:` filter on `Work.list`
|
|
34
|
+
|
|
35
|
+
`AtlasRb::Work.list(incomplete: true)` is the staff list of Works whose
|
|
36
|
+
pipeline gave up, the sibling of the existing `in_progress:` "what's stuck?"
|
|
37
|
+
view. The two are independent and combine: `in_progress: false, incomplete:
|
|
38
|
+
true` reads as "finished, but degraded".
|
|
39
|
+
|
|
40
|
+
Work summaries in the response now carry `incomplete` and `incomplete_reason`
|
|
41
|
+
alongside `in_progress`.
|
|
42
|
+
|
|
3
43
|
## 1.10.0
|
|
4
44
|
|
|
5
45
|
### Removed — `title` on `Person.create` and `Person.update`
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -255,6 +255,28 @@ AtlasRb::Work.list(in_progress: false, page: 2) # completed deposits, page 2
|
|
|
255
255
|
AtlasRb::Work.complete("w-789") # mark w-789 done
|
|
256
256
|
```
|
|
257
257
|
|
|
258
|
+
A Work carries a second, independent lifecycle state for the other kind of
|
|
259
|
+
failure. `complete` says the deposit finished; `incomplete` says something
|
|
260
|
+
downstream of it gave up — a rendition, the derivatives, the full-text
|
|
261
|
+
extraction — after that job exhausted its retries. Call `mark_incomplete`
|
|
262
|
+
from the give-up handler, and `clear_incomplete` when a later run succeeds,
|
|
263
|
+
which makes the state self-healing.
|
|
264
|
+
|
|
265
|
+
```ruby
|
|
266
|
+
AtlasRb::Work.mark_incomplete("w-789", reason: "pdf_rendition_gave_up")
|
|
267
|
+
AtlasRb::Work.clear_incomplete("w-789")
|
|
268
|
+
AtlasRb::Work.list(incomplete: true) # the staff repair list
|
|
269
|
+
AtlasRb::Work.list(in_progress: false, incomplete: true) # finished, but degraded
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`reason` is a machine token, one per give-up handler. Atlas stores it as an
|
|
273
|
+
opaque string and does not validate it against a list, so the vocabulary is
|
|
274
|
+
yours and a new token needs no Atlas release. Map it to display text at the
|
|
275
|
+
point of use, with a fallback for a token the view has not been taught.
|
|
276
|
+
|
|
277
|
+
The flag never hides the Work. A record with its file, title and metadata but
|
|
278
|
+
one missing derivative is degraded, not broken, and stays readable.
|
|
279
|
+
|
|
258
280
|
### Audit-event history
|
|
259
281
|
|
|
260
282
|
`Resource.history` wraps Atlas's `GET /resources/<id>/history` endpoint
|
data/lib/atlas_rb/work.rb
CHANGED
|
@@ -43,6 +43,11 @@ module AtlasRb
|
|
|
43
43
|
#
|
|
44
44
|
# @param in_progress [Boolean, nil] when set, filter to Works whose
|
|
45
45
|
# `in_progress` flag matches. Omit (or pass `nil`) for "all works".
|
|
46
|
+
# @param incomplete [Boolean, nil] when set, filter to Works whose
|
|
47
|
+
# `incomplete` flag matches — the staff list of Works whose enrichment
|
|
48
|
+
# pipeline gave up (see {.mark_incomplete}). Independent of
|
|
49
|
+
# `in_progress:`, and the two combine: `in_progress: false,
|
|
50
|
+
# incomplete: true` reads as "finished, but degraded".
|
|
46
51
|
# @param page [Integer, nil] 1-indexed page number.
|
|
47
52
|
# @param per_page [Integer, nil] page size override.
|
|
48
53
|
# @param nuid [String, nil] optional acting user's NUID. On the relay-signing
|
|
@@ -53,16 +58,20 @@ module AtlasRb
|
|
|
53
58
|
# omitted.
|
|
54
59
|
# @return [AtlasRb::Mash] `{ "works" => [...], "pagination" => {...} }`.
|
|
55
60
|
# Each entry in `"works"` is a Work summary (`id`, `title`,
|
|
56
|
-
# `description`, `in_progress`).
|
|
61
|
+
# `description`, `in_progress`, `incomplete`, `incomplete_reason`).
|
|
57
62
|
#
|
|
58
63
|
# @example Find stuck deposits
|
|
59
64
|
# AtlasRb::Work.list(in_progress: true)
|
|
60
65
|
#
|
|
66
|
+
# @example Find works whose pipeline gave up
|
|
67
|
+
# AtlasRb::Work.list(incomplete: true)
|
|
68
|
+
#
|
|
61
69
|
# @example Page through all works
|
|
62
70
|
# AtlasRb::Work.list(page: 2, per_page: 50)
|
|
63
|
-
def self.list(in_progress: nil, page: nil, per_page: nil, nuid: nil, on_behalf_of: nil)
|
|
71
|
+
def self.list(in_progress: nil, incomplete: nil, page: nil, per_page: nil, nuid: nil, on_behalf_of: nil)
|
|
64
72
|
params = {}
|
|
65
73
|
params[:in_progress] = in_progress unless in_progress.nil?
|
|
74
|
+
params[:incomplete] = incomplete unless incomplete.nil?
|
|
66
75
|
params[:page] = page if page
|
|
67
76
|
params[:per_page] = per_page if per_page
|
|
68
77
|
AtlasRb::Mash.new(JSON.parse(
|
|
@@ -232,6 +241,88 @@ module AtlasRb
|
|
|
232
241
|
connection({}, nuid, on_behalf_of: on_behalf_of).post(ROUTE + id + '/complete')
|
|
233
242
|
end
|
|
234
243
|
|
|
244
|
+
# Flag a Work whose enrichment pipeline gave up.
|
|
245
|
+
#
|
|
246
|
+
# The counterpart to {.complete}, for the other half of the lifecycle:
|
|
247
|
+
# `complete` says the deposit finished, this says something downstream of
|
|
248
|
+
# it did not. Call it from a work-scoped job's give-up handler — the PDF or
|
|
249
|
+
# media rendition, the derivatives, the full-text extraction — once that
|
|
250
|
+
# job has exhausted its retries. Atlas's `GET /works?incomplete=true` then
|
|
251
|
+
# lists the Work for staff, and `incomplete_bsi` on its Solr document lets
|
|
252
|
+
# a result row render a pill without a per-row fetch.
|
|
253
|
+
#
|
|
254
|
+
# The flag **never hides** the Work. A record with its file, title and
|
|
255
|
+
# metadata but one missing derivative is degraded, not broken, and stays
|
|
256
|
+
# readable — enrichment does not fail a deposit.
|
|
257
|
+
#
|
|
258
|
+
# Idempotent on the server; the last reason wins. Clear it with
|
|
259
|
+
# {.clear_incomplete} when a later run of the same job succeeds, which
|
|
260
|
+
# makes the state self-healing.
|
|
261
|
+
#
|
|
262
|
+
# @param id [String] the Work ID.
|
|
263
|
+
# @param reason [String, nil] a machine token naming the cause — one per
|
|
264
|
+
# give-up handler, e.g. `"pdf_rendition_gave_up"`,
|
|
265
|
+
# `"media_rendition_gave_up"`, `"ingest_gave_up"`. Atlas stores it as an
|
|
266
|
+
# opaque string and does **not** validate it against a list, so the
|
|
267
|
+
# vocabulary is the caller's and a new token needs no Atlas release. Map
|
|
268
|
+
# it to display text at the point of use, with a fallback for a token the
|
|
269
|
+
# view has not been taught. A blank reason still sets the flag.
|
|
270
|
+
# @param nuid [String, nil] optional NUID of the acting user.
|
|
271
|
+
# @param on_behalf_of [String, nil] optional NUID for the `On-Behalf-Of`
|
|
272
|
+
# header. Falls through to {AtlasRb.config}.default_on_behalf_of when
|
|
273
|
+
# omitted.
|
|
274
|
+
# @return [Hash] the updated Work, the same shape {.find} returns, carrying
|
|
275
|
+
# `incomplete` and `incomplete_reason`.
|
|
276
|
+
# @raise [AtlasRb::StaleResourceError] if Atlas reports an optimistic-lock
|
|
277
|
+
# conflict that exhausted its internal retry budget (HTTP 409 with
|
|
278
|
+
# `error: "stale_resource"`).
|
|
279
|
+
# @raise [AtlasRb::NotFoundError] if Atlas answers `404` — the id names no such
|
|
280
|
+
# resource, so the write did not happen.
|
|
281
|
+
# @raise [AtlasRb::ResourceError] on any other non-2xx, carrying Atlas's status
|
|
282
|
+
# and body.
|
|
283
|
+
#
|
|
284
|
+
# @example In a give-up handler
|
|
285
|
+
# AtlasRb::Work.mark_incomplete(work_id, reason: "pdf_rendition_gave_up")
|
|
286
|
+
def self.mark_incomplete(id, reason:, nuid: nil, on_behalf_of: nil)
|
|
287
|
+
AtlasRb::Mash.new(write_resource(
|
|
288
|
+
connection({}, nuid, on_behalf_of: on_behalf_of)
|
|
289
|
+
.post(ROUTE + id + '/incomplete', JSON.dump(reason: reason))
|
|
290
|
+
))["work"]
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Clear the incomplete flag and its reason.
|
|
294
|
+
#
|
|
295
|
+
# The repair half of {.mark_incomplete}: call it from the same job when a
|
|
296
|
+
# later run succeeds, or by hand once an operator has fixed the Work. Both
|
|
297
|
+
# fields clear together — a reason without a flag would leave a stale cause
|
|
298
|
+
# on the Solr document.
|
|
299
|
+
#
|
|
300
|
+
# Idempotent: clearing a Work that was never flagged is a no-op.
|
|
301
|
+
#
|
|
302
|
+
# @param id [String] the Work ID.
|
|
303
|
+
# @param nuid [String, nil] optional NUID of the acting user.
|
|
304
|
+
# @param on_behalf_of [String, nil] optional NUID for the `On-Behalf-Of`
|
|
305
|
+
# header. Falls through to {AtlasRb.config}.default_on_behalf_of when
|
|
306
|
+
# omitted.
|
|
307
|
+
# @return [Hash] the updated Work, the same shape {.find} returns, with
|
|
308
|
+
# `incomplete` false and `incomplete_reason` null.
|
|
309
|
+
# @raise [AtlasRb::StaleResourceError] if Atlas reports an optimistic-lock
|
|
310
|
+
# conflict that exhausted its internal retry budget (HTTP 409 with
|
|
311
|
+
# `error: "stale_resource"`).
|
|
312
|
+
# @raise [AtlasRb::NotFoundError] if Atlas answers `404` — the id names no such
|
|
313
|
+
# resource, so the write did not happen.
|
|
314
|
+
# @raise [AtlasRb::ResourceError] on any other non-2xx, carrying Atlas's status
|
|
315
|
+
# and body.
|
|
316
|
+
#
|
|
317
|
+
# @example On a later successful run
|
|
318
|
+
# AtlasRb::Work.clear_incomplete(work_id)
|
|
319
|
+
def self.clear_incomplete(id, nuid: nil, on_behalf_of: nil)
|
|
320
|
+
AtlasRb::Mash.new(write_resource(
|
|
321
|
+
connection({}, nuid, on_behalf_of: on_behalf_of)
|
|
322
|
+
.delete(ROUTE + id + '/incomplete')
|
|
323
|
+
))["work"]
|
|
324
|
+
end
|
|
325
|
+
|
|
235
326
|
# Replace a Work's metadata by uploading a MODS XML document.
|
|
236
327
|
#
|
|
237
328
|
# @param id [String] the Work ID.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: atlas_rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.10.
|
|
4
|
+
version: 1.10.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Cliff
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|