I'm building a REST backend that requires a large collection of values to compute the answers. This collection is downloaded at boot time and then on demand but needs to be updated a few times per day. I can't figure out how to cope with this mutable state. I've tried both ref and mutable variables in the main function but the old collection never gets released and memory usage grows without control.
What is the correct way of dealing with this mutable state?
EDIT
While preparing a sample of what I'm doing I found the first bug. I was doing:
let sqlfeed() =
use cmd = new SqlFeedType(connectionString)
Some (cmd.Execute() |> Seq.toList)
Now I'm doing I'm doing something like this:
let sqlfeed() =
Some (using (new SqlFeedType(connectionString)) (fun cmd -> cmd.Execute() |> Seq.toList))
Then
[<EntryPoint>]
let main argv =
let optionSqlFeed = ref None
let app =
choose [
Filters.path "/sqlfeed" >=> warbler (fun ctx ->
match !optionSqlFeed with
| None ->
optionSqlFeed := sqlfeed()
| Some a ->
optionSqlFeed := None
Successful.OK "done" )
]
startWebServer defaultConfig app
Before, when I called sqlfeed and the data was downloaded I saw the memory go up. On successive calls with alternating assignments to None, memory wouldn't be released and the total usage just climbed. Now, when I call sqlfeed and assign None to the mutable variable, the memory still does not get released, but upon the next call to sqlfeed the memory is released.
Why won't the memory be released when I assign None, but will be released when I call sqlfeed again?