
I'm interested in FRP, have read several of the papers and am wondering if it could be applied to writing multi-client server programs. What would be the input type events for such a system? What would be the output type events? How would the system handle the fact that it has to multiplex several IO streams (sockets)? I'm trying to answer these questions myself and having a hard time. Should input events include new connection requests and shutdowns? Individual bytes? Streams of bytes? or higher level PDUs? What kind of output should be generated? Full PDUs? streams of bytes? Pairs of (connection identifier,data)? How would such a system effectively hide the multiplexed IO going on? Is this sort of problem poorly suited for FRP? Tim Newsham http://www.thenewsh.com/~newsham/

Hi,
I'm interested in FRP, have read several of the papers and am wondering if it could be applied to writing multi-client server programs.
That's funny: in the last few months, I have developed a functional-reactive framework for large scale distributed system programming. You can find the source code and a technical report here: http://perso.eleves.bretagne.ens-cachan.fr/~dagand/opis/ This code is in OCaml but the concepts can be translated in Haskell: advised by Conal Elliott, I have already written the core of Opis in Haskell (i.e the Arrow instances and a small network simulator) to ensure the feasibility of a purely functional implementation. The implementation in Haskell is based on the Mealy automaton while my code in OCaml efficiently emulates this construct (based on suggestions of Zheng Li, Oleg Kiselyov and Jacques Garrigue).
What would be the input type events for such a system? What would be the output type events? How would the system handle the fact that it has to multiplex several IO streams (sockets)?
In my system, the input events are network events -- such as a received TCP message or a UDP packet as well as notifications (connection closed, listening on port X, ...) -- or timer events -- such as "a timer has just fired", "the timer is correctly set up" or "the timer has been removed" -- or user events -- whatever the user wants to signal. The outputs are commands to the "launcher" system: the launcher will collect these outputs and interpret them in term of (side-effecting) actions. For example, the reactive function might ask to "send the data D to peer x": thus, the launcher will connect to x, marshal the data and send it to x. Similarly, you can ask to listen on a network port, set up a timer, send an event to the user, ... The multiplexing is done out of the reactive function, in the launcher system. For networking, for instance, it opens one thread per open connection. Once a thread has retrieved a complete message, it sends it to reactive processing by a "Chan" (in Control.Concurrent). I hope the technical report is clearer than this rough description. I can send you a more "haskeller-friendly" paper if you are interested.
Should input events include new connection requests and shutdowns?
New connection requests are silent whereas a connection shutdown raises an input event.
Individual bytes? Streams of bytes? or higher level PDUs? What kind of output should be generated? Full PDUs? streams of bytes? Pairs of (connection identifier,data)?
I work at the message level. For instance, the reactive function outputs "Send( destination_ip , TCP, data )", then the launcher marshals "data" and sends it to "destination_ip". On the other side, the launcher marshals the received buffer of bytes to the same type and transmits "TCP_in( source_ip , data )" to the reactive function. Hence, for the reactive function, values are typed "end-to-end", hence reducing the risk of error in marshaling.
How would such a system effectively hide the multiplexed IO going on?
Personally, I chose to hide this multiplexing on the "launcher" side, ie. out of the reactive function. As the "launcher" side is developed once and for all (by me), a Opis' user will not have to deal with multiplexing: she just has to care with processing well-defined inputs by reacting with the correct outputs.
Is this sort of problem poorly suited for FRP?
According to my experience, developing peer-to-peer systems in Opis has been a great pleasure, because of its simplicity. On the other hand, my architecture is based on the Arrow type to build the reactive functions. Hence, I work hand-in-hand with the type-checker. When developing a protocol in Opis, it is sometimes like working with a theorem prover: if you forget that a given event could occur, the type-checker complains, for example. Hence, in the P2P field, my tool is a complete alien: people say that it looks great but don't want to invest time to learn it... :-( The "side-effects" of using purely functional structures are plentiful (and well-known here): ease of debugging of pure functions, modularity (given a reactive function, I can run it live on a network, simulate, debug, or model-check it without modification), ease of backtracking (useful for the debugger and the model-checker), reproducibility (see the complexity profiler), provability (see the use of Isabelle's certified code), and so on ... Currently, I'm developing a complete formalisation of the Mealy arrow instance in Coq and, hopefully, one day, I will be able to develop a complete P2P protocol in Coq ;-) Hope this inspires you, Regards, -- Pierre-Evariste DAGAND http://perso.eleves.bretagne.ens-cachan.fr/~dagand/

2008/8/20, Jason Dusek
What's the Haskeller friendly paper?
This version of the paper was submitted to ICFP this year (and was rejected): http://perso.eleves.bretagne.ens-cachan.fr/~dagand/opis/icfp_paper.pdf In the technical report, we tried to address ICFP reviewers' comments. Sadly for us haskellers, a reviewer was strongly opposed to the use of Haskell to present a project in OCaml. That's why we decided to only use OCaml in the technical report. The core Arrow implementation and the structure of launchers did not changed a lot. However, we corrected the definition of timers to be simpler and fixed a problem with the random number embedding. Also, the term "multiplexer" in this paper corresponds to "launcher" in the technical report. My adviser did not liked the word "multiplexer". If people here are interested in an Haskell-Opis (HOpis ?), I would gladly put my current Haskell implementation on a public repository and start translating the OCaml code in Haskell. Regards, -- Pierre-Evariste DAGAND http://perso.eleves.bretagne.ens-cachan.fr/~dagand/

pedagand:
2008/8/20, Jason Dusek
: What's the Haskeller friendly paper?
This version of the paper was submitted to ICFP this year (and was rejected):
http://perso.eleves.bretagne.ens-cachan.fr/~dagand/opis/icfp_paper.pdf
In the technical report, we tried to address ICFP reviewers' comments. Sadly for us haskellers, a reviewer was strongly opposed to the use of Haskell to present a project in OCaml. That's why we decided to only use OCaml in the technical report.
That's so cool. :) Were you using Haskell as the pseudocode? -- Don

Were you using Haskell as the pseudocode?
Actually, in the ICFP paper mentionned above, we describe the most important parts of our Arrow implementation and then wrote a complete tutorial on 2.5 pages. So, that was not pseudocode but real, executable code. However, we did not use the Arrow syntax, to simplify the translation in other languages. Using Haskell was motivated (on a suggestion of Conal Elliott) to prove the purity of our solution and that our constructs actually instanciate Arrow and its friends. Btw, for those of you interested in the Arrow instance, including Mealy, Conal Elliott blog [http://conal.net/blog/] is a must-read. -- Pierre-Evariste DAGAND http://perso.eleves.bretagne.ens-cachan.fr/~dagand/

I think FRP is well-suited to this problem; it lets you abstract out
the imperative network code from the "reactive core" of the code. The
network code can live in a separate thread that uses select() and
listen(), and updates event streams.
I was thinking about writing a MUD using FRP; in my mind, the
framework looked something like this:
-- A connection is
-- 1) An event that fires once when the connection is closed
-- 2) An event that fires each time a line is received over the connection
-- 3) A routine that outputs a line to that connection
-- 4) A routine that closes the conection
data Connection = Conn
{ connClosed :: Event ()
, connLines :: Event String
, connWrite :: String -> IO ()
, connDisconnect :: IO ()
}
-- Listen on a given port for connections and return them as an FRP
event stream.
-- Since Connection contains an event stream, this is going
-- to be a nested event; we will use join/>>= on Event at some point to get the
-- commands from each connection
listen :: Int -> IO (Event Connection)
-- the server is an FRP program that outputs an event stream of IO actions;
-- the actions will generally just be "write a message to a particular socket"
server :: Event Connection -> Event (IO ())
-- Now main is trivial to implement, given sinkE from Conal's FRP paper
-- http://conal.net/papers/simply-reactive/
-- sinkE :: (a -> IO ()) -> Event a -> IO ()
main = listen 4200 >>= sinkE id . server
-- An example server that writes "hello world" to each client and
disconnects them
server conns = do
connection <- conns
return $ do
connWrite connection "Hello World."
connDisconnect connection
-- ryan
On Sun, Aug 17, 2008 at 2:26 PM, Tim Newsham
I'm interested in FRP, have read several of the papers and am wondering if it could be applied to writing multi-client server programs. What would be the input type events for such a system? What would be the output type events? How would the system handle the fact that it has to multiplex several IO streams (sockets)?
I'm trying to answer these questions myself and having a hard time. Should input events include new connection requests and shutdowns? Individual bytes? Streams of bytes? or higher level PDUs? What kind of output should be generated? Full PDUs? streams of bytes? Pairs of (connection identifier,data)? How would such a system effectively hide the multiplexed IO going on? Is this sort of problem poorly suited for FRP?
Tim Newsham http://www.thenewsh.com/~newsham/ _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (5)
-
Don Stewart
-
Jason Dusek
-
Pierre-Evariste Dagand
-
Ryan Ingram
-
Tim Newsham