network-transport-zeromq-0.2.1.1: ZeroMQ backend for network-transport

Copyright(C) 2014 EURL Tweag
Safe HaskellNone
LanguageHaskell2010

Network.Transport.ZMQ

Contents

Description

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.

Synopsis

Main API

createTransport

Arguments

:: ZMQParameters 
-> ByteString

Transport address (IP or hostname)

-> IO Transport 

Create 0MQ based transport.

data ZMQParameters

Parameters for ZeroMQ connection.

Constructors

ZMQParameters 

data SecurityMechanism

A ZeroMQ "security mechanism".

Constructors

SecurityPlain

Clear-text authentication, using a (username, password) pair.

Fields

plainPassword :: ByteString
 
plainUsername :: ByteString
 

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

Constructors

Hints 

Fields

hintsPort :: Maybe Int

The port to bind.

hintsControlPort :: Maybe Int

The port that is used to receive multicast messages.

apiNewEndPoint

Arguments

:: 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

Arguments

:: 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.