[web-devel] Question about the composing order of conduit combination operations

Michael Snoyman michael at snoyman.com
Thu Apr 5 14:05:37 CEST 2012


I'm not sure of the details of the question, but there was a bug in
conduit 0.4.0 that I fixed in 0.4.0.1. It affected the order of
operations in cases like this. I believe the exact issue was that it
would perform monadic actions from the left-hand-side even if output
wasn't needed yet.

Can you try upgrading and see if that solves your problem?

Michael

On Thu, Apr 5, 2012 at 3:01 PM, Hiromi ISHII <konn.jinro at gmail.com> wrote:
> Hi,
>
> I'm implementing a tiny SMTP server using conduit-0.4.0 and network-conduit-0.4.0.
>
> I wrote code like below:
>
>> smtpServer src sink = do
>>   LC.sourceList [ renderReply $ SMTPReply 220 (Just "localhost") ["hello"]] $$ sink
>>   src $$ C.sequence (sinkParser smtpCommand)
>>       =$ LC.map (BS.pack . show)
>>       =$ sink
>
> Here is the complete (and slightly different) code: https://github.com/konn/haskell-smtp/blob/master/smtp-server/Network/SMTP/Server.hs
> (You know, this server is not actually an smtp server; just echoing client's input for now.)
>
> I ran this program and communicated using telnet.
> I expected the access log like below (S means server, C means client; new-lines are CRLF) :
>
>> S: 220 localhost hello
>> C: EHLO another.example.com
>> S: EHLO "another.example.com"
>> C: MAIL FROM:<Postmaster at example.com>
>> S: MAIL (Path [] (Mailbox {mbLocalPart = "Postmaster", mbDomain = "example.com"})) []
>> C: RCPT TO:<foo at example.com>
>> S: RCPT (Path [] (Mailbox {mbLocalPart = "foo", mbDomain = "example.com"})) []
>> C: DATA
>> C: hoge
>> C: fuga
>> C: oooo
>> C: .
>> S: DATA "hoge\r\nfuga\r\noooo"
>> C: QUIT
>> S: QUIT
>
> But I got:
>
>> S: 220 localhost hello
>> C: EHLO another.example.com
>> C: MAIL FROM:<Postmaster at example.com>
>> C: RCPT TO:<foo at example.com>
>> S: EHLO "another.example.com"
>> C: DATA
>> S: MAIL (Path [] (Mailbox {mbLocalPart = "Postmaster", mbDomain = "example.com"})) []
>> C: hoge
>> C: fuga
>> C: oooo
>> C: .
>> C: QUIT
>> S: RCPT (Path [] (Mailbox {mbLocalPart = "foo", mbDomain = "example.com"})) []
>
> It seems that conduit produces a new SMTPCommand after reading another new command, and processes and convert it into SMTPReply much father later.
>
> By the way, I rewrote the program above just like below and everythings seems to be good:
>
>> smtpServer src sink = do
>>   LC.sourceList [ renderReply $ SMTPReply 220 (Just "localhost") ["hello"]] $$ sink
>>   src $= C.sequence (sinkParser smtpCommand)
>>       $= LC.map (BS.pack . show)
>>       $$ sink
>
> If Conduits, Sinks and Sources are the same sings in conduit-0.4, why these two codes above behaves differently?
> To summarize, my questions are divided into three:
>
> 1. Why the first one doesn't work as I expected?
> 2. Why the second one works well?
> 3. Is this difference intended? If so, what are the difference of semantics of ($=), (=$), ($$), (=$=) and their composition?
>
> -- Hiromi ISHII
> konn.jinro at gmail.com
>
>
> _______________________________________________
> web-devel mailing list
> web-devel at haskell.org
> http://www.haskell.org/mailman/listinfo/web-devel



More information about the web-devel mailing list