How to waitForProcess?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

How to waitForProcess?

Magicloud Magiclouds
Hi,
  I have code like this and it leaves lots of zombies of flow-export.
Then I add waitForProcess.... Well I do not know where to put it.
Before or after 'hGetContents' both make the program hung.

exportCSV :: FilePath -> IO [String]
exportCSV file = do
  csv_ <- withBinaryFile file ReadMode $ \i -> do
    (_, Just o, _, h) <- createProcess $ CreateProcess (RawCommand
"/usr/bin/flow-export" ["-f2"]) Nothing Nothing (UseHandle i)
CreatePipe Inherit True False
    hGetContents o
  return $ tail $ lines csv_

--
竹密岂妨流水过
山高哪阻野云飞

And for G+, please use magiclouds#gmail.com.

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: How to waitForProcess?

Ivan Lazar Miljenovic
On 5 September 2012 13:45, Magicloud Magiclouds
<[hidden email]> wrote:
> Hi,
>   I have code like this and it leaves lots of zombies of flow-export.
> Then I add waitForProcess.... Well I do not know where to put it.
> Before or after 'hGetContents' both make the program hung.

You're probably being bitten by hGetContents being lazy.  Force the
result of hGetContents (e.g. `evaluate . length =<< hGetContents o ')
and then use waitForProcess.

>
> exportCSV :: FilePath -> IO [String]
> exportCSV file = do
>   csv_ <- withBinaryFile file ReadMode $ \i -> do
>     (_, Just o, _, h) <- createProcess $ CreateProcess (RawCommand
> "/usr/bin/flow-export" ["-f2"]) Nothing Nothing (UseHandle i)
> CreatePipe Inherit True False
>     hGetContents o
>   return $ tail $ lines csv_
>
> --
> 竹密岂妨流水过
> 山高哪阻野云飞
>
> And for G+, please use magiclouds#gmail.com.
>
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe



--
Ivan Lazar Miljenovic
[hidden email]
http://IvanMiljenovic.wordpress.com

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: How to waitForProcess?

Mike Ledger
In reply to this post by Magicloud Magiclouds
You might have to use hGetContents, then waitForProcess, and then terminateProcess -- you can then check if the process is indeed terminated using getProcessExitCode.

On Wed, Sep 5, 2012 at 1:45 PM, Magicloud Magiclouds <[hidden email]> wrote:
Hi,
  I have code like this and it leaves lots of zombies of flow-export.
Then I add waitForProcess.... Well I do not know where to put it.
Before or after 'hGetContents' both make the program hung.

exportCSV :: FilePath -> IO [String]
exportCSV file = do
  csv_ <- withBinaryFile file ReadMode $ \i -> do
    (_, Just o, _, h) <- createProcess $ CreateProcess (RawCommand
"/usr/bin/flow-export" ["-f2"]) Nothing Nothing (UseHandle i)
CreatePipe Inherit True False
    hGetContents o
  return $ tail $ lines csv_

--
竹密岂妨流水过
山高哪阻野云飞

And for G+, please use magiclouds#gmail.com.

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: How to waitForProcess?

Magicloud Magiclouds
In reply to this post by Ivan Lazar Miljenovic
Forgot about that, just read 'readProcess' code to figure out.
Thanks.

On Wed, Sep 5, 2012 at 12:37 PM, Ivan Lazar Miljenovic
<[hidden email]> wrote:

> On 5 September 2012 13:45, Magicloud Magiclouds
> <[hidden email]> wrote:
>> Hi,
>>   I have code like this and it leaves lots of zombies of flow-export.
>> Then I add waitForProcess.... Well I do not know where to put it.
>> Before or after 'hGetContents' both make the program hung.
>
> You're probably being bitten by hGetContents being lazy.  Force the
> result of hGetContents (e.g. `evaluate . length =<< hGetContents o ')
> and then use waitForProcess.
>
>>
>> exportCSV :: FilePath -> IO [String]
>> exportCSV file = do
>>   csv_ <- withBinaryFile file ReadMode $ \i -> do
>>     (_, Just o, _, h) <- createProcess $ CreateProcess (RawCommand
>> "/usr/bin/flow-export" ["-f2"]) Nothing Nothing (UseHandle i)
>> CreatePipe Inherit True False
>>     hGetContents o
>>   return $ tail $ lines csv_
>>
>> --
>> 竹密岂妨流水过
>> 山高哪阻野云飞
>>
>> And for G+, please use magiclouds#gmail.com.
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> [hidden email]
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
>
> --
> Ivan Lazar Miljenovic
> [hidden email]
> http://IvanMiljenovic.wordpress.com



--
竹密岂妨流水过
山高哪阻野云飞

And for G+, please use magiclouds#gmail.com.

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: How to waitForProcess?

Brandon Allbery
In reply to this post by Mike Ledger
On Tue, Sep 4, 2012 at 9:39 PM, Mike Ledger <[hidden email]> wrote:
You might have to use hGetContents, then waitForProcess, and then terminateProcess -- you can then check if the process is indeed terminated using getProcessExitCode.

Er?  When waitForProcess returns the process is dead; there's nothing to terminateProcess.  If you do it the other way around then you may not get full output.

For starters, I would not build up the CreateProcess record directly but use the "proc" record and override it with your I/O definitions.  I've been bit by this before (I think some older version of System.Process lacked useful predefined records?).

There is a severe gotcha here if you do things naively (like your example code does).  If there is more output than will fit in a pipe, *no* ordering of read / wait in a single thread will work without deadlocking; you have no choice but to do the read in a separate thread.  This is not a Haskell issue, it is how pipes work on POSIX systems.  (I don't know if Windows has the same problem.)

--
brandon s allbery                                      [hidden email]
wandering unix systems administrator (available)     (412) 475-9364 vm/sms


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe