Copyright | (c) Andrew Gibiansky, 2016 |
---|---|
License | MIT |
Maintainer | andrew.gibiansky@gmail.com |
Stability | stable |
Portability | POSIX |
Safe Haskell | None |
Language | Haskell2010 |
This is a primarily internal module; users of the jupyter
package do not need to import or
use functions or data types from this module.
This module provides a low-level interface to the Jupyter ZeroMQ sockets, message encoding, and
message decoding. The primary interface consists of withKernelSockets
and withClientSockets
, which
create the sets of sockets needed to serve a kernel or run a client, and sendMessage
and receiveMessage
,
which, as the names may imply, send and receive messages (encoding and decoding them along the way) on the
sockets.
- data KernelSockets z = KernelSockets {}
- withKernelSockets :: Maybe KernelProfile -> (forall z. KernelProfile -> KernelSockets z -> ZMQ z a) -> IO a
- data ClientSockets z = ClientSockets {}
- withClientSockets :: Maybe KernelProfile -> (forall z. KernelProfile -> ClientSockets z -> ZMQ z a) -> IO a
- data KernelProfile = KernelProfile {}
- type Port = Int
- type IP = String
- data Transport = TCP
- readProfile :: FilePath -> IO (Maybe KernelProfile)
- writeProfile :: KernelProfile -> FilePath -> IO ()
- sendMessage :: (IsMessage v, Sender a) => ByteString -> Socket z a -> MessageHeader -> v -> ZMQ z ()
- receiveMessage :: (IsMessage v, Receiver a) => Socket z a -> ZMQ z (Either String (MessageHeader, v))
- mkRequestHeader :: IsMessage v => UUID -> Username -> v -> IO MessageHeader
- mkReplyHeader :: IsMessage v => MessageHeader -> v -> IO MessageHeader
- threadKilledHandler :: AsyncException -> IO ()
- messagingError :: MonadIO m => String -> String -> m a
- data MessagingException = MessagingException String
Opening ZeroMQ Sockets
data KernelSockets z Source
The collection of ZeroMQ sockets needed to communicate with Jupyter clients on the Jupyter messaging wire protocol. These sockets are to be used by a kernel communicating with a client.
Roles of different sockets are described here.
KernelSockets | |
|
:: Maybe KernelProfile | Optionally, specify how the ZeroMQ sockets should be
opened, including the ports on which they should be
opened. If |
-> (forall z. KernelProfile -> KernelSockets z -> ZMQ z a) | Callback to invoke with the socket info and ZeroMQ sockets. |
-> IO a |
Create and bind all ZeroMQ sockets used for serving a Jupyter kernel. Store info about the
created sockets in a KernelProfile
, and then run a ZMQ
action, providing the used
KernelProfile
and the sockets themselves in a JupyterSockets
record.
data ClientSockets z Source
The collection of ZeroMQ sockets needed to communicate with Jupyter kernels on the Jupyter messaging wire protocol. These sockets are to be used by a client communicating with a kernel.
Roles of different sockets are described here.
ClientSockets | |
|
:: Maybe KernelProfile | Optionally, specify how the ZeroMQ sockets should be
opened, including the ports on which they should be
opened. If |
-> (forall z. KernelProfile -> ClientSockets z -> ZMQ z a) | Callback to invoke with the socket info and ZeroMQ sockets. |
-> IO a |
Create and bind all ZeroMQ sockets used for using a Jupyter kernel from a client. Store info about the
created sockets in a KernelProfile
, and then run a ZMQ
action, providing the used
KernelProfile
and the sockets themselves in a JupyterSockets
record.
Kernel Profiles
data KernelProfile Source
A kernel profile, specifying how the kernel communicates.
The kernel profile is usually obtained by a kernel by parsing the connection file passed to it as an argument as indicated by the kernelspec.
The profileTransport
, profileIp
and five profile Port fields specify the ports which the
kernel should bind to. These ports are usually generated fresh for every client or server started.
profileSignatureKey
is used to cryptographically sign messages, so that other users on the
system can’t send code to run in this kernel. See the
wire protocol documentation
for the details of how this signature is calculated.
More info on the fields of the connection file and the KernelProfile
is available in the
respective Jupyter documentation.
KernelProfile | |
|
Eq KernelProfile Source | |
Ord KernelProfile Source | |
Read KernelProfile Source | |
Show KernelProfile Source | |
ToJSON KernelProfile Source | Instance to decode a |
FromJSON KernelProfile Source | Decode a This object is passed to kernels in the connection file. |
The transport mechanism used to communicate with the Jupyter frontend.
TCP | Default transport mechanism via TCP. |
readProfile :: FilePath -> IO (Maybe KernelProfile) Source
Read a KernelProfile
from a file. This file (the connection file) should contain a
JSON-encoded object with all necessary fields, as described in the
connection files
section of the Jupyter documentation.
If the file contents cannot be parsed, Nothing
is returned.
writeProfile :: KernelProfile -> FilePath -> IO () Source
Write a KernelProfile
to a JSON file, which can be passed as the connection file to a
starting kernel.
Sending and Receiving messages
:: (IsMessage v, Sender a) | |
=> ByteString | HMAC key used to sign the message. |
-> Socket z a | Socket on which to send the message. |
-> MessageHeader | Header for the message. |
-> v | Data type representing the message to be send. |
-> ZMQ z () |
Send a Jupyter message on a socket, encoding it as described in the wire protocol documentation.
receiveMessage :: (IsMessage v, Receiver a) => Socket z a -> ZMQ z (Either String (MessageHeader, v)) Source
Read a client message from a ZeroMQ socket, as well as the message header that came with it. Block until all data for the message has been received.
If receiving all the data succeeds but parsing fails, return a String
error message.
This message is polymorphic in its return type v
, and so may be used to parse any message
type.
:: IsMessage v | |
=> UUID | Session UUID for this client session |
-> Username | Username to use in the header |
-> v | Message for which to make header (necessary to get |
-> IO MessageHeader | New |
Create a new MessageHeader
, which is suitable to be used for a request from a client to a
kernel.
The main difference between mkRequestHeader
and mkReplyHeader
is that a reply header has a
parent header, while a request header is not triggered by another message, and so has no parent
header. However, since there is no parent header to inherit information from, the session UUID
and username must be set explicitly.
:: IsMessage v | |
=> MessageHeader | Header of message being replied to |
-> v | Reply message for which to generate header (necessary to get |
-> IO MessageHeader | New |
Create a new MessageHeader
for a message which is a reply to a previous message.
Unlike mkRequestHeader
, mkReplyHeader
requires a parent header, and so is used for replies,
rather than for initiating a communication.
Miscellaneous utilities
threadKilledHandler :: AsyncException -> IO () Source
Handle an AsyncException
: if the exception is ThreadKilled
, then do nothing,
otherwise, rethrow the exception.
This helper utility exists to gracefully shutdown infinite loops in which we listen on
ZeroMQ sockets, and exists to stop ThreadKilled
exceptions from propagating back to
the main thread (which, presumably, is the thread that killed the thread in question).
This is a utility provided for use with listener threads.
Throw a MessagingException
with a descriptive error message.
Should be used when the messaging protocol is not being properly observed or in other unrecoverable situations.
data MessagingException Source
Exception to throw when the messaging protocol is not being observed.
See messagingError
.
Eq MessagingException Source | |
Ord MessagingException Source | |
Show MessagingException Source | |
Exception MessagingException Source | An |