Class: PatientHttp::ExternalStorage
- Inherits:
-
Object
- Object
- PatientHttp::ExternalStorage
- Defined in:
- lib/patient_http/external_storage.rb
Overview
Handles external storage of large payloads.
This class provides methods for storing, fetching, and deleting payloads from external storage. It is decoupled from the models being stored (Request, Response, Error).
Defined Under Namespace
Classes: PayloadNotFoundError, PayloadStoreNotFoundError
Constant Summary collapse
- REFERENCE_KEY =
Key used in serialized JSON to indicate an external storage reference
"$ref"
Instance Attribute Summary collapse
-
#config ⇒ Configuration
readonly
The pool configuration.
Class Method Summary collapse
-
.storage_ref?(data) ⇒ Boolean
Check if a hash is a storage reference.
Instance Method Summary collapse
-
#delete(data) ⇒ void
Delete payload from external storage.
-
#enabled? ⇒ Boolean
Check if external storage is enabled (i.e. a payload store is configured).
-
#fetch(data) ⇒ Hash
Fetch a hash from external storage.
-
#initialize(config) ⇒ ExternalStorage
constructor
Create a new ExternalStorage instance.
-
#storage_ref?(data) ⇒ Boolean
Check if a hash is a storage reference.
-
#store(data, max_size: nil) ⇒ Hash
Store a hash externally if it exceeds the configured threshold.
Constructor Details
#initialize(config) ⇒ ExternalStorage
Create a new ExternalStorage instance.
45 46 47 |
# File 'lib/patient_http/external_storage.rb', line 45 def initialize(config) @config = config end |
Instance Attribute Details
#config ⇒ Configuration (readonly)
Returns the pool configuration.
40 41 42 |
# File 'lib/patient_http/external_storage.rb', line 40 def config @config end |
Class Method Details
.storage_ref?(data) ⇒ Boolean
Check if a hash is a storage reference.
34 35 36 |
# File 'lib/patient_http/external_storage.rb', line 34 def storage_ref?(data) data.is_a?(Hash) && data.key?(REFERENCE_KEY) end |
Instance Method Details
#delete(data) ⇒ void
This method returns an undefined value.
Delete payload from external storage.
This method is idempotent - it’s safe to call on non-reference hashes, already-deleted payloads, or nil values.
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/patient_http/external_storage.rb', line 123 def delete(data) return unless data && self.class.storage_ref?(data) ref = data[REFERENCE_KEY] store_name = ref["store"].to_sym key = ref["key"] store = config.payload_store(store_name) store&.delete(key) end |
#enabled? ⇒ Boolean
Check if external storage is enabled (i.e. a payload store is configured).
60 61 62 |
# File 'lib/patient_http/external_storage.rb', line 60 def enabled? !!config.payload_store end |
#fetch(data) ⇒ Hash
Fetch a hash from external storage.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/patient_http/external_storage.rb', line 100 def fetch(data) raise ArgumentError.new("Not a storage reference") unless self.class.storage_ref?(data) ref = data[REFERENCE_KEY] store_name = ref["store"].to_sym key = ref["key"] store = config.payload_store(store_name) raise PayloadStoreNotFoundError.new("Payload store '#{store_name}' not registered") unless store stored_data = store.fetch(key) raise PayloadNotFoundError.new("Stored payload not found: #{store_name}/#{key}") unless stored_data stored_data end |
#storage_ref?(data) ⇒ Boolean
Check if a hash is a storage reference.
53 54 55 |
# File 'lib/patient_http/external_storage.rb', line 53 def storage_ref?(data) self.class.storage_ref?(data) end |
#store(data, max_size: nil) ⇒ Hash
Store a hash externally if it exceeds the configured threshold.
If no payload store is configured, or if the hash is below the threshold, the original hash is returned unchanged.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/patient_http/external_storage.rb', line 76 def store(data, max_size: nil) store = config.payload_store raise PayloadStoreNotFoundError.new("No payload store configured") unless store json = JSON.generate(data) return data if max_size && json.bytesize <= max_size key = store.generate_key store.store_json(key, json) { REFERENCE_KEY => { "store" => config.default_payload_store_name.to_s, "key" => key } } end |