The glue in the system is written in \gls{iTasks}. Functions for managing
devices, \glspl{Task} and \glspl{SDS} are created. An interface is made that
allows an interactive management console for the \gls{mTask} system. This
interface provides functionality to list shares, add tasks, remove tasks,
administrate devices and view the state of the system.

\section{Integration}
When the system starts up the devices residing in the \gls{SDS} must be cleaned
up. It might be the case that they contain tasks, shares or errors. A user or
programmer can then choose to reconnect some devices using the
\CI{connectDevice} function.

\begin{lstlisting}[caption={Starting up the devices},%
	label={lst:startupdevs}]
startupDevices :: Task [MTaskDevice]
startupDevices = upd (map reset) deviceStoreNP
	where reset d = {d & deviceTask=Nothing, deviceTasks=[], deviceError=Nothing}
\end{lstlisting}

An image of the management interface is shown in Figure~\ref{lst:manage}.
The system management is done by a single \gls{Task} called \CI{mTaskManager}.
To manage the system, a couple of different functionalities are needed and
are launched. The left sidebar of the interface shows the list of example
\glspl{Task} that are present in the system. When clicking a task, a dialog
opens in which you can select the device to send the task to.  The dialog might
contain user specified variables. All example \glspl{mTask} are of the type
\CI{Task (Main (ByteCode () Stmt))} and can thus ask for user input first.

The bottom panel shows the device information. In this panel, the devices can
be created and modified. Moreover, this panel allows the user to reconnect with
a device after a restart of the server application.

\begin{figure}[H]
	\centering
	\includegraphics[width=\linewidth]{manage}
	\caption{The device management interface}\label{lst:management}
\end{figure}

\section{Shares}
The architecture of the system stores the \glspl{SDS} in the \gls{SDS} that
stores the list of devices. This means that if a \gls{SDS} updates, everyone
watching it will be notified. This would result in to a lot of notifications
that are not ment to be for the listener. Moreover, when a client updates the
\gls{SDS} this is processed by the connection handler and results in an update
of the real \gls{SDS}. When an \gls{iTasks}-\gls{Task} writes to a \gls{SDS}
this is not passed on to the device.

To solve the problem, parametric lenses are used on the device storage.
Listing~\ref{lst:actualdev} shows the actual types for the device storage.
Programmers wanting to access the entire \gls{SDS} use the \CI{deviceStoreNP}.
Programmers wanting to access a single \gls{SDS} on a device can use the
\CI{getRealShare} function which is a wrapper around the \CI{deviceStore} which
applies a parametric lens to the \gls{SDS}.

\begin{lstlisting}[label={lst:actualdev},%
	caption={Real types for the device \gls{SDS}}]
deviceStoreNP :: Shared [MTaskDevice]
deviceStore :: RWShared (Maybe (MTaskDevice, Int)) [MTaskDevice] [MTaskDevice]

realDeviceStore :: Shared [MTaskDevice]

getRealShare :: MTaskDevice MTaskShare -> Shared BCValue
\end{lstlisting}

\subsection{Parametric Lens}
The type of the parametric lens is \CI{Maybe (MTaskDevice, Int)} where the
\CI{Int} is the identifier of the \gls{SDS}. The \gls{iTasks} way of applying
lenses is through the \CI{sdsFocus} function and through the \CI{sdsLens}
functions. \CI{sdsFocus} allows the programmer to fix the parameter.
\CI{sdsLens} is basically a \CI{mapReadWrite} that has access to the parameter.
This allows the programmer to create filters and lenses. Both of the methods
are not good enough for the device \gls{SDS} because they do not achieve the
writing to the actual device. Writing to a device requires being able to write
to shares. To solve this problem, a real base \gls{SDS} is created. All the
details are visible in Listing~\ref{shareimpl}.
\todo{elaborate}

\begin{lstlisting}[label={lst:shareimpl},%
	caption={Base share implementation}]
realDeviceStore :: Shared [MTaskDevice]
realDeviceStore = memoryShare "mTaskDevices" []

deviceStore :: RWShared (Maybe (MTaskDevice, Int)) [MTaskDevice] [MTaskDevice]
deviceStore = SDSSource {SDSSource | name="deviceStore", read=realRead, write=realWrite}
where
	realRead :: (Maybe (MTaskDevice,Int)) *IWorld -> (MaybeError TaskException [MTaskDevice], *IWorld)
	realRead p iw = read realDeviceStore iw

	realWrite :: (Maybe (MTaskDevice,Int)) [MTaskDevice] *IWorld
			-> (MaybeError TaskException (SDSNotifyPred (Maybe (MTaskDevice,Int))), *IWorld)
	realWrite mi w iw
	# (merr, iw) = write w realDeviceStore iw
	| isError merr || isNothing mi = (merr $> notifyPred mi, iw)
	# (Just (dev, ident)) = mi
	| ident == -1 = (merr $> notifyPred mi, iw)
	= case find ((==)dev) w of
		Nothing = (Error $ exception "Device doesn't exist anymore", iw)
		Just {deviceShares} = case find (\d->d.identifier == ident) deviceShares of
			Nothing = (Error $ exception $ "deviceStore: Share doesn't exist: " +++ toString ident, iw)
			Just s = case sendMessagesIW [MTUpd ident s.MTaskShare.value] dev iw of
				(Error e, iw) = (Error e, iw)
				(Ok _, iw) = (Ok $ notifyPred mi, iw)

	notifyPred :: (Maybe (MTaskDevice, Int)) (Maybe (MTaskDevice, Int)) -> Bool
	notifyPred Nothing Nothing = True
	notifyPred Nothing (Just _) = False
	notifyPred (Just _) Nothing = False
	notifyPred (Just (d1, -1)) (Just (d2, _)) = d1 == d2
	notifyPred (Just (d1, i1)) (Just (d2, i2)) = d1 == d2 && i1 == i2
\end{lstlisting}
