Skip to content

Instantly share code, notes, and snippets.

@altbodhi
Created July 21, 2020 04:43
Show Gist options
  • Save altbodhi/60a734325e16e4a6c3cd945fa72d2162 to your computer and use it in GitHub Desktop.
Save altbodhi/60a734325e16e4a6c3cd945fa72d2162 to your computer and use it in GitHub Desktop.
let now () = System.DateTime.Now.ToString("s")
type CacheCommand<'id, 'result> =
| Get of 'id * AsyncReplyChannel<Result<'result, string>>
| Clear
type Cache(getter) =
let mailbox =
MailboxProcessor.Start(fun inbox ->
let rec loop cache =
async {
let! cmd = inbox.Receive()
match cmd with
| Get (i, repl) ->
let (item, cache') =
match Map.tryFind i cache with
| None ->
match getter i with
| None -> (Error "нет данных", cache)
| Some it -> (Ok it, Map.add i it cache)
| Some v -> (Ok v, cache)
repl.Reply(item)
return! loop cache'
| Clear -> return! loop Map.empty
}
loop (Map [ 1, "Привет"; 2, "Как" ]))
member this.GetItem i =
async {
let! answer = mailbox.PostAndAsyncReply(fun res -> Get(i, res))
let nw = now ()
match answer with
| Ok v -> printfn "%s [INFO] id = %i , value = %s" nw i v
| Error e -> printfn "%s [ERROR] %s" nw e
}
|> Async.RunSynchronously
member this.Cleanup() = mailbox.Post Clear
let getFromDb =
fun i -> if i < 10 then Some(i.ToString()) else None
let cache = Cache getFromDb
async {
while true do
for i = 1 to 12 do
cache.GetItem i
do! Async.Sleep 1000
cache.Cleanup()
do! Async.Sleep 1000
} |> Async.RunSynchronously
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment