void
print_jobs(edg_wll_JobStat *states)
{
- int i,j;
-
- for (i=0; states[i].state != EDG_WLL_JOB_UNDEF; i++) {
- char *id = edg_wlc_JobIdUnparse(states[i].jobId);
- char *st = edg_wll_StatToString(states[i].state);
-
- if (!states[i].parent_job) {
- if (states[i].jobtype == EDG_WLL_STAT_SIMPLE) {
- printf(" %s .... %s %s\n", id, st, (states[i].state==EDG_WLL_JOB_DONE) ? edg_wll_done_codeToString(states[i].done_code) : "" );
- }
- else if ((states[i].jobtype == EDG_WLL_STAT_DAG) ||
- (states[i].jobtype == EDG_WLL_STAT_COLLECTION)) {
- printf("%s %s .... %s %s\n", (states[i].jobtype==EDG_WLL_STAT_DAG)?"DAG ":"COLL",id, st, (states[i].state==EDG_WLL_JOB_DONE) ? edg_wll_done_codeToString(states[i].done_code) : "");
- for (j=0; states[j].state != EDG_WLL_JOB_UNDEF; j++) {
- if (states[j].parent_job) {
- char *par_id = edg_wlc_JobIdUnparse(states[j].parent_job);
-
- if (!strcmp(id,par_id)) {
- char *sub_id = edg_wlc_JobIdUnparse(states[j].jobId),
- *sub_st = edg_wll_StatToString(states[j].state);
-
- printf(" `- %s .... %s %s\n", sub_id, sub_st, (states[j].state==EDG_WLL_JOB_DONE) ? edg_wll_done_codeToString(states[j].done_code) : "");
- free(sub_id);
- free(sub_st);
- }
- free(par_id);
- }
- }
- }
- }
-
- free(id);
- free(st);
+ int i,j;
+
+ for (i=0; states[i].state != EDG_WLL_JOB_UNDEF; i++) {
+ char *id = edg_wlc_JobIdUnparse(states[i].jobId);
+ char *st = edg_wll_StatToString(states[i].state);
+
+ if (!states[i].parent_job) {
+ if (states[i].jobtype == EDG_WLL_STAT_SIMPLE) {
+ printf(" %s .... %s %s\n", id, st, (states[i].state==EDG_WLL_JOB_DONE) ? edg_wll_done_codeToString(states[i].done_code) : "" );
+ }
+ else if ((states[i].jobtype == EDG_WLL_STAT_DAG) ||
+ (states[i].jobtype == EDG_WLL_STAT_COLLECTION)) {
+ printf("%s %s .... %s %s\n", (states[i].jobtype==EDG_WLL_STAT_DAG)?"DAG ":"COLL",id, st, (states[i].state==EDG_WLL_JOB_DONE) ? edg_wll_done_codeToString(states[i].done_code) : "");
+ for (j=0; states[j].state != EDG_WLL_JOB_UNDEF; j++) {
+ if (states[j].parent_job) {
+ char *par_id = edg_wlc_JobIdUnparse(states[j].parent_job);
+
+ if (!strcmp(id,par_id)) {
+ char *sub_id = edg_wlc_JobIdUnparse(states[j].jobId),
+ *sub_st = edg_wll_StatToString(states[j].state);
+
+ printf(" `- %s .... %s %s\n", sub_id, sub_st, (states[j].state==EDG_WLL_JOB_DONE) ? edg_wll_done_codeToString(states[j].done_code) : "");
+ free(sub_id);
+ free(sub_st);
+ }
+ free(par_id);
+ }
}
-
- printf("\nFound %d jobs\n",i);
+ }
+ }
+
+ free(id);
+ free(st);
+ }
+
+ printf("\nFound %d jobs\n",i);
}
\marginpar{Naming conventions}%
All names exported by the \LB library (function names, symbolic
constants) are prefixed to avoid name clashes. The prefix is
-\lstinline'edg_wll_' for function names and \lstinline'EDG_WLL_' for
-symbolic constants. In C++ the namespace \lstinline'glite::lb' is used
+\verb'edg_wll_' for function names and \verb'EDG_WLL_' for
+symbolic constants. In C++ the namespace \verb'glite::lb' is used
instead.
\marginpar{Symbolic constants}%
If pointers are passed in output of function call (either as a return
value, output argument or part of structure), the corresponding
objects are \emph{always} allocated dynamically and have to be freed
-when not used anymore.
+when not used anymore. Structures defined in \LB API can be
+deallocated by calling convenience
+\verb'edg_wll_Free'\textit{Type}\verb'()' functions. {\it This
+deallocates members of the structure, but not the structure itself. It
+has to be \verb'free()''d explicitly.}
\marginpar{Opaque and transparent types}%
Types used in \LB API are either opaque or transparent. \textit{Opaque
types} are considered internal to the library, their structure is not
exposed to users and is subject to change without notice. The only way
to modify opaque objects is to use API calls. Example of opaque type
-is \lstinline'edg_wll_Context'.
+is \verb'edg_wll_Context'.
Structure of \textit{transparent types} is completely visible to
user, is well documented and no incompatible changes will be done
without notice. Example of transparent type is
-\lstinline'edg_wll_Event'.
+\verb'edg_wll_Event'.
\marginpar{Return values}%
-The return type of most of the API functions is \lstinline'int'.
+The return type of most of the API functions is \verb'int'.
Unless specified otherwise, zero return value means success, non-zero
-failure. Standard error codes from \lstinline'<errno.h>' are used as
+failure. Standard error codes from \verb'errno.h' are used as
much as possible. In a few cases the error can not be intuitively
mapped and \LB specific error value greater than
-\lstinline'EDG_WLL_ERROR_BASE' is returned.
+\verb'EDG_WLL_ERROR_BASE' is returned.
\TODO{mozna by stalo za to zminit f-ce edg\_wll\_*Error*}
-Few API function return \lstinline'char *'. In such a~case
-\lstinline'NULL' indicates an error, non-null value means success.
+Few API function return \verb'char *'. In such a~case
+\verb'NULL' indicates an error, non-null value means success.
\subsection{Context and Parameter Settings}
\label{s:context}
at the same time. One thread may use more than one context, though.
Upon context initialization, all the parameters are assigned default
-values. If not set explicitely, many of the parameters take their
+values. If not set explicitly, many of the parameters take their
value from environment variables. If the corresponding environment
variable is set, the parameter is initialized to its value instead of
the default. Note that a~few parameters cannot be assigned default
For use with the \emph{producer} calls (see section~\ref{s:producer})
the context has to be assigned a~single \jobid (with the
-\lstinline'edg_wll_SetLoggingJob' call), and keeps track of an event
+\verb'edg_wll_SetLoggingJob()' call), and keeps track of an event
\emph{sequence code} for the job (see~\cite{lbug}, detailed
description in~\cite{lbarch}).
The context object and its API functions are described more thoroughly
-in section~\ref{s:edg_wll_context}.
+in section~\ref{s:edg_wll_context}
\subsection{Connection Pool}
The \LB library maintains pool of client--server connections to
\subsubsection{Context}
\label{s:edg_wll_context}
-\marginpar{Context initialization}
+\marginpar{Context initialization}%
Opaque data structure representing \LB API context (see
-section~\ref{s:context}) is named \lstinline'edg_wll_Context'.
+section~\ref{s:context}) is named \verb'edg_wll_Context'.
The context must be initialized before the first \LB API call:
\begin{lstlisting}
#include <glite/lb/context.h>
\marginpar{Parameter setting}%
The context parameters can be set explicitly by calling
-\lstinline'edg_wll_SetParam(edg_wll_Context *, edg_wll_ContextParam, ...)'
+\begin{lstlisting}
+int edg_wll_SetParam(edg_wll_Context *, edg_wll_ContextParam, ...);
+\end{lstlisting}
function. The second argument is symbolic name of the context
parameter; parameters specific for producer and consumer API are
described in respective API sections, the common parameters are:
\end{table}
The third argument is parameter value, which can be of type
-\lstinline'int', \lstinline'char *' or \lstinline'struct timeval *'.
-If the parameter value is set to \lstinline'NULL' (or 0), the
+\verb'int', \verb'char *' or \verb'struct timeval *'.
+If the parameter value is set to \verb'NULL' (or 0), the
parameter is reset to the default value.
If you want to obtain current value of some context parameter, call
-\lstinline'edg_wll_GetParam(edg_wll_Context, edg_wll_ContextParam, ...)' function:
+\begin{lstlisting}
+int edg_wll_GetParam(edg_wll_Context, edg_wll_ContextParam, ...);
+\end{lstlisting}
+function:
\begin{lstlisting}
char *cert_file;
\label{s:edg_wll_Event}
The transparent data structure \verb'edg_wll_Event' represents \LB
event, atomic data unit received and processed by \LB. It is a set of
-key--value pairs with predefined structure -- allowed event types and
-attributes. The only important operation defined on
-\verb'edg_wll_Event' itself is
-\lstinline{edg\_wll\_FreeEvent(edg\_wll\_Event *event)} to free the
-event structure.
-
+attributes (\ie key--value pairs) with predefined structure -- there
+are common attributes and each defined event type allows for specific
+set of additional attributes. The most important common event
+attributes are listed in table~\ref{t:cevent},
\begin{table}[h]
\begin{tabularx}{\textwidth}{llX}
\label{t:cevent}
\end{table}
-
-
The \verb'edg_wll_Event' is returned by consumer \LB
-API job event related calls. The data structure has common part and
-event type specific part. Most important common event attributes are
-listed in table~\ref{t:cevent}, for more information see file
-\verb'org.glite.lb.types/types.T'
+API job event related calls. The only important operation defined on
+\verb'edg_wll_Event' itself is
+\begin{lstlisting}
+edg_wll_FreeEvent(edg_wll_Event *event)
+\end{lstlisting}
+to free the event structure.
\marginpar{List of event types}%
The event structure makes use of enumerated types extensively,
}
\end{lstlisting}
+For more information see file \verb'include/glite/lb/events.h'
\subsubsection{JobStatus}
-Data type \texttt{edg\_wll\_JobStat} represents status of a job as
-computed by \LB from received events. The data structure have a common
-part and a job state specific part. Most important common
-attributes:
-\begin{itemize}
- \item \texttt{state} -- numeric code of the status
- (EDG\_WLL\_JOB\_SUBMITTED, EDG\_WLL\_JOB\_WAITING, \dots)
- \item \texttt{type} -- type of the job (EDG\_WLL\_JOB\_SIMPLE,
- EDG\_WLL\_JOB\_DAG, EDG\_WLL\_JOB\_COLLECTION)
- \item \texttt{children} -- list of subjob \jobid's
-\end{itemize}
+The transparent data type \verb'edg_wll_JobStat' represents status of
+a job as computed by the \LB from received events. Much like the
+\verb'edg_wll_Event' structure it can be viewed as a set of
+attributes, where some attributes are common and some specific
+for a given job state (but unlike the \verb'edg_wll_Event' it is not
+implemented as union of structs but rather as one big struct). Most
+important common attributes are summarized in table~\ref{t:cstatus}.
+
+\TODO{Is somewhere documented what attributes are filled in for given
+job type and status?}
+
+\begin{table}[h]
+\begin{tabularx}{\linewidth}{llX}
+\bf Attribute name & \bf Attribute type & \bf Description \\
+\hline
+\verb'jobId' & \verb'glite_jobid_t' & Job identifier of this job. \\
+\verb'state' & \verb'edg_wll_JobStatCode' & Numeric code of the status, \eg
+\verb'EDG_WLL_JOB_SUBMITTED'. \\
+\verb'type' & \verb'enum edg_wll_StatJobtype' & Type of the job, \eg
+\verb'EDG_WLL_JOB_SIMPLE'. \\
+\verb'children' & \verb'char**' & List of subjob \jobid's \\
+\verb'owner' & \verb'char*' & Owner (certificate subject) of the
+job. \\
+\end{tabularx}
+\caption{Common job status attributes}
+\end{table}
+
+Job status structure is returned by the \LB consumer API job status
+queries. When no longer used, it has to be freed by calling
+\begin{lstlisting}
+void edg_wll_FreeStatus(edg_wll_JobStat *);
+\end{lstlisting}
+
+The following example prints out the states of jobs given in the input
+list; the job states are printed together with their subjobs on the
+same input list:
+\lstinputlisting[firstline=12,numbers=left]{util.c}
+
+For more information see file \verb'include/glite/lb/jobstat.h'
\subsubsection{Building Programs}
+The easiest way to build programs using the \LB library is to use
+GNU's libtool to take care of all the dependencies:
+\begin{verbatim}
+flavour=gcc32dbg
+libtool --mode=compile gcc -c example1.c util.c \
+ -I$GLITE_LOCATION/include -D_GNU_SOURCE
+libtool --mode=link gcc -o example1 example1.o util.o \
+ -L$GLITE_LOCATION/lib -lglite_lb_client_$flavour
+\end{verbatim}
+The library comes in different flavours (with/without debugging
+symbols, with/withou thread support) which in turn depend on the
+correct Globus library flavours.
+
+\TODO{Library dependencies - which rpms are needed?}
\subsection{C++ Language Binding}
\marginpar{Exceptions}%
% -*- mode: latex -*-
\section{\LB\ Logging (Producer) API}
-\label{ProdOverview}
+\label{s:ProdOverview}
+
+\subsection{C Language Binding}
The \LB\ logging API (or producer API) is used to create and deliver
events to the \LB\ server and/or proxy, depending on the function
used:
\verb'edg_wll_LogUserTag*(...)' and \verb'edg_wll_ChangeACL(...)' are
the only functions of interest.
-\subsection{Call semantics}
+\subsubsection{Call semantics}
\LB producer calls generally do not have transaction semantics, the
query following succesful logging call is not guaranteed to see
updated \LB server state. The typical call -- loging an event -- is
Job registrations are all synchronous.
-\subsection{Header files}
+\subsubsection{Header files}
\begin{table}[h]
\begin{tabularx}{\textwidth}{>{\tt}lX}
\end{tabularx}
\end{table}
-\subsection{Context parameters}
-The table\ref{} summarizes context parameters relevant to the
+\subsubsection{Context parameters}
+The table\ref{t:pcontext} summarizes context parameters relevant to the
event logging. If parameter is not set in the context explicitly, the
\LB\ library will search for value of corresponding environment
variable. The symbolic C names should be prepended with
\lstinline'GLITE_WMS_LBPROXY_USER' & Certificate subject of the user
(if logging through \LB\ proxy). \\
\end{tabularx}
+\caption{Producer specific context parameters}
+\label{t:pcontext}
\end{table}
The \verb'GLITE_WMS_LOG_DESTINATION' environment variable contains
both locallogger host and port separated by colon (\ie\ ``host:port'').
-\subsection{Return values}
+\subsubsection{Return values}
The logging functions return 0 on success and one of \texttt{EINVAL,
ENOSPC, ENOMEM, ECONNREFUSED, EAGAIN} on error. If \texttt{EAGAIN} is
returned, the function should be called again to retry the delivery;
The synchronous variants of logging functions can in addition return
\verb'EDG_WLL_ERROR_NOJOBID' or \verb'EDG_WLL_ERROR_DB_DUP_KEY'.
-\subsection{Logging events}
+\subsubsection{Logging events}
\TODO{odkaz na soubor}
In this section we will give an example how to log an UserTag event to
the \LB.
\subsection{Java binding}
\TODO{mirek}
-\TODO{C, C++, WS doplnit jako subsekce}
\ No newline at end of file