Re: [Haskell-cafe] HSGI: Haskell Server Gateway Interface

[Original discussion in haskell-cafe: http://www.haskell.org/pipermail/haskell-cafe/2009-February/055270.html] Manlio Perillo:
Here are the problems:
1) supported HTTP methods are fixed, since you use a custom data type
(Btw. It is not my proposal, Johan Tibell has written it. I'll mail him to notify him about this discussion.) I agree with that. In my own framework prototype i have data HttpMethod = OPTIONS | GET | HEAD | POST | PUT | DELETE | TRACE | CONNECT | Extension String deriving (Eq, Show)
2) no support for other possible CGI variables (or simply custom variables: I use the environ dictionary to store application configuration, and I think it is a great thing).
A user dictionary / association list could be useful. A Trie is probably faster than a Map so i am not sure if the Map type should be used. Could also be implemented by the frameworks themselves.
3) No support for optimized file serving, like with WSGI file_wrapper
Would be nice to have provided it is cross-platform.
4) No support for keeping "complex" state (like database connection) in the environ.
I have read some examples with CGI package, where a custom monad transformer is used. I'm not sure if this solution is flexible and "scalable".
This should be a task for the framework itself. Using a ReaderT or StateT transformer is very common in Haskell.
5) I can't find documentation about the type of the response. It is rather clear that it is (ByteString, [(ByteString, ByteString)], Enumerator)
but this should be documented somewhere.
It's a wiki so feel free to change it or add more documentation. About the enumerator, using it is indeed debatable because it is not immediately obvious how it works, but i haven't seen anything for Haskell that works better. Like other haskellers have said lazy bytestrings with IO is asking for trouble. I have been bitten by it myself and it is hard to debug. Imho lazy bytestrings are only useful when the data generator is a pure function. Regards, Felix

Felix Martini ha scritto:
[Original discussion in haskell-cafe: http://www.haskell.org/pipermail/haskell-cafe/2009-February/055270.html]
Manlio Perillo:
Here are the problems:
1) supported HTTP methods are fixed, since you use a custom data type
(Btw. It is not my proposal, Johan Tibell has written it. I'll mail him to notify him about this discussion.)
I agree with that. In my own framework prototype i have
data HttpMethod = OPTIONS | GET | HEAD | POST | PUT | DELETE | TRACE | CONNECT | Extension String deriving (Eq, Show)
+1
2) no support for other possible CGI variables (or simply custom variables: I use the environ dictionary to store application configuration, and I think it is a great thing).
A user dictionary / association list could be useful. A Trie is probably faster than a Map so i am not sure if the Map type should be used. Could also be implemented by the frameworks themselves.
Let the framework handle the configuration data is what most of the Python web framework do. I personally prefer to have the configuration data stored in the environ dictionary.
3) No support for optimized file serving, like with WSGI file_wrapper
Would be nice to have provided it is cross-platform.
It needs not to be cross platform. See how WSGI file_wrapper is implemented. You just need to pass to the server a file Handle (and optionally an offset). If the server does not support sendfile, or memory mapped files, it can just iterate over the file and sends each chunk to the client.
4) No support for keeping "complex" state (like database connection) in the environ.
I have read some examples with CGI package, where a custom monad transformer is used. I'm not sure if this solution is flexible and "scalable".
This should be a task for the framework itself. Using a ReaderT or StateT transformer is very common in Haskell.
How is this "composable"? Let's assume we have a "big" application. As an example an application with multiple url dispatchers: /a -> /ax -> /ay /b -> /bx -> /by Of course I would like to setup the connection on only one place. Storing the connection in the WAI environment is handy. Of course you still need a ReaderT or StateT transformer, but your state is all in one place. Can you post an example? Thanks.
5) I can't find documentation about the type of the response. It is rather clear that it is (ByteString, [(ByteString, ByteString)], Enumerator)
but this should be documented somewhere.
It's a wiki so feel free to change it or add more documentation.
About the enumerator, using it is indeed debatable because it is not immediately obvious how it works, but i haven't seen anything for Haskell that works better. Like other haskellers have said lazy bytestrings with IO is asking for trouble. I have been bitten by it myself and it is hard to debug. Imho lazy bytestrings are only useful when the data generator is a pure function.
Well, I find the enumerator "story" quite strange. It is the best idea available, it is "quite old", however I can't see it largely in use. There is not even a chapter about it in the Real World Haskell.
Regards, Felix
Regards Manlio
participants (2)
-
Felix Martini
-
Manlio Perillo