2013-01-25 13 views
7

Ich versuche, Haskell durch die Entwicklung von Web-App-ish-Dienste vertraut zu machen.Haskell Webserver: Anwendungsstatus beibehalten

Angenommen, ich entwickle einen Web-Server und möchte den persistenten Status zwischen den Anforderungen beibehalten. ein Zähler zum Beispiel. Was ist der Haskell-Weg, Dinge zu tun?

Ich stieß auf diese discussion auf meiner Google-Suche. Die vorgeschlagene Lösung sieht wie ein gutes Beispiel dafür aus, was nicht zu tun ist.

Eine Idee, die ich hatte in einem MVar des Request-Handler nehmen habe:

requestHandler :: MVar State -> IO (Maybe Response) 

Wenn die Prozedur der Registrierung, könnte es mit einem MVar curried wird in Haupt erstellt.

Es muss einen besseren Weg geben. Ich kann nicht anders, als zu denken, dass ich dieses Problem nicht funktional angehen würde.

Danke!

+0

Warum versucht persistenten Zustand auf dem Server selbst zu tragen? Scheint mir, Haskell würde viel besser mit einem RESTful Design zusammenpassen. –

+1

Was ist bei diesem Ansatz "nicht funktional"? Sie haben einen Zustand, den Sie teilen müssen, also wickeln Sie ihn ein und übergeben Sie die Referenz. Scheint ziemlich einfach für mich. – sclv

+0

sclv: Ich frage mich, ob es mehr von einem FRP-Ansatz war. – David

Antwort

4

Wahrscheinlich möchten Sie acid-state, die Ihnen genau das gibt: persistenter Zustand für Haskell-Datentypen. Die Dokumentation, die ich verlinkt habe, beginnt sogar mit einem Anfragezähler, genau wie du es verlangst.

Beachten Sie, dass MVars nicht persistent sind; Der Zähler wird zurückgesetzt, wenn der Server neu gestartet wird. Wenn das das Verhalten ist, das Sie wollen, schlage ich vor, dass Sie stattdessen eine TVar verwenden; Auf diese Weise können Sie den Counter atomar ohne Sperren oder das Risiko von Deadlocks aktualisieren, die zu ihnen gehören.

1

Wenn Sie Persistenz und TVars mögen, können Sie DBRefs verwenden, die die gleiche Semantik und die gleichen Nutzungsmuster wie TVars haben. Sie müssen einen eindeutigen Schlüssel für den Status definieren und verfügen über eine automatische Dateipersistenz. Für die Datenbankpersistenz muss eine IResource-Instanz definiert werden.

Der Staat wird für jede Sitzung einen eindeutigen Zähler hat:

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)