\section{Network IO}
\label{Sec::NetworkIO}

When communicating to other services in the network, sometimes low-level socket IO is inevitable.
For this reason, \lib provides \emph{brokers}.
A broker is an event-based actor running in the middleman that multiplexes socket IO.
It can maintain any number of acceptors and connections.
Since the broker runs in the middleman, implementations should be careful to consume as little time as possible in message handlers.
Any considerable amount work should outsourced by spawning new actors (or maintaining worker actors).
All functions shown in this section can be accessed by including the header \lstinline^"caf/io/all.hpp"^ and live in the namespace \lstinline^caf::io^.


\subsection{Spawning Brokers}

Brokers are spawned using the function \lstinline^spawn_io^ and always use functor-based implementations capturing the self pointer of type \lstinline^broker*^.
For convenience, \lstinline^spawn_io_server^ can be used to spawn a new broker listening to a local port and \lstinline^spawn_io_client^ can be used to spawn a new broker that connects to given host and port or uses existing IO streams.

\begin{lstlisting}
template<spawn_options Os = no_spawn_options,
         typename F = std::function<behavior (broker*)>,
         typename... Ts>
actor spawn_io(F fun, Ts&&... args);

template<spawn_options Os = no_spawn_options,
         typename F = std::function<behavior (broker*)>,
         typename... Ts>
actor spawn_io_client(F fun,
                      input_stream_ptr in,
                      output_stream_ptr out,
                      Ts&&... args);

template<spawn_options Os = no_spawn_options,
         typename F = std::function<behavior (broker*)>,
         typename... Ts>
actor spawn_io_client(F fun, string host, uint16_t port, Ts&&... args);

template<spawn_options Os = no_spawn_options,
         typename F = std::function<behavior (broker*)>,
         typename... Ts>
actor spawn_io_server(F fun, uint16_t port, Ts&&... args);
\end{lstlisting}

\clearpage
\subsection{Broker Interface}
\label{Sec::NetworkIO::BrokerInterface}

\begin{lstlisting}
class broker;
\end{lstlisting}

{\small
\begin{tabular*}{\textwidth}{m{0.51\textwidth}m{0.44\textwidth}}
  \multicolumn{2}{m{\linewidth}}{\large{\textbf{Member Functions}}\vspace{3pt}} \\
  \\
  \hline
  \lstinline^void configure_read(^ \lstinline^connection_handle hdl,^ \lstinline^receive_policy::config config)^ & Modifies the receive policy for the connection identified by \lstinline^hdl^. This will cause the middleman to enqueue the next \lstinline^new_data_msg^ according to the given \lstinline^config^ created by \lstinline^receive_policy::exactly(x)^, \lstinline^receive_policy::at_most(x)^, or \lstinline^receive_policy::at_least(x)^ (with \lstinline^x^ denoting the number of bytes) \\
  \hline
  \lstinline^void write(connection_handle hdl,^ \lstinline^size_t num_bytes,^ \lstinline^const void* buf)^ & Writes data to the output buffer \\
  \hline
  \lstinline^void flush(connection_handle hdl)^ & Sends the data from the output buffer \\
  \hline
  \lstinline^template <class F, class... Ts>^ \lstinline^actor fork(F fun,^ \lstinline^connection_handle hdl, Ts&&... args)^ & Spawns a new broker that takes ownership of given connection \\
  \hline
  \lstinline^size_t num_connections()^ & Returns the number of open connections \\
  \hline
  \lstinline^void close(connection_handle hdl)^ & Closes a connection \\
  \hline
  \lstinline^void close(accept_handle hdl)^ & Closes an acceptor \\
  \hline
\end{tabular*}
}

\clearpage
\subsection{Broker-related Message Types}

Brokers receive system messages directly from the middleman whenever an event on one of it handles occurs.

\begin{lstlisting}
struct new_connection_msg {
  accept_handle source;
  connection_handle handle;
};
\end{lstlisting}

Whenever a new incoming connection (identified by the \lstinline^handle^ field) has been accepted for one of the broker's accept handles, it will receive a \lstinline^new_connection_msg^.

\begin{lstlisting}
struct new_data_msg {
  connection_handle handle;
  std::vector<char> buf;
};
\end{lstlisting}

New incoming data is transmitted to the broker using messages of type \lstinline^new_data_msg^.
The raw bytes can be accessed as buffer object of type \lstinline^std::vector<char>^.
The amount of data, i.e., how often this message is received, can be controlled using \lstinline^configure_read^ (see \ref{Sec::NetworkIO::BrokerInterface}).
It is worth mentioning that the buffer is re-used whenever possible.
This means, as long as the broker does not create any new references to the message by copying it, the middleman will always use only a single buffer per connection.

\begin{lstlisting}
struct connection_closed_msg {
  connection_handle handle;
};
\end{lstlisting}

\begin{lstlisting}
struct acceptor_closed_msg {
  accept_handle handle;
};
\end{lstlisting}


A \lstinline^connection_closed_msg^ or \lstinline^ acceptor_closed_msg^ informs the broker that one of it handles is no longer valid.
