Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Webserver: maintaining application state

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!

like image 700
David Avatar asked Jan 25 '13 19:01

David


2 Answers

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.

like image 138
Dag Avatar answered Nov 18 '22 07:11

Dag


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)
like image 1
agocorona Avatar answered Nov 18 '22 08:11

agocorona