Code Monkey home page Code Monkey logo

Comments (6)

tibbe avatar tibbe commented on July 17, 2024

I think to start with we should document the current behavior. I'm worried that behavior in Network.Socket.recv and Network.Socket.ByteString.recv differs here. Secondly we should take a deep look to see what the POSIX standard specifies here and consider if we ought to change our current behavior. We shouldn't make such a decision lightly, given the age and widespread use of the API.

On a more philosophical note I don't like the Haskell way of handling EOF by throwing an exception. EOF is not an error condition.

from network.

joeyadams avatar joeyadams commented on July 17, 2024

Secondly we should take a deep look to see what the POSIX standard specifies here and consider if we ought to change our current behavior.

The recv system call returns 0 on EOF, consistent with the documentation of Network.Socket.recv.

On a more philosophical note I don't like the Haskell way of handling EOF by throwing an exception. EOF is not an error condition.

The hGetBufSome function doesn't throw an exception. It returns empty strings on EOF, like the recv system call does. getLine and getChar, however, do throw EOF when there are no more lines or characters, which makes more sense.

I strongly feel that the current implementation of Network.Socket.recv is incorrect in throwing EOF on end of input, but concede that it would break things to change it now. However, the new (and not-yet-released) recvBuf has the incorrect behavior.

How about this:

  • Update the documentation of Network.Socket.recv to describe the current behavior, and encourage users to use the ByteString version instead. Network.Socket.recv is basically deprecated anyway.
  • Implement the correct semantics in recvBuf. It hasn't been released yet, so this shouldn't break anything.

from network.

tibbe avatar tibbe commented on July 17, 2024

Sounds good.

from network.

joeyadams avatar joeyadams commented on July 17, 2024

Houston, we have a problem. recvBufFrom throws an exception on EOF, and it's been around since 2004. Here are the relevant commits:

  • 7b43363 (2002): changes recv, recvFrom to throw an exception on EOF
  • b401455 (2004): adds sendBufTo/recvBufFrom

Commit 7b43363 gives this justification:

* Have these map zero-byte results from the underlying
  APIs to an EOF IOError, bringing them into line with
  what the  hGet* actions do when interpreting read()
  results.

But what hGet* actions were they talking about? hGetBuf returns 0 instead of throwing an exception. It has for a long time. However, some other functions do throw EOF:

  • getChar throws EOF on end of input, since there's no sane way to return a Char on end of input. An exception-free variant would have type IO (Maybe Char).
  • getLine throws EOF on end of input. If it returned an empty line instead, it would be indistinguishable from empty lines in the file (e.g. \n\n\n). An exception-free variant would have type IO (Maybe String).

Here is an argument against recv functions returning an empty string on EOF: the caller has to give the zero-length string special treatment. If a caller naïvely reads chunks until it has enough data, it will go into an infinite loop.

Perhaps we should add Maybe variants, so the caller explicitly handles the EOF case:

recvMaybe        :: Socket -> Int -> IO (Maybe String)
recvBufMaybe     :: Socket -> Ptr Word8 -> Int -> IO (Maybe Int)
recvBufFromMaybe :: Socket -> Ptr a -> Int -> IO (Maybe Int, SockAddr)

These functions will never throw EOF, and will never return Just "" or Just 0.

I like this idea a lot:

  • Avoids changing the semantics of the existing functions, both of which are older than most dogs
  • Eliminates ambiguity regarding EOF
  • Callers explicitly handle the EOF case
  • Callers don't give 0 special treatment

The Maybe wrapping/unwrapping should have negligible performance impact. It should be dwarfed by system call overhead, which is on the order of microseconds.

So what do we do about ByteString.recv versus Socket.recv ? Also, how should the new recvBuf behave?

from network.

tibbe avatar tibbe commented on July 17, 2024

So what do we do about ByteString.recv versus Socket.recv ? Also, how should the new recvBuf behave?

I don't think we should expand the String API any more. We'd like people to stop using it eventually. Lets just document its behavior. As for recvBuf, I think we should be consistent and raise an exception on EOF.

As a separate issue we could look into what kind of changes would be needed to go from an old crufty API to a more modern one that's easier to use. This likely needs some thought/discussion.

from network.

kazu-yamamoto avatar kazu-yamamoto commented on July 17, 2024

Network module is deprecated. So, I close this.

from network.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.