zynagent-first application framework

Back to the API reference

zyn.Cache#

/// A PostgreSQL-backed, disposable application value cache.
pub const Cache = struct {
    pub const key_limit: usize = 256;
    pub const default_max_value_bytes: usize = 2 * 1024 * 1024;
    pub const default_target_size_bytes: u64 = 1024 * 1024 * 1024;
    
    /// Framework-owned schema in the disposable cache database.
    pub const schema_sql =
        \\CREATE SCHEMA IF NOT EXISTS zyn;
        \\CREATE TABLE IF NOT EXISTS zyn.cache_schema_version (
        \\    version integer NOT NULL PRIMARY KEY
        \\);
        \\DO $zyn$ BEGIN
        \\    IF (SELECT COALESCE(MAX(version), 0) FROM zyn.cache_schema_version) > 1 THEN
        \\        RAISE EXCEPTION 'cache schema is newer than this Zyn release';
        \\    END IF;
        \\END $zyn$;
        \\CREATE TABLE IF NOT EXISTS zyn.cache_entries (
        \\    key text NOT NULL PRIMARY KEY CHECK (octet_length(key) BETWEEN 1 AND 256),
        \\    value bytea NOT NULL,
        \\    expires_at timestamptz NOT NULL,
        \\    written_at timestamptz NOT NULL DEFAULT clock_timestamp()
        \\);
        \\CREATE INDEX IF NOT EXISTS cache_expiry_idx
        \\    ON zyn.cache_entries (expires_at, key);
        \\CREATE INDEX IF NOT EXISTS cache_fifo_idx
        \\    ON zyn.cache_entries (written_at, key);
        \\CREATE TABLE IF NOT EXISTS zyn.rate_limits (
        \\    key_hash bytea PRIMARY KEY CHECK (octet_length(key_hash) = 32),
        \\    theoretical_arrival_at timestamptz NOT NULL
        \\);
        \\CREATE INDEX IF NOT EXISTS rate_limits_arrival_idx
        \\    ON zyn.rate_limits (theoretical_arrival_at);
        \\INSERT INTO zyn.cache_schema_version (version) VALUES (1)
        \\    ON CONFLICT (version) DO NOTHING;
    ;
    
    pub const Options = struct {
        ttl: Io.Duration,
    };
    
    /// Returns a nonexpired value, or null. The returned bytes live in the
    /// request or job allocator, not in the cache's connection pool.
    pub fn get(self: *Cache, key: []const u8) !?[]const u8;
    
    /// Atomically inserts or replaces a bounded value with a required positive TTL.
    pub fn put(self: *Cache, key: []const u8, value: []const u8, options: Options) !void;
    
    /// Removes one key; returns whether it existed, including if it had expired.
    pub fn delete(self: *Cache, key: []const u8) !bool;
    
    /// Computes on a miss or cache failure. Invalid keys and TTLs still fail.
    /// The compute callback's result is copied into the scoped allocator.
    pub fn fetch(
        self: *Cache,
        key: []const u8,
        options: Options,
        context: anytype,
        comptime compute: anytype,
    ) ![]const u8;
    
    /// Bounded maintenance. A failed cleanup does not affect cache reads or writes.
    pub fn prune(self: *Cache) !void;
};