Skip to content

FeatherTools/cache

Repository files navigation

FeatherTools Logo Cache

NuGet NuGet Downloads Checks

Redis-backed distributed cache library. Wraps StackExchange.Redis and IDistributedCache into a single RedisConnection value that supports both standalone Redis and Redis Sentinel (HA).

Install

paket add Feather.Cache

Connection modes

Standalone

Single Redis instance — for local development or when HA is not required.

let connection =
    Redis.connect (RedisConnectionConfiguration.Standalone {
        Instance = Some myInstance  // Alma.ServiceIdentification.Instance
        Port = 6379
    })

Sentinel (HA)

Three Sentinel nodes managing a primary/replica Redis set. The client always writes to and reads from the current primary — failover is transparent.

In Kubernetes, Sentinel pods expose port 26379. Pod DNS names follow the StatefulSet pattern:

let connection =
    Redis.connect (RedisConnectionConfiguration.Sentinel {
        Sentinels = [
            { Instance = Some sentinel0Instance; Port = 26379 }
            { Instance = Some sentinel1Instance; Port = 26379 }
            { Instance = Some sentinel2Instance; Port = 26379 }
        ]
        ServiceName = "sentinelName"  // must match `sentinel monitor <name>` in sentinel.conf
    })

Cache operations

All operations are on IDistributedCache via Cache module, or directly on RedisConnection for atomic ops.

Standard get/set (via Cache module)

open Feather.Cache

// Store with TTL
do! Cache.store connection.Cache (CacheId "my-key") (Some (TimeSpan.FromMinutes 10.0)) "my-value"

// Store without expiry
do! Cache.store connection.Cache (CacheId "my-key") None "my-value"

// Retrieve
let! value = Cache.tryGet connection.Cache (CacheId "my-key")
// value : string option

Atomic get-and-delete

Use when a value should be consumed exactly once (e.g. one-time tokens).

let! value = connection.GetDelete (CacheId "one-time-token")
// value : string option — atomically removed from Redis

Raw string set

Stores a plain Redis String (not a Hash), required when the value must also be read by GetDelete.

do! connection.StringSet (CacheId "my-key") (Some (TimeSpan.FromHours 1.0)) "raw-value"

Notes

  • IDistributedCache (Cache.store / Cache.tryGet) writes Redis Hashes internally (StackExchange.Redis behaviour).
  • GetDelete and StringSet operate on plain Redis Strings and are mutually compatible.
  • Do not mix Cache.store with GetDelete on the same key — they use different Redis types.
  • The RedisConnection implements IDisposable; dispose it on application shutdown.

Release

  1. Increment version in Cache.fsproj
  2. Update CHANGELOG.md
  3. Commit new version and tag it

Development

Requirements

Build

./build.sh build

Tests

./build.sh -t tests

About

Library for F# cache wrappers.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors