2013-01-25 22 views
7

Próbuję lepiej poznać program Haskell, opracowując usługi internetowe.Haskell Webserver: utrzymywanie stanu aplikacji

Załóżmy, że tworzę serwer WWW i chcę zachować stały stan między żądaniami; licznik, na przykład. Jaki jest sposób działania Haskell?

Natknąłem się na to discussion w mojej wyszukiwarce Google. Proponowane rozwiązanie wygląda na dobry przykład tego, czego nie należy robić.

Jednym z pomysłów było to, że miałem program obsługi żądania podjęcia w MVar:

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

Po rejestracji programu obsługi, może to być curry z MVar utworzony w głównym.

Musi istnieć lepszy sposób. Nie mogę przestać myśleć, że podchodzę do tego problemu w sposób niefunkcjonalny.

Dzięki!

+0

Dlaczego staramy się nieść stan trwały na samym serwerze? Wydaje mi się, że Haskell pasowałby znacznie lepiej dzięki RESTful design. –

+1

Co jest "niefunkcjonalne" w tym podejściu? Masz jakiś stan, który musisz udostępnić, więc zawijasz go i przekazujesz referencję. Wydaje mi się to całkiem proste. – sclv

+0

sclv: Zastanawiam się, czy było więcej podejścia do FRP. – David

Odpowiedz

4

Prawdopodobnie chcesz acid-state, który zapewnia dokładnie: stały stan dla typów danych Haskell. Dokumentacja, którą połączę, zaczyna się od licznika żądań, tak jak prosiłeś.

Należy pamiętać, że MVars nie są trwałe; licznik zostanie zresetowany po zrestartowaniu serwera. Jeśli to jest właśnie to zachowanie, które chcesz, proponuję użyć zamiast tego TVar; w ten sposób można aktualizować licznik atomowo bez blokad lub ryzyko wystąpienia zakleszczeń, które z nimi idą.

1

Jeśli podoba Ci się utrwalanie i seriale telewizyjne, możesz użyć DBRefs, które mają tę samą semantykę i takie same wzorce korzystania, jak seriale. Musisz zdefiniować unikalny klucz dla stanu i masz automatyczne utrzymywanie plików. Do utrzymywania bazy danych konieczne jest zdefiniowanie instancji IResource.

Państwo będzie mieć unikalny licznik dla każdej sesji:

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) 
Powiązane problemy