But, on the other hand, I’ve never been happy with the output of
make -j. Interleaving lines of output from parallel subprocesses isn’t very user friendly. (Indeed,
cabal -jused to do the same thing, and recently it has switched to simply hiding the output instead.) Thus I’ve written a little utility than dynamically splits the terminal window when the compute job enters a parallel region (video below).
hydra-head). You can find it at its Github page here and the released package is on Hackage here.
cabal install hydra-print, the simplest way to use it is to bring up a server like this:
And then arrange for a script to pipe the output of multiple commands to it in parallel:
It’s possible to compose command’s output sequentially as well, by asking
(command1 | hydra-head) & (command2 | hydra-head) &
hydra-headto return a named pipe, and deleting it to signal that the stream is finished.
Further, its often convenient to use hydra-view to launch another command, using it to seed the view with output:
p=`hydra-head -p` command1 >> $p command2 >> $p rm -f $p
The repository contains an example Makefile here, which shows how to adapt a Makefile to use hydra-print without any direct support builtin to Make. Of course, built-in support is better, and I hope to come up with a patch for
hydra-view -- make -j
cabal-installto use hydra-print soon.
Using the Haskell LibraryThe library is based on the recent
io-streamspackage, and makes it very easy to send several kinds of Haskell data streams into hydra-print.
The two main ways to use the library are to (1) bring up a static interface with a given number of windows, or (2) bring up a dynamic view monitoring a changing collectionn of streams.
import qualified System.IO.Streams as S import UI.HydraPrint
The former can be called with
hydraPrintStatic defaultHydraConf (zip names strms). It’s type signature is:
hydraPrintStatic ::HydraConf -> [(String, InputStream ByteString)] -> IO ()
As you can see, it takes a fixed number of streams (in a list). A dynamic set of streams is represented as – what else – a stream of streams!
hydraPrint ::HydraConf -> InputStream (String, InputStream ByteString) -> IO ()
In a parallel program one might use a
Control.Concurrent.Chanto aggregate streams and send them to
strmSrc <- span=""> chanToInput strmChan hydraPrint defaultHydraConf strmSrc->
Finally, I think the most obvious improvement to make to this little utility would be to provide the option of a
tmuxinterface instead. This would provide much more functionality and should be pretty straightforward, because
tmuxitself is quite scriptable. Emacs [client] would be another option.