Skip to content

Instantly share code, notes, and snippets.

@altbodhi
Created September 3, 2020 02:58
Show Gist options
  • Select an option

  • Save altbodhi/bbc5da07654921ded8fe151d7bcd6384 to your computer and use it in GitHub Desktop.

Select an option

Save altbodhi/bbc5da07654921ded8fe151d7bcd6384 to your computer and use it in GitHub Desktop.
Прототип новой функциональности на F# глазами C#-программиста
open System
open System.Threading
let rnd = Random(Environment.TickCount)
let disks = [ 1; 2; 3; 4 ]
type Status =
| Fail of int
| Normal of int
type LastSend = int * DateTime
let getStatus d =
if rnd.Next(100) < 50 then Fail d else Normal d
let reSendAfter = DateTime.Now.AddSeconds(70.)
let createTimerAndObservable timerInterval (stopAfter: int) =
let timer =
new System.Timers.Timer(float timerInterval)
timer.AutoReset <- true
let observable = timer.Elapsed
let task =
async {
timer.Start()
do! Async.Sleep stopAfter
timer.Stop()
}
(task, observable)
let timer, timerEventStream = createTimerAndObservable 5000 60000
let sendMessage s = printfn "%s" s
let diskAgent =
MailboxProcessor<Status>
.Start(fun inbox ->
let rec messageLoop (lastChecks) =
async {
let! msg = inbox.Receive()
match msg with
| Fail d ->
if lastChecks
|> List.exists (fun (disk, time) -> disk = d && time < reSendAfter) then
printfn "Disk %d is fail. Skip send message" d
else
sprintf "Disk %d is fail. Required replacement." d
|> sendMessage
return! messageLoop
(lastChecks
|> List.filter (fun (disk, _) -> disk <> d)
|> List.append [ (d, DateTime.Now) ])
| Normal d ->
printfn "Disk %d is normal" d
return! messageLoop
(lastChecks
|> List.filter (fun (disk, _) -> disk <> d))
}
messageLoop ([]))
timerEventStream
|> Observable.subscribe (fun _ ->
printfn "%A check disks status" DateTime.Now
for d in disks do
getStatus d |> diskAgent.Post)
Async.RunSynchronously timer
@altbodhi
Copy link
Author

altbodhi commented Sep 3, 2020

Идея в том, что сообщение о сбое диска должно быть отправлено один раз до наступления некоторого времени.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment