cardano-shell-0.1.0.0
Safe HaskellNone
LanguageHaskell2010

Cardano.Shell.NodeIPC

Description

Synopsis

Data types

newtype Port Source #

Port that is used to communicate between Cardano-node and Daedalus (e.g 8090)

Constructors

Port 

Fields

Instances

Instances details
Eq Port Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Methods

(==) :: Port -> Port -> Bool #

(/=) :: Port -> Port -> Bool #

Show Port Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Methods

showsPrec :: Int -> Port -> ShowS #

show :: Port -> String #

showList :: [Port] -> ShowS #

Generic Port Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Associated Types

type Rep Port :: Type -> Type #

Methods

from :: Port -> Rep Port x #

to :: Rep Port x -> Port #

Arbitrary Port Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

ToJSON Port Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

FromJSON Port Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

type Rep Port Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

type Rep Port = D1 ('MetaData "Port" "Cardano.Shell.NodeIPC.Lib" "cardano-shell-0.1.0.0-31Sro4CeSAWE4uOGxln0rB" 'True) (C1 ('MetaCons "Port" 'PrefixI 'True) (S1 ('MetaSel ('Just "getPort") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Word16)))

data MsgIn Source #

Message from the server being sent to the client.

Constructors

QueryPort

Ask which port to use

Ping

Ping

Shutdown

Shutdown message from the server

MessageInFailure MessageSendFailure 

Instances

Instances details
Eq MsgIn Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Methods

(==) :: MsgIn -> MsgIn -> Bool #

(/=) :: MsgIn -> MsgIn -> Bool #

Show MsgIn Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Methods

showsPrec :: Int -> MsgIn -> ShowS #

show :: MsgIn -> String #

showList :: [MsgIn] -> ShowS #

Generic MsgIn Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Associated Types

type Rep MsgIn :: Type -> Type #

Methods

from :: MsgIn -> Rep MsgIn x #

to :: Rep MsgIn x -> MsgIn #

Arbitrary MsgIn Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

ToJSON MsgIn Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

FromJSON MsgIn Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

type Rep MsgIn Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

type Rep MsgIn = D1 ('MetaData "MsgIn" "Cardano.Shell.NodeIPC.Lib" "cardano-shell-0.1.0.0-31Sro4CeSAWE4uOGxln0rB" 'False) ((C1 ('MetaCons "QueryPort" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Ping" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Shutdown" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "MessageInFailure" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 MessageSendFailure))))

data MsgOut Source #

Message which is send out from Cardano-node

Constructors

Started

Notify Daedalus that the node has started

ReplyPort Word16

Reply of QueryPort

Pong

Reply of Ping

ShutdownInitiated

Reply of shutdown

MessageOutFailure MessageSendFailure 

Instances

Instances details
Eq MsgOut Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Methods

(==) :: MsgOut -> MsgOut -> Bool #

(/=) :: MsgOut -> MsgOut -> Bool #

Show MsgOut Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Generic MsgOut Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Associated Types

type Rep MsgOut :: Type -> Type #

Methods

from :: MsgOut -> Rep MsgOut x #

to :: Rep MsgOut x -> MsgOut #

Arbitrary MsgOut Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

ToJSON MsgOut Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

FromJSON MsgOut Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

type Rep MsgOut Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

type Rep MsgOut = D1 ('MetaData "MsgOut" "Cardano.Shell.NodeIPC.Lib" "cardano-shell-0.1.0.0-31Sro4CeSAWE4uOGxln0rB" 'False) ((C1 ('MetaCons "Started" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "ReplyPort" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Word16))) :+: (C1 ('MetaCons "Pong" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "ShutdownInitiated" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "MessageOutFailure" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 MessageSendFailure)))))

newtype ReadHandle Source #

Read-only handle

Constructors

ReadHandle 

newtype WriteHandle Source #

Write-only handle

Constructors

WriteHandle 

IPC protocol

data ProtocolDuration Source #

When using pipes, the write doesn't block, but the read blocks! As a consequence, we eiter need to use IDs to keep track of the client/server pair, or (read) block so we know which message pair arrived. This might seems an overkill for this task, but it's actually required if we want to reason about it and test it properly.

>>> (readEnd, writeEnd) <- createPipe
>>> replicateM 100 $ sendMessage (WriteHandle writeEnd) Cardano.Shell.NodeIPC.Ping
[(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),()]
>>> mesg <- replicateM 100 ((readMessage (ReadHandle readEnd)) :: IO MsgIn)
>>> mesg <- (readMessage (ReadHandle readEnd)) :: IO MsgIn

Blocked!

The way the IPC protocol works - it either responds to a single IPC message or it remains in a loop responding to multiple messages.

Constructors

SingleMessage

Responds to a single message and exits

MultiMessage

Runs forever responding to messages

startNodeJsIPC :: ProtocolDuration -> Port -> IO (Either NodeIPCError ()) Source #

Start IPC with NodeJS

This only works if NodeJS spawns the Haskell executable as child process (See server.js as an example)

handleIPCProtocol :: Port -> MsgIn -> IO MsgOut Source #

Function for handling the protocol

clientIPCListener Source #

Arguments

:: ProtocolDuration 
-> ClientHandles 
-> Port

This is really making things confusing. A Port is here, but it's determined on the client side, not before.

-> IO (Either NodeIPCError ()) 

Client side IPC protocol.

data ServerHandles Source #

The set of handles for the server, the halves of one pipe.

data ClientHandles Source #

The set of handles for the client, the halves of one pipe.

createFullDuplexAnonPipesHandles :: IO (ServerHandles, ClientHandles) Source #

Creation of a two-way communication between the server and the client. Full-duplex (two-way) communication normally requires two anonymous pipes. TODO(KS): Bracket this!

bracketFullDuplexAnonPipesHandles :: ((ServerHandles, ClientHandles) -> IO ()) -> IO () Source #

A bracket function that can be useful.

serverReadWrite :: ServerHandles -> MsgIn -> IO (Either NodeIPCError MsgOut) Source #

This is a blocking call that sends the message to the client and returns it's response, after the client response arrives.

Exceptions

data NodeIPCError Source #

Exception thrown from Node IPC protocol

Constructors

NodeChannelNotFound Text

Node channel was not found

UnableToParseNodeChannel Text

Unable to parse given Text as File descriptor

IPCError

Exception thrown when there's something wrong with IPC

HandleClosed Handle

Given handle is closed therefore cannot be used

HandleEOF Handle

Given handle End Of File

UnreadableHandle Handle

Given handle cannot be used to read

UnwritableHandle Handle

Given handle cannot be used to write

NoStdIn 

Instances

Instances details
Eq NodeIPCError Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Show NodeIPCError Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

data MessageSendFailure Source #

Message that can be used to let the other know the that exception had occured

Instances

Instances details
Eq MessageSendFailure Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Show MessageSendFailure Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Generic MessageSendFailure Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

Associated Types

type Rep MessageSendFailure :: Type -> Type #

Arbitrary MessageSendFailure Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

ToJSON MessageSendFailure Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

FromJSON MessageSendFailure Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

type Rep MessageSendFailure Source # 
Instance details

Defined in Cardano.Shell.NodeIPC.Lib

type Rep MessageSendFailure = D1 ('MetaData "MessageSendFailure" "Cardano.Shell.NodeIPC.Lib" "cardano-shell-0.1.0.0-31Sro4CeSAWE4uOGxln0rB" 'False) (C1 ('MetaCons "ParseError" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)) :+: C1 ('MetaCons "GeneralFailure" 'PrefixI 'False) (U1 :: Type -> Type))

Used for testing

sendMessage :: (MonadIO m, ToJSON msg) => WriteHandle -> msg -> m () Source #

Send JSON message with given WriteHandle

readMessage :: (MonadIO m, MonadThrow m, FromJSON msg) => ReadHandle -> m msg Source #

Read JSON message with given ReadHandle

exampleWithFD :: MsgIn -> IO (MsgOut, MsgOut) Source #

Example using file descriptor

exampleServerWithProcess :: MsgIn -> IO (Either NodeIPCError (MsgOut, MsgOut)) Source #

Example of an IPC server that is using haskell executable as an server.

This will be the server, the one which sends the message (such as Ping, QueryPort) to get the response from the client. The client is executed via stack exec node-ipc haskell

getReadWriteHandles :: IO (ReadHandle, WriteHandle) Source #

Create a pipe for interprocess communication and return a (ReadHandle, WriteHandle) Handle pair.

getHandleFromEnv :: String -> IO (Either NodeIPCError Handle) Source #

Acquire a Handle that can be used for IPC from Environment

Predicates