activestorage-hotcell-client 1.0.0 → 1.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/README.md +1 -1
- data/lib/active_storage/hot_cell/client/analyzers/analyzing.rb +1 -1
- data/lib/active_storage/hot_cell/client/analyzers/video.rb +1 -1
- data/lib/active_storage/hot_cell/client/railtie.rb +9 -5
- data/lib/active_storage/hot_cell/client/transformers/transforming.rb +16 -1
- data/lib/active_storage/hot_cell/client/version.rb +1 -1
- data/lib/active_storage/hot_cell/client.rb +10 -13
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4abc5bc93c3eb1b9370c321983b0038e9cba28203e0610b29b0b5d838eece2df
|
|
4
|
+
data.tar.gz: 2b53ad5e9304c42c0820c879e9beb5faa74db34d050bb49bc02f5a074b80f9ce
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7f985858d5827fdb6ddcafee076136a6a37a6bcdcb2f07fa5495b3dbe8a9fa2e3b6f29093add11255d4bf94214fda2e025d5caecc9e4fed10c61e123fcecf8cc
|
|
7
|
+
data.tar.gz: 5884cc6183a3513fab8a27543d24a3546038407e33667c82366e328a5ed84179486076a549281436732c31fecc47baf5abc95f76b4a05d2719ef4168caebb3a7
|
data/README.md
CHANGED
|
@@ -16,7 +16,7 @@ module ActiveStorage
|
|
|
16
16
|
# **Which way `metadata` fails is the whole design of the method.** The built-in vips analyzer rescues
|
|
17
17
|
# every Vips::Error and returns an empty hash, which Rails then merges with `analyzed: true` — so an
|
|
18
18
|
# undecodable image is recorded as successfully analyzed, forever, and nothing ever re-enqueues
|
|
19
|
-
# AnalyzeJob. That is right for a permanent
|
|
19
|
+
# AnalyzeJob. That is right for a permanent failure and catastrophic for a transient one.
|
|
20
20
|
#
|
|
21
21
|
# So a permanent failure follows the built-in behaviour and lets the blob be marked analyzed, with the
|
|
22
22
|
# reason written to the log so it can be re-decided later against a newer library. A transient failure
|
|
@@ -10,7 +10,7 @@ module ActiveStorage
|
|
|
10
10
|
module Client
|
|
11
11
|
module Analyzers
|
|
12
12
|
# Rails' VideoAnalyzer shells out to ffprobe inside the application process. Moving ffprobe into a
|
|
13
|
-
# cell means this has to move with it, or an application that adopts
|
|
13
|
+
# cell means this has to move with it, or an application that adopts Hot Cell still analyzes media in
|
|
14
14
|
# its own process and cannot take ffprobe out of its image — the incomplete move for exactly the
|
|
15
15
|
# media type a cell exists to isolate.
|
|
16
16
|
#
|
|
@@ -9,11 +9,15 @@ module ActiveStorage
|
|
|
9
9
|
# reads those from config and there is no way for a gem to set them that the engine does not later
|
|
10
10
|
# overwrite. Everything else this gem needs is done here.
|
|
11
11
|
class Railtie < ::Rails::Railtie
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
# on_load rather than to_prepare, because to_prepare runs while the application is initializing, and
|
|
13
|
+
# loading a job there loads Active Job, which Rails' guard_load_hooks reports when eager loading is off.
|
|
14
|
+
# on_load also runs again each time a job is reloaded, and never for a job the application's Rails
|
|
15
|
+
# version does not have.
|
|
16
|
+
initializer "active_storage.hot_cell.client.retry_transient_failures" do
|
|
17
|
+
ActiveStorage::HotCell::Client::JOBS.each do |name|
|
|
18
|
+
Rails.autoloaders.main.on_load(name) do |job|
|
|
19
|
+
ActiveStorage::HotCell::Client.retry_transient_failures! job
|
|
20
|
+
end
|
|
17
21
|
end
|
|
18
22
|
end
|
|
19
23
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "tempfile"
|
|
4
|
+
require "marcel"
|
|
4
5
|
require "active_storage"
|
|
5
6
|
require "active_support/core_ext/class/attribute"
|
|
6
7
|
require "active_support/core_ext/hash/deep_transform_values"
|
|
@@ -33,7 +34,7 @@ module ActiveStorage
|
|
|
33
34
|
output = Tempfile.new([ "hotcell", ".#{format}" ], binmode: true)
|
|
34
35
|
|
|
35
36
|
begin
|
|
36
|
-
convert file, output, format: format
|
|
37
|
+
convert file, output, format: canonical(format), operations: stringified(transformations)
|
|
37
38
|
output.tap(&:rewind)
|
|
38
39
|
rescue StandardError
|
|
39
40
|
output.close!
|
|
@@ -41,6 +42,20 @@ module ActiveStorage
|
|
|
41
42
|
end
|
|
42
43
|
end
|
|
43
44
|
|
|
45
|
+
# Rails names a web image's variant format after its upload's extension, so a JPEG uploaded as
|
|
46
|
+
# `photo.jfif` asks for `jfif`. ImageMagick has no coder for `jfif`, `jif` or `jfi`, and libvips has no
|
|
47
|
+
# saver for the last two (#84). So a web image's format crosses as its content type's canonical
|
|
48
|
+
# extension, the one Rails itself names when the upload's extension does not match.
|
|
49
|
+
def canonical(format)
|
|
50
|
+
content_type = Marcel::MimeType.for(extension: format.to_s)
|
|
51
|
+
|
|
52
|
+
if ActiveStorage.web_image_content_types.include?(content_type)
|
|
53
|
+
Marcel::Magic.new(content_type).extensions.first
|
|
54
|
+
else
|
|
55
|
+
format.to_s
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
44
59
|
# Both handles are reopened by path, narrowly, and that is the protocol rather than fussiness. Rails
|
|
45
60
|
# hands out Tempfiles, which are read-write; an input descriptor must be read-only and an output
|
|
46
61
|
# write-only. An access mode is fixed at open, so a cell handed the wrong one cannot narrow it — it can
|
|
@@ -28,10 +28,11 @@ module ActiveStorage
|
|
|
28
28
|
module Client
|
|
29
29
|
# These four jobs declare `retry_on ActiveStorage::IntegrityError` and nothing else, and ActiveJob does
|
|
30
30
|
# not retry by default. They should retry the transient class too: `capacity` most obviously, and every
|
|
31
|
-
# other transient
|
|
31
|
+
# other transient failure. The policy matches the one they already declare, so a cell failure and an
|
|
32
32
|
# integrity failure back off the same way.
|
|
33
33
|
#
|
|
34
|
-
# Which of these classes exists depends on the Rails version
|
|
34
|
+
# Which of these classes exists depends on the Rails version. A name the application does not have is
|
|
35
|
+
# never loaded, so the retry is never applied to it.
|
|
35
36
|
JOBS = %w[
|
|
36
37
|
ActiveStorage::AnalyzeJob
|
|
37
38
|
ActiveStorage::CreateVariantsJob
|
|
@@ -51,22 +52,18 @@ module ActiveStorage
|
|
|
51
52
|
Operations::Previewers::Video::Ffmpeg ].freeze
|
|
52
53
|
|
|
53
54
|
class << self
|
|
54
|
-
# The railtie calls this
|
|
55
|
+
# The railtie calls this each time one of the JOBS loads. Applied once it would not survive a code
|
|
55
56
|
# reload: a gem engine's app/jobs is in the reloadable autoloader, so these classes are discarded and
|
|
56
57
|
# redefined, and the retry would silently disappear after the first file save in development.
|
|
57
58
|
#
|
|
58
59
|
# Every registered cell contributes its transient class, because the documented multi-cell
|
|
59
60
|
# arrangement routes PreviewVideo to a cell of its own and each cell names its own class. A cell not
|
|
60
|
-
# yet registered contributes nothing rather than raising: this runs
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
def retry_transient_failures!(
|
|
64
|
-
transients = CLIENTS.filter_map { |client| client.cell.transient if client.registered? }
|
|
65
|
-
|
|
66
|
-
return [] if transients.empty?
|
|
67
|
-
|
|
68
|
-
jobs.filter_map(&:safe_constantize)
|
|
69
|
-
.each { |job| job.retry_on(*transients, **RETRY) }
|
|
61
|
+
# yet registered contributes nothing rather than raising: this runs in an application that has
|
|
62
|
+
# bundled the gem and not yet written the initializer, and that boot has to succeed for the rollout
|
|
63
|
+
# to take two deploys rather than one.
|
|
64
|
+
def retry_transient_failures!(job)
|
|
65
|
+
transients = CLIENTS.filter_map { |client| client.cell.transient if client.registered? }.uniq
|
|
66
|
+
job.retry_on(*transients, **RETRY) if transients.any?
|
|
70
67
|
end
|
|
71
68
|
end
|
|
72
69
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activestorage-hotcell-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Dalessio
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 1.
|
|
18
|
+
version: 1.2.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 1.
|
|
25
|
+
version: 1.2.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: activestorage
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -39,7 +39,7 @@ dependencies:
|
|
|
39
39
|
version: 8.2.0.alpha
|
|
40
40
|
description: |
|
|
41
41
|
Drop-in replacements for Active Storage's variant processor, analyzers, and previewers. Configure
|
|
42
|
-
Rails with these classes and variants, image and media analysis, and previews run in a
|
|
42
|
+
Rails with these classes and variants, image and media analysis, and previews run in a Hot Cell
|
|
43
43
|
container instead of in the application process.
|
|
44
44
|
email:
|
|
45
45
|
- mike@37signals.com
|
|
@@ -77,8 +77,8 @@ licenses:
|
|
|
77
77
|
- MIT
|
|
78
78
|
metadata:
|
|
79
79
|
homepage_uri: https://github.com/basecamp/hotcell
|
|
80
|
-
source_code_uri: https://github.com/basecamp/hotcell/tree/v1.
|
|
81
|
-
changelog_uri: https://github.com/basecamp/hotcell/blob/v1.
|
|
80
|
+
source_code_uri: https://github.com/basecamp/hotcell/tree/v1.2.0/activestorage-hotcell-client
|
|
81
|
+
changelog_uri: https://github.com/basecamp/hotcell/blob/v1.2.0/CHANGELOG.md
|
|
82
82
|
documentation_uri: https://basecamp.github.io/hotcell/
|
|
83
83
|
bug_tracker_uri: https://github.com/basecamp/hotcell/issues
|
|
84
84
|
rubygems_mfa_required: 'true'
|
|
@@ -98,5 +98,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
98
98
|
requirements: []
|
|
99
99
|
rubygems_version: 4.0.6
|
|
100
100
|
specification_version: 4
|
|
101
|
-
summary: Point Active Storage's transformer, analyzer, and previewers at a
|
|
101
|
+
summary: Point Active Storage's transformer, analyzer, and previewers at a Hot Cell.
|
|
102
102
|
test_files: []
|