Skip to content

Instantly share code, notes, and snippets.

@Kimserey
Last active December 21, 2015 06:36
Show Gist options
  • Save Kimserey/ca51d2a9d2951882c97e to your computer and use it in GitHub Desktop.
Save Kimserey/ca51d2a9d2951882c97e to your computer and use it in GitHub Desktop.
Agent for countdown
module private CountdownExpiryAgent =
open Modal
type Operation =
| Reset of remainingSecs: int
| Tick
| RegisterHandler of logout: (unit -> unit)
let agent (rv: Var<int>) courtesy =
MailboxProcessor.Start(fun inbox ->
let rec loop state: Async<unit> =
let (rvCountdown, logout) = state
async {
let! msg = inbox.Receive()
match msg with
| Reset time ->
Var.Set rvCountdown time
return! loop (rvCountdown, logout)
| Tick ->
if rvCountdown.Value = courtesy then
JQuery.Of("#courtesyExpiryModal").ModalShow() |> ignore
if rvCountdown.Value = 0 then
do logout |> Option.iter(fun act -> act())
return! loop (rvCountdown, logout)
else
Var.Set rvCountdown (rvCountdown.Value - 1)
Console.Log rvCountdown.Value
return! loop (rvCountdown, logout)
| RegisterHandler (logout) ->
return! loop (rvCountdown, Some logout)
}
loop (rv, None))
let startTick (agent: MailboxProcessor<Operation>) =
async {
while true do
do! Async.Sleep 1000
do agent.Post Operation.Tick
} |> Async.Start
let countdown = Var.Create 0
let post =
let lifetime =
match TokenStorage.get(), TokenStorage.getTimeStamp() with
| Some token, Some stamp ->
let payload = Jwt.getPayload token
match payload.exp - payload.iat with
// Target time is already passed, the token is expired
| lifetime when Jwt.JwtPayload.GetTimeTarget stamp payload < 0 ->
Console.Log "Token expired."; 0
| lifetime -> lifetime
| _ ->
Console.Log "Token not found."; 0
Var.Set countdown lifetime
let courtesyWindow = 60
let agent = agent countdown courtesyWindow
startTick agent
agent.Post
let run() =
let modalOptions =
{ Id = "courtesyExpiryModal"
Title = "Your session is about to expire"
Content = div [ p [ text "Your secure session to this web portal is close to expiring."; br []; text "Please indicate whether you would prefer to remain logged in?" ]
p [ CountdownExpiryAgent.countdown.View |> View.Map (sprintf "Time remaining: %i seconds") |> Doc.TextView ] ]
PositiveAction = Title "Keep me logged in", Action (fun () -> renewToken() |> Async.Ignore)
NegativeAction = Title "Log out", Action (fun () -> async { do logout() }) }
Modal.createModal modalOptions
CountdownExpiryAgent.post (CountdownExpiryAgent.RegisterHandler logout)
Doc.Empty
@Kimserey
Copy link
Author

do CountdownExpiryAgent.post (CountdownExpiryAgent.Reset 120)

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