Last active
October 20, 2021 14:11
-
-
Save aaronmu/2ca737e35dd022ac0eaf93a0b599a432 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
type Timed<'T> = | |
{ Timestamp: DateTimeOffset | |
Value: 'T } | |
type Clock = unit -> DateTimeOffset | |
let Timed (c: Clock) v = | |
{ Timestamp = c () | |
Value = v } | |
let memoizeAsyncFn (clock: Clock) (expiresAt: DateTimeOffset) fn = | |
let d = ConcurrentDictionary () | |
let tryFind k = | |
match d.TryGetValue k with | |
| true, timedValue -> | |
if timedValue.Timestamp >= expiresAt then | |
None | |
else | |
Some timedValue.Value | |
| false, _ -> None | |
let addOrUpdate k v = | |
let v = Timed clock v | |
let setter = Func<_, _,_>(fun _ _ -> v) | |
d.AddOrUpdate (k, v, setter) | |
async { | |
while true do | |
for kvp in d do | |
if kvp.Value.Timestamp >= expiresAt then | |
let _ = d.Remove kvp.Key | |
() | |
else | |
() | |
do! Async.Sleep 60000 | |
} |> Async.Start | |
fun x -> | |
match tryFind x with | |
| Some v -> async { return v } | |
| None -> | |
async { | |
let! v = fn x | |
let _ = addOrUpdate x v | |
return v | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment