Class: Tina4::Realtime::S3Storage

Inherits:
StorageBackend show all
Defined in:
lib/tina4/realtime/s3_storage.rb

Overview

S3-compatible store (AWS S3, MinIO, ...). Opt-in; needs the aws-sdk-s3 gem.

Presigned GET URLs let clients fetch large blobs straight from object storage instead of streaming through the app.

Instance Method Summary collapse

Constructor Details

#initialize(endpoint: nil, key: nil, secret: nil, bucket: nil, region: nil) ⇒ S3Storage

Returns a new instance of S3Storage.

Raises:

  • (ArgumentError)


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/tina4/realtime/s3_storage.rb', line 10

def initialize(endpoint: nil, key: nil, secret: nil, bucket: nil, region: nil)
  super()
  require "aws-sdk-s3" # optional dependency, loaded lazily

  @bucket = bucket || ENV["TINA4_STORAGE_BUCKET"]
  raise ArgumentError, "S3Storage requires TINA4_STORAGE_BUCKET" if @bucket.nil? || @bucket.empty?

  opts = {
    access_key_id: key || ENV["TINA4_STORAGE_KEY"],
    secret_access_key: secret || ENV["TINA4_STORAGE_SECRET"],
    region: region || ENV["TINA4_STORAGE_REGION"] || "us-east-1",
    force_path_style: true
  }
  ep = endpoint || ENV["TINA4_STORAGE_URL"]
  opts[:endpoint] = ep if ep && !ep.empty?
  @client = Aws::S3::Client.new(**opts)
end

Instance Method Details

#delete(key) ⇒ Object



44
45
46
47
48
49
50
# File 'lib/tina4/realtime/s3_storage.rb', line 44

def delete(key)
  @client.delete_object(bucket: @bucket, key: key)
  nil
rescue StandardError => e
  Tina4::Log.error("S3Storage delete failed for #{key}: #{e.message}")
  nil
end

#exists?(key) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
55
56
57
# File 'lib/tina4/realtime/s3_storage.rb', line 52

def exists?(key)
  @client.head_object(bucket: @bucket, key: key)
  true
rescue StandardError
  false
end

#get(key) ⇒ Object



33
34
35
36
37
# File 'lib/tina4/realtime/s3_storage.rb', line 33

def get(key)
  @client.get_object(bucket: @bucket, key: key).body.read
rescue StandardError
  nil
end

#put(key, data, mime = "application/octet-stream") ⇒ Object



28
29
30
31
# File 'lib/tina4/realtime/s3_storage.rb', line 28

def put(key, data, mime = "application/octet-stream")
  @client.put_object(bucket: @bucket, key: key, body: data, content_type: mime)
  nil
end

#url(key, ttl = 3600) ⇒ Object



39
40
41
42
# File 'lib/tina4/realtime/s3_storage.rb', line 39

def url(key, ttl = 3600)
  Aws::S3::Presigner.new(client: @client)
                    .presigned_url(:get_object, bucket: @bucket, key: key, expires_in: ttl)
end