-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Network abstraction layer
--   
--   <a>Network.Transport</a> is a Network Abstraction Layer which provides
--   the following high-level concepts:
--   
--   <ul>
--   <li>Nodes in the network are represented by <a>EndPoint</a>s. These
--   are heavyweight stateful objects.</li>
--   <li>Each <a>EndPoint</a> has an <a>EndPointAddress</a>.</li>
--   <li>Connections can be established from one <a>EndPoint</a> to another
--   using the <a>EndPointAddress</a> of the remote end.</li>
--   <li>The <a>EndPointAddress</a> can be serialised and sent over the
--   network, where as <a>EndPoint</a>s and connections cannot.</li>
--   <li>Connections between <a>EndPoint</a>s are unidirectional and
--   lightweight.</li>
--   <li>Outgoing messages are sent via a <a>Connection</a> object that
--   represents the sending end of the connection.</li>
--   <li>Incoming messages for <i>all</i> of the incoming connections on an
--   <a>EndPoint</a> are collected via a shared receive queue.</li>
--   <li>In addition to incoming messages, <a>EndPoint</a>s are notified of
--   other <a>Event</a>s such as new connections or broken
--   connections.</li>
--   </ul>
--   
--   This design was heavily influenced by the design of the Common
--   Communication Interface
--   (<a>http://www.olcf.ornl.gov/center-projects/common-communication-interface</a>).
--   Important design goals are:
--   
--   <ul>
--   <li>Connections should be lightweight: it should be no problem to
--   create thousands of connections between endpoints.</li>
--   <li>Error handling is explicit: every function declares as part of its
--   type which errors it can return (no exceptions are thrown)</li>
--   <li>Error handling is "abstract": errors that originate from
--   implementation specific problems (such as "no more sockets" in the TCP
--   implementation) get mapped to generic errors ("insufficient
--   resources") at the Transport level.</li>
--   </ul>
--   
--   This package provides the generic interface only; you will probably
--   also want to install at least one transport implementation
--   (network-transport-*).
@package network-transport
@version 0.5.2


-- | Network Transport
module Network.Transport

-- | To create a network abstraction layer, use one of the
--   <tt>Network.Transport.*</tt> packages.
data Transport
Transport :: IO (Either (TransportError NewEndPointErrorCode) EndPoint) -> IO () -> Transport

-- | Create a new end point (heavyweight operation)
[newEndPoint] :: Transport -> IO (Either (TransportError NewEndPointErrorCode) EndPoint)

-- | Shutdown the transport completely
[closeTransport] :: Transport -> IO ()

-- | Network endpoint.
data EndPoint
EndPoint :: IO Event -> EndPointAddress -> (EndPointAddress -> Reliability -> ConnectHints -> IO (Either (TransportError ConnectErrorCode) Connection)) -> IO (Either (TransportError NewMulticastGroupErrorCode) MulticastGroup) -> (MulticastAddress -> IO (Either (TransportError ResolveMulticastGroupErrorCode) MulticastGroup)) -> IO () -> EndPoint

-- | Endpoints have a single shared receive queue.
[receive] :: EndPoint -> IO Event

-- | EndPointAddress of the endpoint.
[address] :: EndPoint -> EndPointAddress

-- | Create a new lightweight connection.
--   
--   <a>connect</a> should be as asynchronous as possible; for instance, in
--   Transport implementations based on some heavy-weight underlying
--   network protocol (TCP, ssh), a call to <a>connect</a> should be
--   asynchronous when a heavyweight connection has already been
--   established.
[connect] :: EndPoint -> EndPointAddress -> Reliability -> ConnectHints -> IO (Either (TransportError ConnectErrorCode) Connection)

-- | Create a new multicast group.
[newMulticastGroup] :: EndPoint -> IO (Either (TransportError NewMulticastGroupErrorCode) MulticastGroup)

-- | Resolve an address to a multicast group.
[resolveMulticastGroup] :: EndPoint -> MulticastAddress -> IO (Either (TransportError ResolveMulticastGroupErrorCode) MulticastGroup)

-- | Close the endpoint
[closeEndPoint] :: EndPoint -> IO ()

-- | Lightweight connection to an endpoint.
data Connection
Connection :: ([ByteString] -> IO (Either (TransportError SendErrorCode) ())) -> IO () -> Connection

-- | Send a message on this connection.
--   
--   <a>send</a> provides vectored I/O, and allows multiple data segments
--   to be sent using a single call (cf. <a>sendMany</a>). Note that this
--   segment structure is entirely unrelated to the segment structure
--   <i>returned</i> by a <a>Received</a> event.
[send] :: Connection -> [ByteString] -> IO (Either (TransportError SendErrorCode) ())

-- | Close the connection.
[close] :: Connection -> IO ()

-- | Event on an endpoint.
data Event

-- | Received a message
Received :: {-# UNPACK #-} !ConnectionId -> [ByteString] -> Event

-- | Connection closed
ConnectionClosed :: {-# UNPACK #-} !ConnectionId -> Event

-- | Connection opened
--   
--   <a>ConnectionId</a>s need not be allocated contiguously.
ConnectionOpened :: {-# UNPACK #-} !ConnectionId -> Reliability -> EndPointAddress -> Event

-- | Received multicast
ReceivedMulticast :: MulticastAddress -> [ByteString] -> Event

-- | The endpoint got closed (manually, by a call to closeEndPoint or
--   closeTransport)
EndPointClosed :: Event

-- | An error occurred
ErrorEvent :: (TransportError EventErrorCode) -> Event

-- | Connection data ConnectHintsIDs enable receivers to distinguish one
--   connection from another.
type ConnectionId = Word64

-- | Reliability guarantees of a connection.
data Reliability
ReliableOrdered :: Reliability
ReliableUnordered :: Reliability
Unreliable :: Reliability

-- | Multicast group.
data MulticastGroup
MulticastGroup :: MulticastAddress -> IO () -> Maybe Int -> ([ByteString] -> IO ()) -> IO () -> IO () -> IO () -> MulticastGroup

-- | EndPointAddress of the multicast group.
[multicastAddress] :: MulticastGroup -> MulticastAddress

-- | Delete the multicast group completely.
[deleteMulticastGroup] :: MulticastGroup -> IO ()

-- | Maximum message size that we can send to this group.
[maxMsgSize] :: MulticastGroup -> Maybe Int

-- | Send a message to the group.
[multicastSend] :: MulticastGroup -> [ByteString] -> IO ()

-- | Subscribe to the given multicast group (to start receiving messages
--   from the group).
[multicastSubscribe] :: MulticastGroup -> IO ()

-- | Unsubscribe from the given multicast group (to stop receiving messages
--   from the group).
[multicastUnsubscribe] :: MulticastGroup -> IO ()

-- | Close the group (that is, indicate you no longer wish to send to the
--   group).
[multicastClose] :: MulticastGroup -> IO ()

-- | EndPointAddress of an endpoint.
newtype EndPointAddress
EndPointAddress :: ByteString -> EndPointAddress
[endPointAddressToByteString] :: EndPointAddress -> ByteString

-- | EndPointAddress of a multicast group.
newtype MulticastAddress
MulticastAddress :: ByteString -> MulticastAddress
[multicastAddressToByteString] :: MulticastAddress -> ByteString

-- | Hints used by <a>connect</a>
data ConnectHints
ConnectHints :: Maybe Int -> ConnectHints
[connectTimeout] :: ConnectHints -> Maybe Int

-- | Default hints for connecting
defaultConnectHints :: ConnectHints

-- | Errors returned by Network.Transport API functions consist of an error
--   code and a human readable description of the problem
data TransportError error
TransportError :: error -> String -> TransportError error

-- | Errors during the creation of an endpoint
data NewEndPointErrorCode

-- | Not enough resources
NewEndPointInsufficientResources :: NewEndPointErrorCode

-- | Failed for some other reason
NewEndPointFailed :: NewEndPointErrorCode

-- | Connection failure
data ConnectErrorCode

-- | Could not resolve the address
ConnectNotFound :: ConnectErrorCode

-- | Insufficient resources (for instance, no more sockets available)
ConnectInsufficientResources :: ConnectErrorCode

-- | Timeout
ConnectTimeout :: ConnectErrorCode

-- | Failed for other reasons (including syntax error)
ConnectFailed :: ConnectErrorCode

-- | Failure during the creation of a new multicast group
data NewMulticastGroupErrorCode

-- | Insufficient resources
NewMulticastGroupInsufficientResources :: NewMulticastGroupErrorCode

-- | Failed for some other reason
NewMulticastGroupFailed :: NewMulticastGroupErrorCode

-- | Not all transport implementations support multicast
NewMulticastGroupUnsupported :: NewMulticastGroupErrorCode

-- | Failure during the resolution of a multicast group
data ResolveMulticastGroupErrorCode

-- | Multicast group not found
ResolveMulticastGroupNotFound :: ResolveMulticastGroupErrorCode

-- | Failed for some other reason (including syntax error)
ResolveMulticastGroupFailed :: ResolveMulticastGroupErrorCode

-- | Not all transport implementations support multicast
ResolveMulticastGroupUnsupported :: ResolveMulticastGroupErrorCode

-- | Failure during sending a message
data SendErrorCode

-- | Connection was closed
SendClosed :: SendErrorCode

-- | Send failed for some other reason
SendFailed :: SendErrorCode

-- | Error codes used when reporting errors to endpoints (through receive)
data EventErrorCode

-- | Failure of the entire endpoint
EventEndPointFailed :: EventErrorCode

-- | Transport-wide fatal error
EventTransportFailed :: EventErrorCode

-- | We lost connection to another endpoint
--   
--   Although <a>Network.Transport</a> provides multiple independent
--   lightweight connections between endpoints, those connections cannot
--   <i>fail</i> independently: once one connection has failed, <i>all</i>
--   connections, in both directions, must now be considered to have
--   failed; they fail as a "bundle" of connections, with only a single
--   "bundle" of connections per endpoint at any point in time.
--   
--   That is, suppose there are multiple connections in either direction
--   between endpoints A and B, and A receives a notification that it has
--   lost contact with B. Then A must not be able to send any further
--   messages to B on existing connections.
--   
--   Although B may not realize <i>immediately</i> that its connection to A
--   has been broken, messages sent by B on existing connections should not
--   be delivered, and B must eventually get an EventConnectionLost
--   message, too.
--   
--   Moreover, this event must be posted before A has successfully
--   reconnected (in other words, if B notices a reconnection attempt from
--   A, it must post the EventConnectionLost before acknowledging the
--   connection from A) so that B will not receive events about new
--   connections or incoming messages from A without realizing that it got
--   disconnected.
--   
--   If B attempts to establish another connection to A before it realized
--   that it got disconnected from A then it's okay for this connection
--   attempt to fail, and the EventConnectionLost to be posted at that
--   point, or for the EventConnectionLost to be posted and for the new
--   connection to be considered the first connection of the "new bundle".
EventConnectionLost :: EndPointAddress -> EventErrorCode
instance GHC.Generics.Generic Network.Transport.Event
instance GHC.Classes.Eq Network.Transport.Event
instance GHC.Show.Show Network.Transport.Event
instance GHC.Generics.Generic Network.Transport.EventErrorCode
instance GHC.Classes.Eq Network.Transport.EventErrorCode
instance GHC.Show.Show Network.Transport.EventErrorCode
instance GHC.Classes.Eq Network.Transport.SendErrorCode
instance GHC.Show.Show Network.Transport.SendErrorCode
instance GHC.Classes.Eq Network.Transport.ResolveMulticastGroupErrorCode
instance GHC.Show.Show Network.Transport.ResolveMulticastGroupErrorCode
instance GHC.Classes.Eq Network.Transport.NewMulticastGroupErrorCode
instance GHC.Show.Show Network.Transport.NewMulticastGroupErrorCode
instance GHC.Classes.Eq Network.Transport.ConnectErrorCode
instance GHC.Show.Show Network.Transport.ConnectErrorCode
instance GHC.Classes.Eq Network.Transport.NewEndPointErrorCode
instance GHC.Show.Show Network.Transport.NewEndPointErrorCode
instance GHC.Generics.Generic (Network.Transport.TransportError error)
instance GHC.Show.Show error => GHC.Show.Show (Network.Transport.TransportError error)
instance GHC.Generics.Generic Network.Transport.MulticastAddress
instance GHC.Classes.Ord Network.Transport.MulticastAddress
instance GHC.Classes.Eq Network.Transport.MulticastAddress
instance Data.Hashable.Class.Hashable Network.Transport.EndPointAddress
instance Data.Data.Data Network.Transport.EndPointAddress
instance GHC.Classes.Ord Network.Transport.EndPointAddress
instance GHC.Classes.Eq Network.Transport.EndPointAddress
instance GHC.Generics.Generic Network.Transport.Reliability
instance GHC.Classes.Eq Network.Transport.Reliability
instance GHC.Show.Show Network.Transport.Reliability
instance Data.Binary.Class.Binary Network.Transport.Event
instance Data.Binary.Class.Binary Network.Transport.EventErrorCode
instance Data.Binary.Class.Binary error => Data.Binary.Class.Binary (Network.Transport.TransportError error)
instance (Data.Typeable.Internal.Typeable err, GHC.Show.Show err) => GHC.Exception.Exception (Network.Transport.TransportError err)
instance GHC.Classes.Eq error => GHC.Classes.Eq (Network.Transport.TransportError error)
instance Data.Binary.Class.Binary Network.Transport.MulticastAddress
instance GHC.Show.Show Network.Transport.MulticastAddress
instance Data.Binary.Class.Binary Network.Transport.EndPointAddress
instance GHC.Show.Show Network.Transport.EndPointAddress
instance Control.DeepSeq.NFData Network.Transport.EndPointAddress
instance Data.Binary.Class.Binary Network.Transport.Reliability


-- | Internal functions
module Network.Transport.Internal

-- | Serialize 32-bit to network byte order
encodeWord32 :: Word32 -> ByteString

-- | Deserialize 32-bit from network byte order Throws an IO exception if
--   this is not exactly 32 bits.
decodeWord32 :: ByteString -> Word32

-- | Encode an Enum in 32 bits by encoding its signed Int equivalent
--   (beware of truncation, an Enum may contain more than 2^32 points).
encodeEnum32 :: Enum a => a -> ByteString

-- | Decode any Num type from 32 bits by using fromIntegral to convert from
--   a Word32.
decodeNum32 :: Num a => ByteString -> a

-- | Serialize 16-bit to network byte order
encodeWord16 :: Word16 -> ByteString

-- | Deserialize 16-bit from network byte order Throws an IO exception if
--   this is not exactly 16 bits.
decodeWord16 :: ByteString -> Word16

-- | Encode an Enum in 16 bits by encoding its signed Int equivalent
--   (beware of truncation, an Enum may contain more than 2^16 points).
encodeEnum16 :: Enum a => a -> ByteString

-- | Decode any Num type from 16 bits by using fromIntegral to convert from
--   a Word16.
decodeNum16 :: Num a => ByteString -> a

-- | Prepend a list of bytestrings with their total length Will be an
--   exception in case of overflow: the sum of the lengths of the
--   ByteStrings overflows Int, or that sum overflows Word32.
prependLength :: [ByteString] -> [ByteString]

-- | Translate exceptions that arise in IO computations
mapIOException :: Exception e => (IOException -> e) -> IO a -> IO a

-- | Like <a>try</a>, but lifted and specialized to IOExceptions
tryIO :: MonadIO m => IO a -> m (Either IOException a)

-- | Safe version of <a>toEnum</a>
tryToEnum :: (Enum a, Bounded a) => Int -> Maybe a

-- | If the timeout value is not Nothing, wrap the given computation with a
--   timeout and it if times out throw the specified exception. Identity
--   otherwise.
timeoutMaybe :: Exception e => Maybe Int -> e -> IO a -> IO a

-- | <tt>asyncWhenCancelled g f</tt> runs f in a separate thread and waits
--   for it to complete. If f throws an exception we catch it and rethrow
--   it in the current thread. If the current thread is interrupted before
--   f completes, we run the specified clean up handler (if f throws an
--   exception we assume that no cleanup is necessary).
asyncWhenCancelled :: forall a. (a -> IO ()) -> IO a -> IO a

-- | Not all versions of "base" export <a>void</a>
void :: Monad m => m a -> m ()

-- | This was introduced in "base" some time after 7.0.4
forkIOWithUnmask :: ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId

-- | Logging (for debugging)
tlog :: MonadIO m => String -> m ()


-- | Utility functions
--   
--   Note: this module is bound to change even more than the rest of the
--   API :)
module Network.Transport.Util

-- | Fork a new thread, create a new end point on that thread, and run the
--   specified IO operation on that thread.
--   
--   Returns the address of the new end point.
spawn :: Transport -> (EndPoint -> IO ()) -> IO EndPointAddress
