[Haskell-cafe] Waiting on input with `hWaitForInput' or `threadWaitRead'
Jason Dusek
jason.dusek at gmail.com
Tue Oct 18 03:18:01 CEST 2011
2011/10/17 Ertugrul Soeylemez <es at ertes.de>:
> Jason Dusek <jason.dusek at gmail.com> wrote:
>> I would like to use evented I/O for a proxying application.
>> My present thinking is to fork a thread for each new
>> connection and then to wait for data on either socket in this
>> thread, writing to one or the other socket as needed.
>>
>> [...]
>>
>> Ideally, I'd get something like select() on handles, just
>> saying whether there are bytes or not. However, I haven't
>> managed to find anything like that in the standard libraries.
>
> I don't think you want either of the functions you mentioned.
> What you probably want instead is to do concurrent
> programming by creating Haskell threads. A hundred Haskell
> threads reading from Handles are translated to one or more OS
> threads using whatever polling mechanism (select(), poll(),
> epoll) your operating system supports.
>
> I have uploaded a simple concurrent echo server implementation
> to hpaste [1]. It uses one thread for the stdout logger, one
> thread for the server, one thread for each client and finally
> a main thread waiting for you to hit enter to quit the
> application.
>
> [1] http://hpaste.org/52742 - Concurrent echo server with logger
I am not sure how to apply the principle you mention to a proxy,
which must read from and write to both handles in turn (or,
ideally, as needed).
Here's a little demo that uses hWaitForInput and strict
ByteStrings as well as plain hGetContents with lazy ByteStrings:
http://hpaste.org/52777
You can load it in GHC and try out the strict/hWaitForInput
version like this:
> proxy (PortNumber 9001) (PortNumber 9000) strictBridge
Then run, in this order, in two terminals:
:; nc -l -k 9000 # The proxied backend server.
:; nc localhost 9001 # The nominal client.
Now you can type text on the client side, hit return and see it
on the server side and then vice versa.
The lazy bridging code, `lazyBridge', blocks (unsurprisingly)
and does not allow packets to go back and forth. I think I need
explicit selects/waits here to get the back and forth traffic.
Maybe there is a some way to leverage GHC's internal async I/O
but I'm not sure how to do it.
--
Jason Dusek
() ascii ribbon campaign - against html e-mail
/\ www.asciiribbon.org - against proprietary attachments
More information about the Haskell-Cafe
mailing list