-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add storage interface with reference memory implementation.
- Loading branch information
Showing
17 changed files
with
646 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# frozen_string_literal: true | ||
|
||
module AtprotoAuth | ||
module Storage | ||
# Base storage interface that all implementations must conform to | ||
class Interface | ||
# Store a value with optional TTL | ||
# @param key [String] Storage key | ||
# @param value [Object] Value to store | ||
# @param ttl [Integer, nil] Time-to-live in seconds | ||
# @return [Boolean] Success status | ||
# @raise [StorageError] if operation fails | ||
def set(key, value, ttl: nil) | ||
raise NotImplementedError | ||
end | ||
|
||
# Retrieve a value | ||
# @param key [String] Storage key | ||
# @return [Object, nil] Stored value or nil if not found | ||
# @raise [StorageError] if operation fails | ||
def get(key) | ||
raise NotImplementedError | ||
end | ||
|
||
# Delete a value | ||
# @param key [String] Storage key | ||
# @return [Boolean] Success status | ||
# @raise [StorageError] if operation fails | ||
def delete(key) | ||
raise NotImplementedError | ||
end | ||
|
||
# Check if key exists | ||
# @param key [String] Storage key | ||
# @return [Boolean] True if key exists | ||
# @raise [StorageError] if operation fails | ||
def exists?(key) | ||
raise NotImplementedError | ||
end | ||
|
||
# Get multiple values | ||
# @param keys [Array<String>] Storage keys | ||
# @return [Hash<String, Object>] Key-value pairs | ||
# @raise [StorageError] if operation fails | ||
def multi_get(keys) | ||
raise NotImplementedError | ||
end | ||
|
||
# Store multiple values | ||
# @param hash [Hash<String, Object>] Key-value pairs | ||
# @param ttl [Integer, nil] Time-to-live in seconds | ||
# @return [Boolean] Success status | ||
# @raise [StorageError] if operation fails | ||
def multi_set(hash, ttl: nil) | ||
raise NotImplementedError | ||
end | ||
|
||
# Acquire a lock | ||
# @param key [String] Lock key | ||
# @param ttl [Integer] Lock timeout in seconds | ||
# @return [Boolean] True if lock acquired | ||
# @raise [StorageError] if operation fails | ||
def acquire_lock(key, ttl:) | ||
raise NotImplementedError | ||
end | ||
|
||
# Release a lock | ||
# @param key [String] Lock key | ||
# @return [Boolean] Success status | ||
# @raise [StorageError] if operation fails | ||
def release_lock(key) | ||
raise NotImplementedError | ||
end | ||
|
||
# Execute block with lock | ||
# @param key [String] Lock key | ||
# @param ttl [Integer] Lock timeout in seconds | ||
# @yield Block to execute with lock | ||
# @return [Object] Block result | ||
# @raise [StorageError] if operation fails | ||
def with_lock(key, ttl: 30) | ||
raise NotImplementedError | ||
end | ||
|
||
protected | ||
|
||
# Validate key format | ||
# @param key [String] Key to validate | ||
# @raise [StorageError] if key is invalid | ||
def validate_key!(key) | ||
raise StorageError, "Key cannot be nil" if key.nil? | ||
raise StorageError, "Key must be a string" unless key.is_a?(String) | ||
raise StorageError, "Key cannot be empty" if key.empty? | ||
raise StorageError, "Invalid key format" unless key.start_with?("atproto:") | ||
end | ||
|
||
# Validate TTL value | ||
# @param ttl [Integer, nil] TTL to validate | ||
# @raise [StorageError] if TTL is invalid | ||
def validate_ttl!(ttl) | ||
return if ttl.nil? | ||
raise StorageError, "TTL must be a positive integer" unless ttl.is_a?(Integer) && ttl.positive? | ||
end | ||
end | ||
|
||
# Base error class for storage operations | ||
class StorageError < AtprotoAuth::Error; end | ||
|
||
# Error for lock-related operations | ||
class LockError < StorageError; end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# frozen_string_literal: true | ||
|
||
module AtprotoAuth | ||
module Storage | ||
# Utility for building storage keys with correct format | ||
class KeyBuilder | ||
NAMESPACE_SEPARATOR = ":" | ||
NAMESPACE_PREFIX = "atproto" | ||
|
||
class << self | ||
def session_key(id) | ||
build_key("session", id) | ||
end | ||
|
||
def state_key(token) | ||
build_key("state", token) | ||
end | ||
|
||
def nonce_key(server_url) | ||
build_key("nonce", server_url) | ||
end | ||
|
||
def dpop_key(client_id) | ||
build_key("dpop", client_id) | ||
end | ||
|
||
def lock_key(namespace, id) | ||
build_key("lock", namespace, id) | ||
end | ||
|
||
private | ||
|
||
def build_key(*parts) | ||
[NAMESPACE_PREFIX, *parts].join(NAMESPACE_SEPARATOR) | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.