drms_server
+----------------------------------------------+
| |
+----------+ | +--------+ +--------+++ +-------------+ |
| | | | +-+ in ||+--+ | |
| SUMS +---+---+ SUMS | +--------+++ | +---+-------- client 0
| | | | thread | +++--------+ | | |
| | | | +-+|| out +--+ +---+-------- client 1
+----------+ | +--------+ +++--------+ | | |
| +--------+ | | |
| | | | | |
| | signal ----------------+ +---+-------- client n
| | thread | | server | |
| | | | thread pool | |
| +--------+ +------++-----+ |
+-----------------------------------++---------+
+------++-----+
| |
| DB |
| |
+-------------+The drms_server is designed to support multiple client modules running at the same time. It performs the following major tasks:
drms_server opens a single DB connection. This DB connection is shared by all modules connected to the same drms_server program via sockets. Such shared DB connection makes drms_commit() issued from the client modules extremely hazardous, e.g., one client module can inadvadently commit another client module data. The correct usage of drms_commit requires higher level coordination among the client modules.
drms_server talks the SUMS via SUMS API. All the interactions with SUMS are happenning in the SUMS thread, drms_sums_thread. This thread retrieves SUMS request from the sum_inbox, and places SUMS reply in sum_outbox. Both sum_inbox and sum_outbox are FIFO queues with the thread id as tag. They are shared memory. Don't insert local variable into the queue unless you are sure to get the reply back before the local variable vanishes. Due to FIFO queue implementation, only the head of the queue is examined. if the head is not removed, nothing behind it can be removed.
| producer | consumer | |
| sum_inbox | any call to SUMS API | drms_sums_thread |
| sum_outbox | drms_sums_thread | function that needs SUMS call reply |
The closing sequence can be tricky, one might run into race condition if not careful. There are two exit routes: drms_server_commit() and drms_server_abort().
drms_delete_temporaries() removes all records created as DRMS_TRANSIENT drms_commit_all_units() commits all data units (does not include log SU) drms_server_close_session() { fflush() on stdout and stderr restore_stder() drms_commit() log SU update drms_session table entry } wait for SUMS threads to finish via pthread_join() disconnect stat db connection db_commit() for data db connection db_abort() for data db connection? drms_free_env()
db_rollback() on db data connection drms_server_close_session() add to sums inbox/outbox to thaw thread that may be waiting disconnect stat db connection db_abort() for data db connection sleep() to wait for other threads to finish cleanly. drms_free_env()
drms_server [FLAGS] [SESSION_ARGUMENTS]
-h: Show drms_server usage information. -V: Run drms_server in verbose mode. -Q: Run drms_server in quiet mode. -f: Run drms_server in the foreground. Without -f drms_server spawns a server in a background process, prints the connection info to stdout and exits. -A: Archive SUs opened for writing during this session. -L: Redirect stdout and stderr to SU log files. -n: Turn off Nagle's algorithm on TCP/IP sockets.param=value, where param is one of the following.JSOC_DBHOST Specifies (overrides) the database host to connect to. Default is DBNAME JSOC_DBNAME Specifies (overrides) the database name to use. Default is DBNAME JSOC_DBUSER Specifies (overrides) the username used during database host connection. Default is USER. JSOC_DBPASSWD Specifies (overrides) the password for the username. Default is PASSWD. JSOC_SESSIONNS Specifies (overrides) the DRMS session namespace. DRMS_RETENTION Sets (forces) the storage-unit retention time for the DRMS session started by <module>. DRMS_QUERY_MEM Sets the memory maximum for a database query. DRMS_SERVER_WAIT Non-zero value indicates waiting 2 seconds before exiting, otherwise don't wait.
Variables | |
| CmdParams_t | cmdparams |
| ModuleArgs_t | module_args [] |
| Global DRMS-module structure representing the default command-line arguments for a DRMS module. | |
| ModuleArgs_t * | gModArgs = module_args |
| Global DRMS-module pointer that refers to module_args. | |
| int | threadcounter = 0 |
| char * | abortmessage = NULL |
| DRMS_Env_t * | env |
Initial value:
{
{ARG_INT, "DRMS_RETENTION", "-1"},
{ARG_INT, "DRMS_QUERY_MEM", "512"},
{ARG_INT, "DRMS_SERVER_WAIT", "1"},
{}
}
module_args, a global array of ModuleArgs_t structures, provides a standard mechanism for declaring the parameters expected to be used by a module along with their types and default values, if any. module_args must be declared in every module. The elements of the module_args array are parsed and compared with arguments supplied to the module from the command line or other invocation to produce a CmdParams_t structure (cmdparams) through which their values are available through the params_get suite of functions.
The module_args declarator requires at least one element, which must be of type ARG_END (which is 0, so an empty initializer as shown in the synopsis is acceptable). Any array elements following the ARG_END element are ignored.
Although the default value (and range, if applicable) is supplied as a character string, it will be interpreted according to the declared type of the argument. Each element of cmdparams, except those of type ARG_VOID, must have a name field. Arguments of type ARG_INT, ARG_FLOAT, ARG_DOUBLE, and ARG_STRING should be self-explanatory. Arguemts of type ARG_FLAG are expected to have single-character names and to be associated with logical binaries, with a default value of FALSE (0); they can be set on the command line via the -X construct (where X is the name of the element to be set to TRUE). ARG_TIME is a special case of ARG_DOUBLE, whose default or assigned values are interpreted by sscan_time (q.v.). ARG_VOID is reserved for use with undeclared arguments supplied on the command line; it should not be used for declared arguments in the module_args list.
The types ARG_INTS, ARG_FLOATS, and ARG_DOUBLES are used for parameters that can be arrays of arbitrary length. The values must be supplied as comma separated sets enclosed within matched delimiting pairs of either brackets [], braces {} or parentheses () (unless there is only one value in the array, in which case the delimiters are optional). The total number of elements in the array is returned as the added parameter name_nvals, and the value for the nth element (counting from 0) as name_n_value. For example, a @ module_args element declared as:
{ARG_FLOATS, "lat", "[0.0, 5.0, 10.0]", "", ""},
would return 3 for params_get_int (params, "lat_nvals") and the value 5.0 for params_get_float (params, "lat_1_value"). The number of array values supplied at run time need not match the number in the default; indeed there is no necessity of setting any default value at all, just as with other types of arguments.
ARG_NUME is a special type of argument representing an enumeration class. It makes use of the module_args->range field, which must be a comma-separated list of strings. The value returned is an integer coresponding to the order number of the range element matching the supplied value. For example, a module_args element declared as:
{ARG_NUME, "color", "green", "", "red, yellow, green, blue"},
would return 2 for params_get_int (params, "color"). A failure occurs if the value supplied does not match anything in the range; the type is designed especially for use with driver programs that can provide menus of options, such as CGI forms.
ARG_DATASET and ARG_DATASERIES are special cases of ARG_STRING reserved for names of DRMS dataset specifications or series names in an environment where the database can be queried for possible values; they are not currently treated differently from any other type of string argument.
ARG_NEWDATA does not appear to be implemented; ARG_NUMARGS is reserved for internal use by the Fortran interface and should not be used.
To summarize, ModuleArgs_t->type must have one of the following values:
| ARG_INT | parameter is to be interpreted as type int |
| ARG_FLOAT | parameter is to be interpreted as type double |
| ARG_DOUBLE | parameter is to be interpreted as type double |
| ARG_TIME | parameter is to be interpreted as type double, with a conversion from standard date-time string formats to a standard reference epoch |
| ARG_STRING | parameter is to be interpreted as type char* |
| ARG_FLAG | the parameter is (ordinarily) a single-character named one which can take the value of 0 or 1. The default value, if present, should be 0; as the command-line flag specifier can only set its parameter values to 1; however, it is better to leave the default value empty, so that the cmdparams_exists function can be used in the code. |
| ARG_NUME | the parameter value is string-compared with the members of the module_args->range list, and replaced with the string representation of the number corresponding to the order number of the (first) matching token in the list; its value is subsequently to be interpreted as type int. Basically equivalent to type enum |
| ARG_INTS | (not yet implemented) |
| ARG_FLOATS | (not yet implemented) |
| ARG_DOUBLE | synonymous with ARG_FLOATS |
| ARG_VOID | (not yet implemented) |
| ARG_END | signals the end of the parsed argument list. Elements may follow in the declaration, but will be ignored. Since ARG_END is defined as 0, an empty (null) member serves the same purpose. |
The module_args->description is intended to be used only by the front-end handler for documentation, such as when the command is invoked with a -H help flag, or in CGI web forms.
Definition at line 174 of file drms_server.c.
1.5.4