Skip to content

Instantly share code, notes, and snippets.

@orient-man
Last active May 16, 2017 13:56
Show Gist options
  • Save orient-man/86e93e38467590a8ec758fd1d837999c to your computer and use it in GitHub Desktop.
Save orient-man/86e93e38467590a8ec758fd1d837999c to your computer and use it in GitHub Desktop.
open System
open System.Collections.Generic
let tryGetValue (dict: IDictionary<_, _>) key = match dict.TryGetValue(key) with true, v -> Some v | _ -> None
let tryParseInt str = match Int32.TryParse(str) with true, v -> Some v | _ -> None
let calcSleepTime clock limitResetTime =
// https://support.sendgrid.com/hc/en-us/requests/1094766
// X-RateLimit-Reset = Unix timestamp = seconds since Jan 01 1970. (UTC)
let now: DateTime = clock ()
DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
.AddSeconds(float limitResetTime)
.ToLocalTime()
.Subtract(now)
.Add(TimeSpan.FromSeconds(3.))
let tryGetSleepTimeIfLimitReached clock (headers: IDictionary<_, _>) =
"X-RateLimit-Remaining"
|> tryGetValue headers
|> Option.bind tryParseInt
|> Option.filter (fun r -> r <= 0)
|> Option.bind (fun _ -> "X-RateLimit-Reset" |> tryGetValue headers)
|> Option.bind tryParseInt
|> Option.map (calcSleepTime clock)
|> Option.filter (fun t -> t > TimeSpan.Zero)
// Tests:
let stoppedClock () = DateTime(2017, 05, 16, 13, 13, 0)
// http://www.unixtimestamp.com/
[ "X-RateLimit-Remaining", "0"; "X-RateLimit-Reset", "1494933300" ] // 11:15 UTC
|> dict
|> tryGetSleepTimeIfLimitReached stoppedClock
|> Option.map (fun t -> t.TotalSeconds) // 123 sekundy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment