[Opensrf-commits] r1882 - in trunk: include/opensrf src/libopensrf (scottmk)
svn at svn.open-ils.org
svn at svn.open-ils.org
Fri Jan 1 17:16:07 EST 2010
Author: scottmk
Date: 2010-01-01 17:16:01 -0500 (Fri, 01 Jan 2010)
New Revision: 1882
Modified:
trunk/include/opensrf/osrf_app_session.h
trunk/src/libopensrf/osrf_app_session.c
Log:
Incorporate _osrf_app_request_resend into osrf_app_session_request_resend(),
which had been its only caller. The code is trivial enough that it will be
simple to break out again if necessary. Meanwhile having it all in a single
function makes it more readable.
Free the hash table of requests correctly; i.e. all of each linked list, not
just the first node.
Various additions and refinements to comments; occasional tweaks to white space.
M include/opensrf/osrf_app_session.h
M src/libopensrf/osrf_app_session.c
Modified: trunk/include/opensrf/osrf_app_session.h
===================================================================
--- trunk/include/opensrf/osrf_app_session.h 2010-01-01 14:49:16 UTC (rev 1881)
+++ trunk/include/opensrf/osrf_app_session.h 2010-01-01 22:16:01 UTC (rev 1882)
@@ -47,7 +47,7 @@
*/
struct osrf_app_session_struct {
- /** Our messag passing object */
+ /** Our message passing object */
transport_client* transport_handle;
/** The original remote id of the remote service we're talking to */
@@ -64,7 +64,8 @@
/** Our ID */
char* session_id;
- /** true if this session does not require connect messages */
+ /** Boolean; true if this session does not require connect messages.
+ Assigned a value depending on the compile-time macro ASSUME_STATELESS. */
int stateless;
/** The connect state */
@@ -73,12 +74,13 @@
/** SERVER or CLIENT */
enum OSRF_SESSION_TYPE type;
- /** the current locale for this session **/
+ /** the current locale for this session. **/
char* session_locale;
- /** let the user use the session to store their own session data */
+ /** let the user use the session to store their own session data. */
void* userData;
+ /** Callback function for freeing user's session data. */
void (*userDataFree) (void*);
int transport_error;
Modified: trunk/src/libopensrf/osrf_app_session.c
===================================================================
--- trunk/src/libopensrf/osrf_app_session.c 2010-01-01 14:49:16 UTC (rev 1881)
+++ trunk/src/libopensrf/osrf_app_session.c 2010-01-01 22:16:01 UTC (rev 1882)
@@ -81,7 +81,7 @@
/**
@brief Free an osrfAppRequest and everything it owns.
- @param req Pointer to an osrfAppRequest, cast to a void pointer.
+ @param req Pointer to an osrfAppRequest.
*/
static void _osrf_app_request_free( osrfAppRequest * req ) {
if( req ) {
@@ -238,9 +238,11 @@
@param req Pointer to the osrfAppRequest representing the request.
@param timeout Maxmimum time to wait, in seconds.
- @return
+ @return Pointer to the next osrfMessage for this request, if one is available, or if it
+ becomes available before the end of the timeout; otherwise NULL;
- If the input queue for this request is not empty, dequeue the next message and return it.
+ If there is already a request available in the input queue, dequeuand return it
+ immediately.
*/
static osrfMessage* _osrf_app_request_recv( osrfAppRequest* req, int timeout ) {
@@ -318,22 +320,16 @@
return NULL;
}
-/** Resend this requests original request message */
-static int _osrf_app_request_resend( osrfAppRequest* req ) {
- if(req == NULL) return 0;
- if(!req->complete) {
- osrfLogDebug( OSRF_LOG_MARK, "Resending request [%d]", req->request_id );
- return _osrf_app_session_send( req->session, req->payload );
- }
- return 1;
-}
-
-
// --------------------------------------------------------------------------
// Session API
// --------------------------------------------------------------------------
-/** Install a locale for the session */
+/**
+ @brief Install a copy of a locale string in a specified session.
+ @param session Pointer to the osrfAppSession in which the locale is to be installed.
+ @param locale The locale string to be copied and installed.
+ @return A pointer to the installed copy of the locale string.
+*/
char* osrf_app_session_set_locale( osrfAppSession* session, const char* locale ) {
if (!session || !locale)
return NULL;
@@ -384,8 +380,23 @@
}
}
-/** Allocates and initializes a new app_session */
+/**
+ @brief Create an osrfAppSession for a client.
+ @param remote_service Name of the service to which to connect
+ @return Pointer to the new osrfAppSession if successful, or NULL upon error.
+ Allocate memory for an osrfAppSession, and initialize it as follows:
+
+ - For talking with Jabber, grab an existing transport_client that must have been
+ already set up by a prior call to osrfSystemBootstrapClientResc().
+ - Build a Jabber ID for addressing the service.
+ - Build a session ID based on a fine-grained timestamp and a process ID. This ID is
+ expected to be unique across the system, but uniqueness is not strictly guaranteed.
+ - Initialize various other bits and scraps.
+ - Add the session to the global session cache.
+
+ Do @em not connect to the service at this point.
+*/
osrfAppSession* osrfAppSessionClientInit( const char* remote_service ) {
if (!remote_service) {
@@ -395,6 +406,7 @@
osrfAppSession* session = safe_malloc(sizeof(osrfAppSession));
+ // Grab an existing transport_client for talking with Jabber
session->transport_handle = osrfSystemGetTransportClient();
if( session->transport_handle == NULL ) {
osrfLogWarning( OSRF_LOG_MARK, "No transport client for service 'client'");
@@ -402,10 +414,11 @@
return NULL;
}
+ // Get a list of domain names from the config settings;
+ // ignore all but the first one in the list.
osrfStringArray* arr = osrfNewStringArray(8);
osrfConfigGetValueList(NULL, arr, "/domain");
const char* domain = osrfStringArrayGetString(arr, 0);
-
if (!domain) {
osrfLogWarning( OSRF_LOG_MARK, "No domains specified in the OpenSRF config file");
free( session );
@@ -413,6 +426,7 @@
return NULL;
}
+ // Get a router name from the config settings.
char* router_name = osrfConfigGetValue(NULL, "/router_name");
if (!router_name) {
osrfLogWarning( OSRF_LOG_MARK, "No router name specified in the OpenSRF config file");
@@ -424,12 +438,13 @@
char target_buf[512];
target_buf[ 0 ] = '\0';
+ // Using the router name, domain, and service name,
+ // build a Jabber ID for addressing the service.
int len = snprintf( target_buf, sizeof(target_buf), "%s@%s/%s",
router_name ? router_name : "(null)",
domain ? domain : "(null)",
remote_service ? remote_service : "(null)" );
osrfStringArrayFree(arr);
- //free(domain);
free(router_name);
if( len >= sizeof( target_buf ) ) {
@@ -469,7 +484,6 @@
// Initialize the hash table
int i;
-
for( i = 0; i < OSRF_REQUEST_HASH_SIZE; ++i )
session->request_hash[ i ] = NULL;
@@ -477,17 +491,44 @@
return session;
}
+/**
+ @brief Find or create an osrfAppSession for a server.
+ @param session_id The session ID. In practice this comes from the thread member of
+ the transport message from the client.
+ @param our_app The name of the service being provided.
+ @param remote_id Jabber ID of the client.
+ @return Pointer to the newly created osrfAppSession if successful, or NULL upon failure.
+
+ First, look in the global session cache for session with the specified session ID. IF
+ you find one, return it immediately, ignoring the values of the @a our_app and @a
+ remote_id parameters. Otherwise:
+
+ - Allocate memory for an osrfAppSession.
+ - For talking with Jabber, grab an existing transport_client that must have been
+ already set up by a prior call to osrfSystemBootstrapClientResc().
+ - Install a copy of the @a our_app string as remote_service.
+ - Install copies of the @a remote_id string as remote_id and orig_remote_id.
+ - Initialize various other bits and scraps.
+ - Add the session to the global session cache.
+
+ Do @em not respond to the client at this point.
+*/
osrfAppSession* osrf_app_server_session_init(
const char* session_id, const char* our_app, const char* remote_id ) {
osrfLogDebug( OSRF_LOG_MARK, "Initing server session with session id %s, service %s,"
" and remote_id %s", session_id, our_app, remote_id );
+ // If such a session already exists, return it without further ado.
+ // In practice this should never happen, and should probably be treated as an
+ // error if it ever does.
osrfAppSession* session = osrf_app_session_find_session( session_id );
- if(session) return session;
+ if(session)
+ return session;
session = safe_malloc(sizeof(osrfAppSession));
+ // Grab an existing transport_client for talking with Jabber
session->transport_handle = osrfSystemGetTransportClient();
if( session->transport_handle == NULL ) {
osrfLogWarning( OSRF_LOG_MARK, "No transport client for service '%s'", our_app );
@@ -495,6 +536,9 @@
return NULL;
}
+ // Decide from a config setting whether the session is stateless or not. However
+ // this determination is pointless because it will immediately be overruled according
+ // to the compile-time macro ASSUME_STATELESS.
int stateless = 0;
char* statel = osrf_settings_host_value("/apps/%s/stateless", our_app );
if(statel) stateless = atoi(statel);
@@ -522,7 +566,6 @@
// Initialize the hash table
int i;
-
for( i = 0; i < OSRF_REQUEST_HASH_SIZE; ++i )
session->request_hash[ i ] = NULL;
@@ -781,12 +824,23 @@
return 1;
}
+/** Resend a request message, as specified by session and request id. */
int osrf_app_session_request_resend( osrfAppSession* session, int req_id ) {
osrfAppRequest* req = find_app_request( session, req_id );
- return _osrf_app_request_resend( req );
+
+ int rc;
+ if(req == NULL) {
+ rc = 0;
+ } else if(!req->complete) {
+ osrfLogDebug( OSRF_LOG_MARK, "Resending request [%d]", req->request_id );
+ rc = _osrf_app_session_send( req->session, req->payload );
+ } else {
+ rc = 1;
+ }
+
+ return rc;
}
-
static int osrfAppSessionSendBatch( osrfAppSession* session, osrfMessage* msgs[], int size ) {
if( !(session && msgs && size > 0) ) return 0;
@@ -864,8 +918,15 @@
return osrf_stack_process(session->transport_handle, timeout, recvd);
}
-/** Disconnects (if client) and removes the given session from the global session cache
- ! This frees all attached app_requests !
+/**
+ @brief Shut down and destroy an osrfAppSession.
+ @param session Pointer to the osrfAppSession to be destroyed.
+
+ If this is a client session, send a DISCONNECT message.
+
+ Remove the session from the global session cache.
+
+ Free all associated resources, including any pending osrfAppRequests.
*/
void osrfAppSessionFree( osrfAppSession* session ){
if(session == NULL) return;
@@ -901,7 +962,12 @@
// Free the request hash
int i;
for( i = 0; i < OSRF_REQUEST_HASH_SIZE; ++i ) {
- _osrf_app_request_free( session->request_hash[ i ] );
+ osrfAppRequest* app = session->request_hash[ i ];
+ while( app ) {
+ osrfAppRequest* next = app->next;
+ _osrf_app_request_free( app );
+ app = next;
+ }
}
free(session);
}
More information about the opensrf-commits
mailing list