Use lstinline to display inline code instead of texttt
This commit is contained in:
@ -4,14 +4,14 @@
|
||||
It is important to understand that the Tutorial Framework is currently implemented as
|
||||
two Docker images:
|
||||
\begin{itemize}
|
||||
\item the \texttt{solvable} image is responsible for running the framework and the client
|
||||
\item the \code{solvable} image is responsible for running the framework and the client
|
||||
code depending on it
|
||||
\item the \texttt{controller} image is responsible for solution checking (to figure out
|
||||
\item the \code{controller} image is responsible for solution checking (to figure out
|
||||
whether the user completed the tutorial or not)
|
||||
\end{itemize}
|
||||
During most of this capter I am going to be discussing the \texttt{solvable} Docker image,
|
||||
with the exception of section~\ref{solutioncheck}, where I will dive into how the
|
||||
\texttt{controller} image is implemented.
|
||||
During most of this capter I am going to be discussing the \code{solvable} Docker image,
|
||||
with the exception of Section~\ref{solutioncheck}, where I will dive into how the
|
||||
\code{controller} image is implemented.
|
||||
|
||||
The most important feature of the framework is it's messaging system.
|
||||
Basically what we need is a system where processes running inside a Docker container
|
||||
@ -51,7 +51,7 @@ of your website (and as such requiring to go over the whole TCP handshake and th
|
||||
HTTP request-response on each update).
|
||||
This has been superseded by WebSockets around 2011, which provide a full-duplex
|
||||
communication channel over TCP between your browser and the server.
|
||||
This is done by initiation a protocol handshake using the \texttt{Connection: Upgrade}
|
||||
This is done by initiation a protocol handshake using the \code{Connection: Upgrade}
|
||||
HTTP header, which establishes a premanent socket connection between the browser
|
||||
and the server.
|
||||
This allows for communication with lower overhead and latency facilitating efficient
|
||||
@ -85,7 +85,7 @@ A few examples of top contenders and reasons for not using them in the end:
|
||||
\item The handling of raw TCP sockets would involve lot's of boilerplate logic that
|
||||
already have quality implementations in messaging libraries: i.e.\ making sure that
|
||||
all bytes are sent or received both require checking the return values of the
|
||||
libc \texttt{send()} and \texttt{recv()} system calls, while ZMQ takes care of this
|
||||
libc \code{send()} and \code{recv()} system calls, while ZMQ takes care of this
|
||||
extra logic involved and even provides higher level messaging patterns such as
|
||||
subscribe-publish, which would need to be implemented on top of raw sockets again.
|
||||
\item Using something like gRPC\footnote{\href{https://grpc.io}{https://grpc.io}}
|
||||
@ -113,10 +113,10 @@ Architecturally TFW consists of four main components:
|
||||
\item \textbf{TFW (proxy) server}: responsible for message routing/proxying
|
||||
between the frontend and event handlers
|
||||
\item \textbf{TFW FSM}: a finite state machine responsible for tracking user progress,
|
||||
that is implemented as an event handler called \texttt{FSMManagingEventHandler}
|
||||
that is implemented as an event handler called \code{FSMManagingEventHandler}
|
||||
\end{itemize}
|
||||
Note that it is important to keep in mind that as I've mentioned previously,
|
||||
the TFW Server and event handlers reside in the \texttt{solvable} Docker container.
|
||||
the TFW Server and event handlers reside in the \code{solvable} Docker container.
|
||||
They all run in separate processes and only communicate using ZeroMQ sockets.
|
||||
|
||||
In the following sections I am going to explain each of the main components in
|
||||
@ -147,17 +147,17 @@ Let's inspect further what a valid TFW message might look like:
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
All valid messages \emph{must} include a \texttt{key} field as this is used by the
|
||||
All valid messages \emph{must} include a \code{key} field as this is used by the
|
||||
framework for addressing: event handlers and frontend components subscribe to one
|
||||
or more \texttt{key}s and only receive messages with \texttt{key}s they have
|
||||
or more \code{key}s and only receive messages with \code{key}s they have
|
||||
subscribed to.
|
||||
It is possible to send a message with an empty key, however these messages will not
|
||||
be forwarded by the TFW server (but will reach it, so in case the target of a message
|
||||
is the TFW server exclusively, an empty \texttt{key} can may used).
|
||||
is the TFW server exclusively, an empty \code{key} can may used).
|
||||
|
||||
The rest of the fields are optional, but most messages will carry something
|
||||
in their \texttt{data} field.
|
||||
The purpose \texttt{trigger} and \texttt{signature} fields will be detailed
|
||||
in their \code{data} field.
|
||||
The purpose \code{trigger} and \code{signature} fields will be detailed
|
||||
at a later point in this paper.
|
||||
|
||||
\subsection{Networking Details}
|
||||
@ -171,8 +171,8 @@ the frontend via WebSockets.
|
||||
The TFW server is also capable of ``reflecting'' messages back to the side they were
|
||||
received on (to faciliate event handler to event handler for instance), or broadcast
|
||||
messages to all components.
|
||||
This is possible by embedding a whole TFW message in the \texttt{data} field of
|
||||
an outer wrapper message with a special \texttt{key} that signals to the TFW server that
|
||||
This is possible by embedding a whole TFW message in the \code{data} field of
|
||||
an outer wrapper message with a special \code{key} that signals to the TFW server that
|
||||
this message requires special attention.
|
||||
An example of this would be:
|
||||
\begin{lstlisting}[captionpos=b,caption={Broadcasting and mirroring TFW messages}]
|
||||
@ -187,12 +187,12 @@ An example of this would be:
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
Any invalid messages (not valid JSON or no \texttt{key} field present) are ignored
|
||||
Any invalid messages (not valid JSON or no \code{key} field present) are ignored
|
||||
by the TFW server.
|
||||
|
||||
\subsection{Event Handlers}
|
||||
|
||||
Event handlers are processes running in the \texttt{solvable} Docker container
|
||||
Event handlers are processes running in the \code{solvable} Docker container
|
||||
that subscribe to specific message types using ZeroMQ sockets.
|
||||
As discussed earlier, using ZeroMQ allows developers to implement event handlers
|
||||
in a wide variety of programming languages.
|
||||
@ -253,7 +253,7 @@ This code editor is essentially a Monaco editor%
|
||||
{https://microsoft.github.io/monaco-editor/}}
|
||||
instance integrated into Angular and upgraded with the capability to
|
||||
exchanges messages with an event handler to save, read and edit files
|
||||
that reside in the writeable file system of the \texttt{solvable}
|
||||
that reside in the writeable file system of the \code{solvable}
|
||||
Docker container.
|
||||
|
||||
All of the built-ins come with full API documentation explaining what they do
|
||||
@ -337,7 +337,7 @@ state transitions, or onentering and exiting a state.
|
||||
It is \emph{very} important to be aware of these callbacks, as much of the
|
||||
actual tutorial logic is often going to be implemented in these.
|
||||
|
||||
Architecturally a built-in event handler called \texttt{FSMManagingEventHandler}
|
||||
Architecturally a built-in event handler called \code{FSMManagingEventHandler}
|
||||
is capable of managing the FSM defined by clients.
|
||||
The responsibilities of said event handler include:
|
||||
\begin{itemize}
|
||||
@ -347,16 +347,16 @@ The responsibilities of said event handler include:
|
||||
such as successful transitions
|
||||
\end{itemize}
|
||||
|
||||
The \texttt{trigger} field of a message can be used to step the framework FSM
|
||||
The \code{trigger} field of a message can be used to step the framework FSM
|
||||
if all preconditions are met.
|
||||
The way this works is if the TFW server encounters a message with a
|
||||
\texttt{trigger} defined, it notifies the event handler managing
|
||||
\code{trigger} defined, it notifies the event handler managing
|
||||
the state machine.
|
||||
|
||||
Since messages can come from unauthenticated sources, it is possible to
|
||||
enforce the authentication of privileged messages, such as messages containing a \texttt{trigger}.
|
||||
enforce the authentication of privileged messages, such as messages containing a \code{trigger}.
|
||||
The framework allows trusted code to access a cryptographic key on the file system, which
|
||||
can be used to digitally sign messages (this is what the \texttt{signature} message
|
||||
can be used to digitally sign messages (this is what the \code{signature} message
|
||||
field is designed for).
|
||||
In this case the TFW server will only forward privileged messages that
|
||||
have a valid signature.
|
||||
@ -364,9 +364,9 @@ have a valid signature.
|
||||
\subsection{Solution checking}\label{solutioncheck}
|
||||
|
||||
Traditionally most challenges on the Avatao platform implement a Docker image called
|
||||
\texttt{controller}, which is responsible for detecting the successful
|
||||
\code{controller}, which is responsible for detecting the successful
|
||||
solution of a challenge.
|
||||
When using the Tutorial Framework a pre-implemented \texttt{controller}
|
||||
When using the Tutorial Framework a pre-implemented \code{controller}
|
||||
image is available, which listens to messages emitted by the
|
||||
framework FSM, and detects if the final state defined by developers is reached.
|
||||
This means that if content creators implement a proper FSM, the solution checking
|
||||
|
Reference in New Issue
Block a user