
Hello, café. Recently I asked about tcp server libraries [1] and there was only one answer haskell-scallable-server [2], but in that package there was some dependencies and server logic that are not good for my task. So I decided to make a library with skeletons for different types of tcp servers and a basic library to make server [3]. Now there is only warp based (simplified) tcp server. Main logic is: * handle new connection and start iteratee green thread * enumerator (library side) reads socket and send data into enumeratee (application side) * enumeratee consumes input and produces server command (now simply output) and push it into iteratee (server side) * iteratee server side reads command and performs action (now simply output command) It gives application possibility to store state in enumerator. My questions to community: 1). can you help to make code better ;) maybe there are some stupid mistakes 2). is there any ideas what thing can be add to the server to make it reusable And another thing that I want to add other types of server e.g. single threaded, with workers pool, or other types. And I want to ask what types of servers will be effective in haskell. [1] http://www.haskell.org/pipermail/haskell-cafe/2012-January/098594.html [2] https://github.com/jamwt/haskell-scalable-server [3] https://github.com/qnikst/TcpServers -- Alexander V Vershilov.

Hello, On 27.01.2012, at 00:47, Alexander V Vershilov wrote:
Recently I asked about tcp server libraries [1] and there was only one answer haskell-scallable-server [2], but in that package there was some dependencies and server logic that are not good for my task.
A simple search for "server" on Hackage turned up the following packages for somewhat generic server infrastructure: http://hackage.haskell.org/package/iterio-server http://hackage.haskell.org/package/generic-server http://hackage.haskell.org/package/c10k http://hackage.haskell.org/package/network-server In issue 19 of The Monad Reader is an article discussing the design of the following web server: http://hackage.haskell.org/package/mighttpd2 This links might be relevant to your original question.
So I decided to make a library with skeletons for different types of tcp servers and a basic library to make server [3].
Now there is only warp based (simplified) tcp server. Main logic is: * handle new connection and start iteratee green thread * enumerator (library side) reads socket and send data into enumeratee (application side) * enumeratee consumes input and produces server command (now simply output) and push it into iteratee (server side) * iteratee server side reads command and performs action (now simply output command) It gives application possibility to store state in enumerator.
My questions to community: 1). can you help to make code better ;) maybe there are some stupid mistakes 2). is there any ideas what thing can be add to the server to make it reusable
I think there is still no consensus on which iteratee library is the one to use. There are at least iteratee, enumerator, iterIO, conduit, and pipes. The reusability of your libary depends on the choice of iteratee-style library you select. Jean

Straightforward to use, but unfortunately uses "unix" package. I take it it is not portable. However its first version did not use it, so maybe the concerned part could be rewritten.
I think there is still no consensus on which iteratee library is the one to use. There are at least iteratee, enumerator, iterIO, conduit, and pipes. The reusability of your libary depends on the choice of iteratee-style library you select.
Yes, and IMO this is a growing problem. Since iteratees were designed, a
lot of different libraries providing this kind of service have appeared.
Of course they all have advantages and inconvenients, but some libraries
that could be compatible are not, because they rely on a different
iteratee-ish package. For instance pipes (as its documentation states) is
really like iteratee... but with more concrete names. Still it's sufficient
to break compatibility.
Or else, we have to make sure that each one (iteratee, enumerator, conduit,
pipes...) has its own set of associated packages and that each provide
equivalent functionalities, but then => combinatorial explosion.
^^ It's just I don't want people to start trolling by applying to Haskell
the adage I've heard quite a few times about Java, stating that "There are
50 ways to achieve something... none of which is good".
2012/1/28 Jean-Marie Gaillourdet
Hello,
On 27.01.2012, at 00:47, Alexander V Vershilov wrote:
Recently I asked about tcp server libraries [1] and there was only one answer haskell-scallable-server [2], but in that package there was some dependencies and server logic that are not good for my task.
A simple search for "server" on Hackage turned up the following packages for somewhat generic server infrastructure:
http://hackage.haskell.org/package/iterio-server http://hackage.haskell.org/package/generic-server http://hackage.haskell.org/package/c10k http://hackage.haskell.org/package/network-server
In issue 19 of The Monad Reader is an article discussing the design of the following web server: http://hackage.haskell.org/package/mighttpd2
This links might be relevant to your original question.
So I decided to make a library with skeletons for different types of tcp servers and a basic library to make server [3].
Now there is only warp based (simplified) tcp server. Main logic is: * handle new connection and start iteratee green thread * enumerator (library side) reads socket and send data into enumeratee (application side) * enumeratee consumes input and produces server command (now simply output) and push it into iteratee (server side) * iteratee server side reads command and performs action (now simply output command) It gives application possibility to store state in enumerator.
My questions to community: 1). can you help to make code better ;) maybe there are some stupid mistakes 2). is there any ideas what thing can be add to the server to make it reusable
I think there is still no consensus on which iteratee library is the one to use. There are at least iteratee, enumerator, iterIO, conduit, and pipes. The reusability of your libary depends on the choice of iteratee-style library you select.
Jean
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Yves Parès wrote:
Yes, and IMO this is a growing problem. Since iteratees were designed, a lot of different libraries providing this kind of service have appeared.
Thats mainly because the solution space was new and lots of unexplored terrain.
Or else, we have to make sure that each one (iteratee, enumerator, conduit, pipes...) has its own set of associated packages and that each provide equivalent functionalities, but then => combinatorial explosion.
There really isn't a combinatorial explosion, but rather a small number of families of packages.
^^ It's just I don't want people to start trolling by applying to Haskell the adage I've heard quite a few times about Java, stating that "There are 50 ways to achieve something... none of which is good".
Java has been around 20 years. The iteratee/enumerator/iterio/conduit/pipes idea has really only been around for a couple of years and I would be surprised it one of them (or a new one combining the best features of the others) doesn't come out the clear winner in the next year or two. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/

Yes, I was forecasting a little...
Concerning conduit, yes it's not another implementation of Oleg's
iteratees, yet its API looks a lot like 'enumerators'.
Plus it aims at solving the same problem, only the implementation that
differs (roughly state variables instead of pure closure-based automata)
2012/1/28 Erik de Castro Lopo
Yves Parès wrote:
Yes, and IMO this is a growing problem. Since iteratees were designed, a lot of different libraries providing this kind of service have appeared.
Thats mainly because the solution space was new and lots of unexplored terrain.
Or else, we have to make sure that each one (iteratee, enumerator, conduit, pipes...) has its own set of associated packages and that each provide equivalent functionalities, but then => combinatorial explosion.
There really isn't a combinatorial explosion, but rather a small number of families of packages.
^^ It's just I don't want people to start trolling by applying to Haskell the adage I've heard quite a few times about Java, stating that "There are 50 ways to achieve something... none of which is good".
Java has been around 20 years. The iteratee/enumerator/iterio/conduit/pipes idea has really only been around for a couple of years and I would be surprised it one of them (or a new one combining the best features of the others) doesn't come out the clear winner in the next year or two.
Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Sat, Jan 28, 2012 at 9:40 AM, Yves Parès
I think there is still no consensus on which iteratee library is the one to use. There are at least iteratee, enumerator, iterIO, conduit, and pipes. The reusability of your libary depends on the choice of iteratee-style library you select.
Yes, and IMO this is a growing problem. Since iteratees were designed, a lot of different libraries providing this kind of service have appeared. Of course they all have advantages and inconvenients, but some libraries that could be compatible are not, because they rely on a different iteratee-ish package. For instance pipes (as its documentation states) is really like iteratee... but with more concrete names. Still it's sufficient to break compatibility.
Or else, we have to make sure that each one (iteratee, enumerator, conduit, pipes...) has its own set of associated packages and that each provide equivalent functionalities, but then => combinatorial explosion.
I find it funny that conduit is said to be an iteratee library since it has no iteratees! We've had more than one iteratee library since at least 1.5 years with the iteratee (Mar 2009) and enumerator (Aug 2010) packages, and AFAIK now we have four iteratee libraries: those two, iterIO (May 2011) and pipes (Jan 2012). However, conduit is not the fifth since it has no iteratees, no enumerators, no enumeratees... it's a different concept, not a different implementation. In principle it's possible to have some code that converts functions between these different iteratee packages -- at least between iteratee, enumerator and iterIO since these seem to have more or less the same implementation ideas. Converting from pipes may be possible, but to pipes seems pretty difficult since pipes sweeps IO under the rug. Cheers, -- Felipe.

Felipe Almeida Lessa wrote:
I find it funny that conduit is said to be an iteratee library since it has no iteratees! We've had more than one iteratee library since at least 1.5 years with the iteratee (Mar 2009) and enumerator (Aug 2010) packages, and AFAIK now we have four iteratee libraries: those two, iterIO (May 2011) and pipes (Jan 2012). However, conduit is not the fifth since it has no iteratees, no enumerators, no enumeratees... it's a different concept, not a different implementation.
I mostly agree, but I think the real strength of Conduits is that it removes a lot of the complexity of the other Iteratee libraries. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/

On 28.01.2012, at 12:56, Felipe Almeida Lessa wrote:
I find it funny that conduit is said to be an iteratee library since it has no iteratees! We've had more than one iteratee library since at least 1.5 years with the iteratee (Mar 2009) and enumerator (Aug 2010) packages, and AFAIK now we have four iteratee libraries: those two, iterIO (May 2011) and pipes (Jan 2012). However, conduit is not the fifth since it has no iteratees, no enumerators, no enumeratees... it's a different concept, not a different implementation.
But it does try to solve the problem, doesn't it? Obviously conduit is an alternative to the iteratee-like packages. Why else would Yesod replace enumerator by conduit? That is the reason why I added it into my list of iteratee-like packages. Jean

On Sun, Jan 29, 2012 at 10:14 AM, Jean-Marie Gaillourdet
But it does try to solve the problem, doesn't it? Obviously conduit is an alternative to the iteratee-like packages. Why else would Yesod replace enumerator by conduit? That is the reason why I added it into my list of iteratee-like packages.
I'm sorry if I misunderstood your message. I read your e-mail as though you were saying that the choice between these libraries has only to do with your taste, and your taste will decide the other libraries with which yours may interoperate. This may be true between iteratee, enumerator and iterIO (module some specific features of each one of them), but that's not true for pipes (since it doesn't handle IO at all right now) and conduit (since it has a different concept despite having the same goal). Cheers, =) -- Felipe.

On Sun, Jan 29, 2012 at 2:21 PM, Felipe Almeida Lessa
On Sun, Jan 29, 2012 at 10:14 AM, Jean-Marie Gaillourdet
wrote: But it does try to solve the problem, doesn't it? Obviously conduit is an alternative to the iteratee-like packages. Why else would Yesod replace enumerator by conduit? That is the reason why I added it into my list of iteratee-like packages.
I'm sorry if I misunderstood your message. I read your e-mail as though you were saying that the choice between these libraries has only to do with your taste, and your taste will decide the other libraries with which yours may interoperate. This may be true between iteratee, enumerator and iterIO (module some specific features of each one of them), but that's not true for pipes (since it doesn't handle IO at all right now) and conduit (since it has a different concept despite having the same goal).
In case anyone's looking for comparisons between conduit and enumerator, I wrote up my most recent thoughts on Reddit[1]. Michael [1] http://www.reddit.com/r/haskell/comments/p1iu0/exciting_changes_coming_to_co...

On 12-01-28 06:56 AM, Felipe Almeida Lessa wrote:
On Sat, Jan 28, 2012 at 9:40 AM, Yves Parès
wrote: I think there is still no consensus on which iteratee library is the one to use. There are at least iteratee, enumerator, iterIO, conduit, and pipes. The reusability of your libary depends on the choice of iteratee-style library you select.
Yes, and IMO this is a growing problem. Since iteratees were designed, a lot of different libraries providing this kind of service have appeared. Of course they all have advantages and inconvenients, but some libraries that could be compatible are not, because they rely on a different iteratee-ish package. For instance pipes (as its documentation states) is really like iteratee... but with more concrete names. Still it's sufficient to break compatibility.
In principle it's possible to have some code that converts functions between these different iteratee packages -- at least between iteratee, enumerator and iterIO since these seem to have more or less the same implementation ideas.
It's not only possible, it's done. The coroutine-enumerator and coroutine-iteratee packages convert to and from the enumerator and iteratee packages, using monad-coroutine as a bridge. The conversions are bare-bone, and I don't know if anybody has ever used them in practice. They still prove the concept.
Converting from pipes may be possible, but to pipes seems pretty difficult since pipes sweeps IO under the rug.
A Pipe appears to be just a specialized Coroutine from the monad-coroutine package with its type arguments expanded, so it would also be convertible. -- Mario Blazevic mblazevic@stilo.com Stilo International This message, including any attachments, is for the sole use of the intended recipient(s) and may contain confidential and privileged information. Any unauthorized review, use, disclosure, copying, or distribution is strictly prohibited. If you are not the intended recipient(s) please contact the sender by reply email and destroy all copies of the original message and any attachments.

Hello. -- Resending reply to maillistmail Sat, Jan 28, 2012 at 11:51:32AM +0100, Jean-Marie Gaillourdet wrote
Hello,
On 27.01.2012, at 00:47, Alexander V Vershilov wrote:
Recently I asked about tcp server libraries [1] and there was only one answer haskell-scallable-server [2], but in that package there was some dependencies and server logic that are not good for my task.
A simple search for "server" on Hackage turned up the following packages for somewhat generic server infrastructure:
http://hackage.haskell.org/package/iterio-server http://hackage.haskell.org/package/generic-server http://hackage.haskell.org/package/c10k http://hackage.haskell.org/package/network-server
In issue 19 of The Monad Reader is an article discussing the design of the following web server: http://hackage.haskell.org/package/mighttpd2
This links might be relevant to your original question.
Thanks I've checked code as sow interesting solutions, maybe I'll ask some more questions about desicions. As I see all servers uses accept-forkIO i.e. one green-thread to accept sockets and then runs another thread for each connection, in this thread function from ServerOptions is run, that function read Socket/Handle itself. Also I've seen another way of implemeting server [http://sequence.complete.org/node/258] in this solution author also uses accept-forkIO style to create workers, but main thread is used for all socket IO, i.e. accepting, reading and writing data back, this server uses STM channels to send data between threads, as I see this is orthogonal way of dealing with server. I'm interested if there is some more ways that are more affectfull in some cases that accept-forkIO(socketIO) or accept(socketIO)-forkIO.
Jean
-- Alexander V Vershilov

On Sat, Jan 28, 2012 at 12:51 PM, Jean-Marie Gaillourdet
Hello,
On 27.01.2012, at 00:47, Alexander V Vershilov wrote:
Recently I asked about tcp server libraries [1] and there was only one answer haskell-scallable-server [2], but in that package there was some dependencies and server logic that are not good for my task.
A simple search for "server" on Hackage turned up the following packages for somewhat generic server infrastructure:
http://hackage.haskell.org/package/iterio-server http://hackage.haskell.org/package/generic-server http://hackage.haskell.org/package/c10k http://hackage.haskell.org/package/network-server
In issue 19 of The Monad Reader is an article discussing the design of the following web server: http://hackage.haskell.org/package/mighttpd2
This links might be relevant to your original question.
I just pushed a new version of network-conduit[1] that adds a light-weight TCP server/client interface. It's very similar to how Warp it structured (which is the underlying engine for mighttpd2). I put together a simple example of a server[2] that simply echos back whatever you send it, and a client[3] that sends a Fibonacci every second. I hope this helps, let me know if you have any questions. Michael [1] http://hackage.haskell.org/package/network-conduit . Sorry, Haddocks haven't generated yet [2] https://github.com/snoyberg/conduit/blob/master/network-conduit/echo-server.... [3] https://github.com/snoyberg/conduit/blob/master/network-conduit/fibclient.hs
participants (7)
-
Alexander V Vershilov
-
Erik de Castro Lopo
-
Felipe Almeida Lessa
-
Jean-Marie Gaillourdet
-
Mario Blažević
-
Michael Snoyman
-
Yves Parès