Copyright | (C) 2014 EURL Tweag |
---|---|
Safe Haskell | None |
Language | Haskell2010 |
0MQ implemmentation of the network-transport API.
The 0MQ implementation guarantees that only a single connection (socket) will
be used between endpoints, provided that the addresses specified are
canonical. If A connects to B and reports its address as
192.168.0.1:8080
and B subsequently connects tries to connect to A as
client1.local:http-alt
then the transport layer will not realize that the
TCP connection can be reused.
This module is intended to be imported qualified.
- createTransport :: ZMQParameters -> ByteString -> IO Transport
- data ZMQParameters = ZMQParameters {
- zmqHighWaterMark :: Word64
- zmqSecurityMechanism :: Maybe SecurityMechanism
- data SecurityMechanism = SecurityPlain {
- plainPassword :: ByteString
- plainUsername :: ByteString
- defaultZMQParameters :: ZMQParameters
- data Hints = Hints {
- hintsPort :: Maybe Int
- hintsControlPort :: Maybe Int
- defaultHints :: Hints
- apiNewEndPoint :: Hints -> TransportInternals -> IO (Either (TransportError NewEndPointErrorCode) EndPoint)
- createTransportExposeInternals :: ZMQParameters -> ByteString -> IO (TransportInternals, Transport)
- breakConnectionEndPoint :: TransportInternals -> EndPointAddress -> EndPointAddress -> IO ()
- breakConnection :: TransportInternals -> EndPointAddress -> EndPointAddress -> IO ()
- unsafeConfigurePush :: TransportInternals -> EndPointAddress -> EndPointAddress -> (Socket Push -> IO ()) -> IO ()
- registerCleanupAction :: TransportInternals -> IO () -> IO (Maybe Unique)
- registerValidCleanupAction :: ValidTransportState -> IO () -> IO (Maybe Unique)
- applyCleanupAction :: TransportInternals -> Unique -> IO ()
Main API
:: ZMQParameters | |
-> ByteString | Transport address (IP or hostname) |
-> IO Transport |
Create 0MQ based transport.
data ZMQParameters
Parameters for ZeroMQ connection.
ZMQParameters | |
|
data SecurityMechanism
A ZeroMQ "security mechanism".
SecurityPlain | Clear-text authentication, using a (username, password) pair. |
|
ZeroMQ specific functionality
network-transport ZeroMQ has a big number of additional options that can be used for socket
configuration and that are not exposed in network-transport abstraction layer. In order to
to use specific options of network-transport-zeromq, the function apiNewEndPoint
was introduced.
This function uses TransportInternals
and a notion of Hints
-- a special data type that contains
the possible configuration options.
Example: Bootstrapping problem.
Due to the network-transport-zeromq design, a new endpoint is bound to a new socket address, making it impossible to bootstrap systems without an additional communication mechanism. This can be avoided if the new function is used to create an endpoint on a specified port:
(intenals, transport) <- createTransportExposeInternals defaultZMQParameters "127.0.0.1" ep <- apiNewEndpoint Hints{hintsPort=8888} internals
Allow to create a endpoint on a specified port and as a result bootstrap the system.
data Hints
A list of Hints provided for connection
Hints | |
|
:: Hints | Hints to apply. |
-> TransportInternals | Internal transport state. |
-> IO (Either (TransportError NewEndPointErrorCode) EndPoint) |
Creates a new endpoint on the transport specified and applies all hints.
Internals
Internal functions provide additional ZeroMQ specific set of configuration options. This functionality should be used with caution as it may break required socket properties.
createTransportExposeInternals
:: ZMQParameters | Configuration parameters for ZeroMQ |
-> ByteString | Host name or IP address |
-> IO (TransportInternals, Transport) |
You should probably not use this function (used for unit testing only)
breakConnectionEndPoint :: TransportInternals -> EndPointAddress -> EndPointAddress -> IO ()
Break connection between two endpoints, other endpoints on the same remove will not be affected.
breakConnection :: TransportInternals -> EndPointAddress -> EndPointAddress -> IO ()
Break endpoint connection, all endpoints that will be affected.
unsafeConfigurePush :: TransportInternals -> EndPointAddress -> EndPointAddress -> (Socket Push -> IO ()) -> IO ()
Configure socket after creation
Cleanup API is prepared to store cleanup actions for example socket
close for objects that uses network-transport-zeromq resources. Theese
actions will be fired on transport close.
If you need to clean resource beforehead use applyCleanupAction
.
registerCleanupAction :: TransportInternals -> IO () -> IO (Maybe Unique)
Register action that will be fired when transport will be closed.
registerValidCleanupAction :: ValidTransportState -> IO () -> IO (Maybe Unique)
Register action on a locked transport.
applyCleanupAction :: TransportInternals -> Unique -> IO ()
Call cleanup action before transport close.
Design
In the zeromq backend we are using following address scheme:
tcp://host:port/ | | | | +---+---------------- can be configured by user, one host, | port pair per distributed process | instance +---------------------------- In future it will be possible to add other schemas.
Transport specifies host that will be used, and port will be automatically generated by the transport for each endpoint.
- Connections Reliability
Currently only reliable connections are supported. In case Unreliable
was
passed the connection will nonetheless be reliable, since it is not incorrect
to do so. This may be changed in future versions.
Network-transport-zeromq maintains one thread for each endpoint that is used to read incoming requests. All sends and connection requests are handled from the user thread and are mostly asynchronous.
Each endpoint obtains one pull socket and one push socket for each remote end point. All lightweight threads abrigged into one heavyweight connection.
Virually connections looks like the following plot:
+------------------+ +--------------+ | Endpoint | | Endpoint | | | | | | +------+ +------+ | | | pull |<-----------------------| push | | + +------+ +------+ | | | +--------------------+ | | + +------+/~~~~ connection 1 ~~~~\+------+ | | | push |~~~~~ connection 2 ~~~~~| pull | | | +------+\ /+------+ | | | +--------------------+ | | +------------------+ +--------------+
Physically ZeroMQ may choose better representations and mapping on a real connections.
The ZeroMQ library takes care of reliability. It keeps message in a queue
such that in case of connection break, it may be restarted with no message
loss. So heartbeating procedure should be introduced on the top on
network-transport, and breakConnection
should be used to notify connection
death. However if High Water Mark will be reached connection to endpoint
considered failed and connection break procedure started automatically.