2013-01-25 11 views
7

Sto cercando di acquisire familiarità con Haskell sviluppando servizi Web-app-ish.Haskell Webserver: mantenimento dello stato dell'applicazione

Dire che sto sviluppando un server Web e voglio mantenere lo stato persistente tra le richieste; un contatore, per esempio. Qual è il modo Haskell di fare le cose?

Mi sono imbattuto in questo discussion sulla mia ricerca Google. La soluzione proposta sembra un buon esempio di cosa non fare.

Un'idea che avevo stavo avendo il gestore di richieste prendere in MVAR:

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

Quando si registra il gestore, potrebbe essere al curry con un MVAR creato nel principale.

Ci deve essere un modo migliore. Non posso fare a meno di pensare che mi sto avvicinando a questo problema in modo non funzionale.

Grazie!

+0

Perché cercare di portare lo stato persistente sul server stesso? Sembra che Haskell si abbinerebbe molto meglio con un design RESTful. –

+1

Che cos'è "non funzionale" per questo approccio? Hai uno stato che devi condividere, quindi lo avvolgi e passa attorno al riferimento. A me sembra piuttosto semplice. – sclv

+0

sclv: Mi chiedo se ci sia stato più di un approccio FRP. – David

risposta

4

Probabilmente si desidera acid-state, che fornisce esattamente questo: stato permanente per i tipi di dati Haskell. La documentazione che ho collegato inizia anche con un contatore di richieste, proprio come richiesto.

Si noti che MVars non sono persistenti; il contatore verrebbe reimpostato al riavvio del server. Se questo è effettivamente il comportamento che vuoi ti consiglio di usare un TVar invece; in questo modo è possibile aggiornare il contatore atomicamente senza serrature o il rischio di deadlock che vanno con loro.

1

Se ti piacciono persistenza e TVars, è possibile utilizzare DBRefs, che hanno la stessa semantica e gli stessi modelli di utilizzo di TVars. È necessario definire una chiave univoca per lo stato e la persistenza automatica dei file. Per la persistenza del database è necessario definire un'istanza IResource.

Lo Stato avrà un contatore unico per ogni sessione:

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) 
Problemi correlati