Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IMAP's fetch results with extreme memory usage and computer freezing. #39

Open
yuvallanger opened this issue Dec 5, 2015 · 6 comments
Labels

Comments

@yuvallanger
Copy link

I have written the following function using the HaskellNet and HaskellNet-SSL libraries.
Using the "fetch" function results with memory usage blowing up and extreme swapping.
What am I doing wrong? Might it be a bug?

import qualified Data.ByteString.Char8       as SB8
import           Network.HaskellNet.IMAP
import           Network.HaskellNet.IMAP.SSL

main = retrieveCSV

retrieveCSV = do
    con <- connectIMAPSSL imapServer
    login con username password
    select con mailbox
    lastMsg <- last <$> search con [ALLs]
    -- this works:
    _ <- fetchHeader con lastMsg
    -- this works:
    _ <- fetchSize con lastMsg
    -- this blows up in memory usage:
    _ <- fetch con lastMsg
    undefined
    where
    imapServer = "imap.gmail.com"
    username   = "example" -- imagine this username is real
    password   = "example" -- imagine this password is real
    mailbox    = "example" -- imagine this mailbox is real
@lemol
Copy link
Contributor

lemol commented Dec 10, 2015

Hi @yuvallanger , sorry for the answer delay. Please can you give more information about the 'lastMsg' mail content? What is it actual size? Does it have any attachment? Or, the problem is for all mail message?
I tried but cannot reproduce the problem.

@mkawalec
Copy link

@lemol, @jtdaugherty This performance issue is probably related to the fact that even the ByteString implementations use a String fetcher. Would you be willing to accept PRs that fix that?

@lemol
Copy link
Contributor

lemol commented Jan 28, 2016

@mkawalec , thank you for your interest. Yes, a PR will be well come!

@mkawalec
Copy link

@lemol: Decided to go the long way and created my own imap library, https://github.com/mkawalec/imap.

@lemol
Copy link
Contributor

lemol commented Feb 16, 2016

Nice, @mkawalec !

@webcpu
Copy link

webcpu commented Sep 19, 2017

I have profiled it and found that function eval/fetchByString/ consumed several gigabytes ram.
Parse is a recursive function and very slow, and tail-recruisve optimisation doesn't help in this case.

eval :: (RespDerivs -> Result RespDerivs r) -> String -> ByteString -> r
eval pMain tag s = case pMain (parse tag (Pos tag 1 1) s) of
                     Parsed v _ _ -> v
                     NoParse e    -> error (show e)

parse :: String -> Pos -> ByteString -> RespDerivs
parse tagstr pos s = d
    where d    = RespDerivs flag tag chr pos
          flag = pParenFlags d
          tag  = Parsed tagstr d (nullError d)
          chr  = if BS.null s
                  then NoParse (eofError d)
                  else let (c, s') = (BS.head s, BS.tail s)
                           t = (parse tagstr (nextPos pos c) s')
                       in Parsed c t
                            (nullError d)

@qnikst qnikst added the bug label Dec 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants