Skip to content

Instantly share code, notes, and snippets.

@JordanMarr
Last active January 15, 2022 08:56
Show Gist options
  • Save JordanMarr/631806b2d24984c50ec22468db6fcfe2 to your computer and use it in GitHub Desktop.
Save JordanMarr/631806b2d24984c50ec22468db6fcfe2 to your computer and use it in GitHub Desktop.
F# Cache utility for ASP.NET
module Cache
open System
open Microsoft.AspNetCore.Http
open Microsoft.Extensions.Caching.Memory
type CacheExpiration =
| Absolute of DateTimeOffset
| AbsoluteRelativeToNow of TimeSpan
| Sliding of TimeSpan
/// Caches the results of an async function for a given key / expiration.
let cacheAsync<'Payload> (ctx: HttpContext) (key: string) (expiration: CacheExpiration) fn =
let cache = ctx.GetService<IMemoryCache>()
cache.GetOrCreateAsync<'Payload>(key, fun entry ->
task {
printfn $"'{key}' not found in cache."
match expiration with
| Absolute dt -> entry.AbsoluteExpiration <- Nullable dt
| AbsoluteRelativeToNow ts -> entry.AbsoluteExpirationRelativeToNow <- Nullable ts
| Sliding ts -> entry.SlidingExpiration <- Nullable ts
let! payload = fn |> Async.StartAsTask
let expirationDescription =
match expiration with
| Absolute dt -> $"{dt - DateTimeOffset.Now}"
| AbsoluteRelativeToNow ts -> $"{ts}"
| Sliding ts -> $"{ts} after last use"
printfn $"'{key}' added to cache for {expirationDescription}."
return payload
}
)
|> Async.AwaitTask
/// Clears the results from cache.
let invalidateCache (ctx: HttpContext) (key: string) =
let cache = ctx.GetService<IMemoryCache>()
cache.Remove(key)
module Handlers
open Microsoft.AspNetCore.Http
let getWidgets (ctx: HttpContext) (projectId: int) =
async {
let! widgets = Widgets.IO.getWidgets projectId
return widgets
}
// USAGE:
let getWidgetsCached (ctx: HttpContext) (projectId: int) =
async {
let! widgets =
let key = $"widgets_%i{projectId}"
let expiration = Cache.AbsoluteRelativeToNow (TimeSpan.FromMinutes 15.)
Cache.cacheAsync ctx key expiration (Widgets.IO.getWidgets projectId)
return widgets
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment