I'm trying to get more familiar with Haskell by developing web-app-ish services.
Say I'm developing a web-server and I want to keep persistent state between requests; a counter, for instance. What is the Haskell way of doing things?
I came across this discussion on my Google search. The proposed solution looks like a good example of what not to do.
One idea I had was having the request handler take in an MVar:
requestHandler :: MVar State -> IO (Maybe Response)
When registering the handler, it could be curried with an MVar created in main.
There must be a better way. I can't help but think I'm approaching this problem in a non-functional way.
Thanks!
You probably want acid-state, which gives you that exactly: persistent state for Haskell data types. The documentation I linked even starts out with a request counter, just like you asked for.
Note that MVars are not persistent; the counter would get reset when the server is restarted. If that's actually the behavior you want I suggest you use a TVar instead; that way you can update the counter atomically without locks or the risk of deadlocks that go with them.
If you like persistence and TVars, you can use DBRefs, that have the same semantics and the same usage patterns as TVars. You must define a unique key for the state and you have automatic file persistence. For database persistence it is necessary to define an IResource instance.
The state will have a unique counter for each session:
import Data.Map as M
import Data.TCache
import Data.TCache.DefaultPersistence
type Counter= Int
type SessionId :: String
data State= State SessionId Counter deriving (Read, Show, Typeable)
instance Indexable State where
key (State k _)= k
requestHandler :: Request -> DBRef State -> IO (Maybe Response)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With