From: erickson Date: Mon, 5 Feb 2007 19:16:43 +0000 (+0000) Subject: add support for child exit handlers and the logger xid string X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=86e361eb339ff80337baaf2832f48de11ef77333;p=Evergreen.git add support for child exit handlers and the logger xid string git-svn-id: svn://svn.open-ils.org/ILS/branches/rel_1_0@6883 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/OpenSRF/src/libstack/osrf_app_session.c b/OpenSRF/src/libstack/osrf_app_session.c index 0b3553717e..e3bfe5cbaf 100644 --- a/OpenSRF/src/libstack/osrf_app_session.c +++ b/OpenSRF/src/libstack/osrf_app_session.c @@ -32,6 +32,8 @@ void osrfAppSessionCleanup() { osrfHashFree(osrfAppSessionCache); } + + /** Frees memory used by an app_request object */ void _osrf_app_request_free( void * req ){ if( req == NULL ) return; @@ -308,6 +310,8 @@ int osrf_app_session_make_req( char* method_name, int protocol, string_array* param_strings ) { if(session == NULL) return -1; + osrfLogMkXid(); + osrf_message* req_msg = osrf_message_init( REQUEST, ++(session->thread_trace), protocol ); osrf_message_set_method(req_msg, method_name); if(params) { @@ -502,6 +506,7 @@ int osrfAppSessionSendBatch( osrfAppSession* session, osrf_message* msgs[], int transport_message* t_msg = message_init( string, "", session->session_id, session->remote_id, NULL ); + message_set_osrf_xid( t_msg, osrfLogGetXid() ); retval = client_send_message( session->transport_handle, t_msg ); diff --git a/OpenSRF/src/libstack/osrf_app_session.h b/OpenSRF/src/libstack/osrf_app_session.h index 0d8f8144de..af35af5e72 100644 --- a/OpenSRF/src/libstack/osrf_app_session.h +++ b/OpenSRF/src/libstack/osrf_app_session.h @@ -231,4 +231,5 @@ int osrfAppSessionStatus( osrfAppSession* ses, int type, char* name, int reqId, void osrfAppSessionCleanup(); + #endif diff --git a/OpenSRF/src/libstack/osrf_application.c b/OpenSRF/src/libstack/osrf_application.c index 238417e43a..1d62642ef9 100644 --- a/OpenSRF/src/libstack/osrf_application.c +++ b/OpenSRF/src/libstack/osrf_application.c @@ -16,6 +16,7 @@ int osrfAppRegisterApplication( char* appName, char* soFile ) { osrfApplication* app = safe_malloc(sizeof(osrfApplication)); app->handle = dlopen (soFile, RTLD_NOW); + app->onExit = NULL; if(!app->handle) { osrfLogWarning( OSRF_LOG_MARK, "Failed to dlopen library file %s: %s", soFile, dlerror() ); @@ -54,9 +55,31 @@ int osrfAppRegisterApplication( char* appName, char* soFile ) { osrfLogSetAppname(appName); + osrfAppSetOnExit(app, appName); + return 0; } + +void osrfAppSetOnExit(osrfApplication* app, char* appName) { + if(!(app && appName)) return; + + /* see if we can run the initialize method */ + char* error; + void (*onExit) (void); + *(void **) (&onExit) = dlsym(app->handle, "osrfAppChildExit"); + + if( (error = dlerror()) != NULL ) { + osrfLogDebug(OSRF_LOG_MARK, "No exit handler defined for %s", appName); + return; + } + + osrfLogInfo(OSRF_LOG_MARK, "registering exit handler for %s", appName); + app->onExit = (*onExit); + //if( (ret = (*onExit)()) ) { +} + + int osrfAppRunChildInit(char* appname) { osrfApplication* app = _osrfAppFindApplication(appname); if(!app) return -1; @@ -82,6 +105,18 @@ int osrfAppRunChildInit(char* appname) { } +void osrfAppRunExitCode() { + osrfHashIterator* itr = osrfNewHashIterator(__osrfAppHash); + osrfApplication* app; + while( (app = osrfHashIteratorNext(itr)) ) { + if( app->onExit ) { + osrfLogInfo(OSRF_LOG_MARK, "Running onExit handler for app %s", itr->current); + app->onExit(); + } + } +} + + int osrfAppRegisterMethod( char* appName, char* methodName, char* symbolName, char* notes, int argc, int options ) { diff --git a/OpenSRF/src/libstack/osrf_application.h b/OpenSRF/src/libstack/osrf_application.h index 10f92ed7ae..0980a81606 100644 --- a/OpenSRF/src/libstack/osrf_application.h +++ b/OpenSRF/src/libstack/osrf_application.h @@ -79,6 +79,7 @@ struct _osrfApplicationStruct { void* handle; /* the lib handle */ osrfHash* methods; + void (*onExit) (void); }; typedef struct _osrfApplicationStruct osrfApplication; @@ -226,5 +227,7 @@ int osrfAppEcho( osrfMethodContext* ctx ); /** * Tells the backend process to run its child init function */ int osrfAppRunChildInit(char* appname); +void osrfAppSetOnExit(osrfApplication* app, char* appName); +void osrfAppRunExitCode(); diff --git a/OpenSRF/src/libstack/osrf_prefork.c b/OpenSRF/src/libstack/osrf_prefork.c index f7bdb4c4f6..7d48d829ed 100644 --- a/OpenSRF/src/libstack/osrf_prefork.c +++ b/OpenSRF/src/libstack/osrf_prefork.c @@ -126,6 +126,13 @@ int prefork_child_init_hook(prefork_child* child) { osrfLogDebug( OSRF_LOG_MARK, "Child init hook for child %d", child->pid); char* resc = va_list_to_string("%s_drone",child->appname); + /* if we're a source-client, tell the logger now that we're a new process*/ + char* isclient = osrfConfigGetValue(NULL, "/client"); + if( isclient && !strcasecmp(isclient,"true") ) + osrfLogSetIsClient(1); + free(isclient); + + /* we want to remove traces of our parents socket connection * so we can have our own */ osrfSystemIgnoreTransportClient(); @@ -161,7 +168,7 @@ void prefork_child_process_request(prefork_child* child, char* data) { osrfLogError( OSRF_LOG_MARK, "Unable to bootstrap client in prefork_child_process_request()"); sleep(1); - exit(1); + osrf_prefork_child_exit(child); } } @@ -306,15 +313,19 @@ prefork_child* launch_child( prefork_simple* forker ) { if( prefork_child_init_hook(child) == -1 ) { osrfLogError(OSRF_LOG_MARK, "Forker child going away because we could not connect to OpenSRF..."); - exit(1); + osrf_prefork_child_exit(child); } prefork_child_wait( child ); - exit(0); /* just to be sure */ + osrf_prefork_child_exit(child); /* just to be sure */ } return NULL; } +void osrf_prefork_child_exit(prefork_child* child) { + osrfAppRunExitCode(); + exit(0); +} void prefork_launch_children( prefork_simple* forker ) { if(!forker) return; @@ -562,6 +573,11 @@ void prefork_child_wait( prefork_child* child ) { if( errno == EAGAIN ) n = 0; + if( errno == EPIPE ) { + osrfLogWarning(OSRF_LOG_MARK, "C child attempted read on broken pipe, exiting..."); + break; + } + if( n < 0 ) { osrfLogWarning( OSRF_LOG_MARK, "Prefork child read returned error with errno %d", errno ); break; @@ -581,7 +597,7 @@ void prefork_child_wait( prefork_child* child ) { osrfLogDebug( OSRF_LOG_MARK, "Child with max-requests=%d, num-served=%d exiting...[%d]", child->max_requests, i, getpid() ); - exit(0); + osrf_prefork_child_exit(child); /* just to be sure */ } diff --git a/OpenSRF/src/libstack/osrf_prefork.h b/OpenSRF/src/libstack/osrf_prefork.h index 28df9dfbda..9515445d64 100644 --- a/OpenSRF/src/libstack/osrf_prefork.h +++ b/OpenSRF/src/libstack/osrf_prefork.h @@ -93,4 +93,4 @@ int prefork_child_free( prefork_child* ); void osrf_prefork_register_routers( char* appname ); - +void osrf_prefork_child_exit( prefork_child* ); diff --git a/OpenSRF/src/libstack/osrf_stack.c b/OpenSRF/src/libstack/osrf_stack.c index c3273520a4..528abd0ff5 100644 --- a/OpenSRF/src/libstack/osrf_stack.c +++ b/OpenSRF/src/libstack/osrf_stack.c @@ -38,6 +38,8 @@ osrfAppSession* osrf_stack_transport_handler( transport_message* msg, char* my_s if(!msg) return NULL; + osrfLogSetXid(msg->osrf_xid); + osrfLogDebug( OSRF_LOG_MARK, "Transport handler received new message \nfrom %s " "to %s with body \n\n%s\n", msg->sender, msg->recipient, msg->body ); diff --git a/OpenSRF/src/libstack/osrf_system.c b/OpenSRF/src/libstack/osrf_system.c index 2c9ac6025a..3f24038362 100644 --- a/OpenSRF/src/libstack/osrf_system.c +++ b/OpenSRF/src/libstack/osrf_system.c @@ -169,6 +169,11 @@ int osrf_system_bootstrap_client_resc( char* config_file, char* contextnode, cha char* domain = strdup(osrfStringArrayGetString( arr, 0 )); /* just the first for now */ osrfStringArrayFree(arr); + /* if we're a source-client, tell the logger */ + char* isclient = osrfConfigGetValue(NULL, "/client"); + if( isclient && !strcasecmp(isclient,"true") ) + osrfLogSetIsClient(1); + free(isclient); int llevel = 0; int iport = 0; diff --git a/OpenSRF/src/libtransport/transport_message.c b/OpenSRF/src/libtransport/transport_message.c index a6e75148f8..f0e63afbd4 100644 --- a/OpenSRF/src/libtransport/transport_message.c +++ b/OpenSRF/src/libtransport/transport_message.c @@ -54,6 +54,12 @@ transport_message* new_message_from_xml( const char* msg_xml ) { xmlChar* router_to = xmlGetProp( root, BAD_CAST "router_to" ); xmlChar* router_class= xmlGetProp( root, BAD_CAST "router_class" ); xmlChar* broadcast = xmlGetProp( root, BAD_CAST "broadcast" ); + xmlChar* osrf_xid = xmlGetProp( root, BAD_CAST "osrf_xid" ); + + if( osrf_xid ) { + message_set_osrf_xid( new_msg, (char*) osrf_xid); + xmlFree(osrf_xid); + } if( router_from ) { new_msg->sender = strdup((char*)router_from); @@ -122,50 +128,19 @@ transport_message* new_message_from_xml( const char* msg_xml ) { if( new_msg->body == NULL ) new_msg->body = strdup(""); - int bufsize; - xmlChar* xmlbuf; - char* encoded_body; - - xmlDocDumpFormatMemory( msg_doc, &xmlbuf, &bufsize, 0 ); - encoded_body = strdup( (char*) xmlbuf ); - - if( encoded_body == NULL ) - osrfLogError(OSRF_LOG_MARK, "message_to_xml(): Out of Memory"); - - xmlFree(xmlbuf); - xmlFreeDoc(msg_doc); - xmlCleanupParser(); - - /*** remove the XML declaration */ - int len = strlen(encoded_body); - char tmp[len]; - memset( tmp, 0, len ); - int i; - int found_at = 0; - - /* when we reach the first >, take everything after it */ - for( i = 0; i!= len; i++ ) { - if( encoded_body[i] == 62) { /* ascii > */ - - /* found_at holds the starting index of the rest of the doc*/ - found_at = i + 1; - break; - } - } + new_msg->msg_xml = xmlDocToString(msg_doc, 0); + xmlFreeDoc(msg_doc); + xmlCleanupParser(); - if( found_at ) { - /* move the shortened doc into the tmp buffer */ - strncpy( tmp, encoded_body + found_at, len - found_at ); - /* move the tmp buffer back into the allocated space */ - memset( encoded_body, 0, len ); - strcpy( encoded_body, tmp ); - } - - new_msg->msg_xml = encoded_body; return new_msg; - } +void message_set_osrf_xid( transport_message* msg, char* osrf_xid ) { + if(!msg) return; + if( osrf_xid ) + msg->osrf_xid = strdup(osrf_xid); + else msg->osrf_xid = strdup(""); +} void message_set_router_info( transport_message* msg, char* router_from, char* router_to, char* router_class, char* router_command, int broadcast_enabled ) { @@ -224,6 +199,7 @@ int message_free( transport_message* msg ){ free(msg->router_to); free(msg->router_class); free(msg->router_command); + free(msg->osrf_xid); if( msg->error_type != NULL ) free(msg->error_type); if( msg->msg_xml != NULL ) free(msg->msg_xml); free(msg); @@ -274,6 +250,7 @@ char* message_to_xml( const transport_message* msg ) { xmlNewProp( message_node, BAD_CAST "router_to", BAD_CAST msg->router_to ); xmlNewProp( message_node, BAD_CAST "router_class", BAD_CAST msg->router_class ); xmlNewProp( message_node, BAD_CAST "router_command", BAD_CAST msg->router_command ); + xmlNewProp( message_node, BAD_CAST "osrf_xid", BAD_CAST msg->osrf_xid ); if( msg->broadcast ) xmlNewProp( message_node, BAD_CAST "broadcast", BAD_CAST "1" ); diff --git a/OpenSRF/src/libtransport/transport_message.h b/OpenSRF/src/libtransport/transport_message.h index 5dbd631ae2..4e94e24361 100644 --- a/OpenSRF/src/libtransport/transport_message.h +++ b/OpenSRF/src/libtransport/transport_message.h @@ -7,6 +7,7 @@ #include #include "opensrf/utils.h" +#include "opensrf/xml_utils.h" #include "opensrf/log.h" #ifndef TRANSPORT_MESSAGE_H @@ -27,6 +28,7 @@ struct transport_message_struct { char* router_to; char* router_class; char* router_command; + char* osrf_xid; int is_error; char* error_type; int error_code; @@ -49,6 +51,8 @@ transport_message* new_message_from_xml( const char* msg_xml ); void message_set_router_info( transport_message* msg, char* router_from, char* router_to, char* router_class, char* router_command, int broadcast_enabled ); +void message_set_osrf_xid( transport_message* msg, char* osrf_xid ); + // --------------------------------------------------------------------------------- // Formats the Jabber message as XML for encoding. // Returns NULL on error diff --git a/OpenSRF/src/libtransport/transport_session.c b/OpenSRF/src/libtransport/transport_session.c index 084de98198..43bdcbc984 100644 --- a/OpenSRF/src/libtransport/transport_session.c +++ b/OpenSRF/src/libtransport/transport_session.c @@ -30,6 +30,7 @@ transport_session* init_transport( char* server, /* for OpenSRF extensions */ session->router_to_buffer = buffer_init( JABBER_JID_BUFSIZE ); session->router_from_buffer = buffer_init( JABBER_JID_BUFSIZE ); + session->osrf_xid_buffer = buffer_init( JABBER_JID_BUFSIZE ); session->router_class_buffer = buffer_init( JABBER_JID_BUFSIZE ); session->router_command_buffer = buffer_init( JABBER_JID_BUFSIZE ); @@ -97,6 +98,7 @@ int session_free( transport_session* session ) { buffer_free(session->message_error_type); buffer_free(session->router_to_buffer); buffer_free(session->router_from_buffer); + buffer_free(session->osrf_xid_buffer); buffer_free(session->router_class_buffer); buffer_free(session->router_command_buffer); buffer_free(session->session_id); @@ -331,6 +333,7 @@ void startElementHandler( buffer_add( ses->from_buffer, get_xml_attr( atts, "from" ) ); buffer_add( ses->recipient_buffer, get_xml_attr( atts, "to" ) ); buffer_add( ses->router_from_buffer, get_xml_attr( atts, "router_from" ) ); + buffer_add( ses->osrf_xid_buffer, get_xml_attr( atts, "osrf_xid" ) ); buffer_add( ses->router_to_buffer, get_xml_attr( atts, "router_to" ) ); buffer_add( ses->router_class_buffer, get_xml_attr( atts, "router_class" ) ); buffer_add( ses->router_command_buffer, get_xml_attr( atts, "router_command" ) ); @@ -467,6 +470,8 @@ void endElementHandler( void *session, const xmlChar *name) { ses->router_command_buffer->buf, ses->router_broadcast ); + message_set_osrf_xid( msg, ses->osrf_xid_buffer->buf ); + if( ses->message_error_type->n_used > 0 ) { set_msg_error( msg, ses->message_error_type->buf, ses->message_error_code ); } @@ -539,6 +544,7 @@ int reset_session_buffers( transport_session* ses ) { buffer_reset( ses->from_buffer ); buffer_reset( ses->recipient_buffer ); buffer_reset( ses->router_from_buffer ); + buffer_reset( ses->osrf_xid_buffer ); buffer_reset( ses->router_to_buffer ); buffer_reset( ses->router_class_buffer ); buffer_reset( ses->router_command_buffer ); diff --git a/OpenSRF/src/libtransport/transport_session.h b/OpenSRF/src/libtransport/transport_session.h index fa13704a22..ba02e5bfa1 100644 --- a/OpenSRF/src/libtransport/transport_session.h +++ b/OpenSRF/src/libtransport/transport_session.h @@ -158,6 +158,7 @@ struct transport_session_struct { growing_buffer* router_from_buffer; growing_buffer* router_class_buffer; growing_buffer* router_command_buffer; + growing_buffer* osrf_xid_buffer; int router_broadcast; /* this can be anything. It will show up in the