Stores objects in an S3-compatible bucket: Cloudflare R2, Garage, MinIO or
AWS S3. Optional: require "data_dungeon/s3", and add awscr-s3 to the
application's own shard.yml.
Objects are content-addressed, so they never change once written; they're
uploaded with long immutable cache headers, which lets a CDN in front of
public_url serve every repeat. Connections are pooled and kept alive,
and a request the service turns away for load (429, 5xx) is retried with
backoff. Give DataDungeon a bucket, or a prefix within one, of its own:
the consistency sweep treats every object under it as DataDungeon's. A
bucket several stores share is shared: true (see Storage#shared?).
Constants
IMMUTABLE = "public, max-age=31536000, immutable"
RETRYABLE = [429, 500, 502, 503, 504]
Constructors
new(bucket :
String, *, endpoint :
String, region :
String, access_key :
String, secret_key :
String, prefix :
String = "", public_url :
String |
Nil = nil, sign_key :
String |
Nil = nil, url_expires :
Time::Span = 1.hour, retries :
Int32 = 3, pool_size :
Int32 = 8, shared :
Bool = false)
public_url (e.g. a custom domain or CDN in front of the bucket) makes
resolve return plain URLs; without it, resolve returns presigned
URLs valid for url_expires.
sign_key turns on signed public_urls: resolve appends ?exp=&sig=,
where sig is the lowercase hex HMAC-SHA256 of "<object>\n<exp>" under
this key. A Worker in front of a private bucket (see worker/) verifies
the signature and expiry before serving, so the bucket need not be public
yet the URLs still carry your own domain and are CDN-cacheable. It only
applies when public_url is set, and the object path must be the signed
subject — so use it with an empty prefix (the Worker serves root-level
content-addressed keys). Without sign_key, public_urls stay plain.
Sourcer2(account_id :
String, bucket :
String, *, access_key :
String, secret_key :
String, prefix :
String = "", public_url :
String |
Nil = nil, sign_key :
String |
Nil = nil, url_expires :
Time::Span = 1.hour, retries :
Int32 = 3, pool_size :
Int32 = 8, shared :
Bool = false) :
S3Storage A Cloudflare R2 bucket in the given account.
SourceInstance methods
S3 reports success for a missing object too, so this is a no-op then.
SourceWhether an object exists at the given key.
Sourcelist_keys
Enumerate every object key currently in the backend. Used by the
consistency sweep to find objects with no owning row. May be expensive
on large object stores; intended for maintenance, not the hot path.
SourceA status the bucket turns a request away with comes before any bytes,
so retrying it never runs the block twice.
SourceRead the bytes stored at the given key.
SourceResolve a key to a usable location — a local absolute path here,
a URL for object stores.
SourceWrite bytes at the given key, creating any containers as needed. The
content type is a hint for backends that serve objects themselves.
Source