From 98e25aee3515ef008484add1f168f97999f7b598 Mon Sep 17 00:00:00 2001 From: scottmk Date: Tue, 10 Aug 2010 02:13:39 +0000 Subject: [PATCH] Provide a way for a service to set the effective buffer size for a specified method. Non-atomic methods accumulate RESULT messages into a buffer, from which they are flushed when the buffer is about to overflow, or when the closing STATUS message is issued. The new osrfMethodSetBufferSize() function allows the service to favor large buffers (for greater throughput) or small ones (for a lower latency for the first response). Since the buffersize is not an absolute limit, the effective buffer size may be set to zero, in which case each RESULT message will be packaged and sent in a separate XMPP message as soon as it is ready. Changing the buffer size has no effect on an atomic method, nor on a method that returns only one RESULT message. M include/opensrf/osrf_application.h M src/libopensrf/osrf_application.c git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1993 9efc2488-bf62-4759-914b-345cdb29e865 --- include/opensrf/osrf_application.h | 3 +++ src/libopensrf/osrf_application.c | 41 ++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/include/opensrf/osrf_application.h b/include/opensrf/osrf_application.h index aace99b..d7560be 100644 --- a/include/opensrf/osrf_application.h +++ b/include/opensrf/osrf_application.h @@ -124,6 +124,7 @@ typedef struct { //char* paramNotes; /**< Description of the params expected for this method. */ int options; /**< Bit switches setting various options for this method. */ void* userData; /**< Opaque pointer to application-specific data. */ + size_t bufsize; /**< How big a buffer to use for non-atomic methods */ /* int sysmethod; @@ -149,6 +150,8 @@ int osrfAppRegisterMethod( const char* appName, const char* methodName, int osrfAppRegisterExtendedMethod( const char* appName, const char* methodName, const char* symbolName, const char* notes, int argc, int options, void* ); +int osrfMethodSetBufferSize( const char* appName, const char* methodName, size_t bufsize ); + osrfMethod* _osrfAppFindMethod( const char* appName, const char* methodName ); int osrfAppRunMethod( const char* appName, const char* methodName, diff --git a/src/libopensrf/osrf_application.c b/src/libopensrf/osrf_application.c index d856971..b75d2bb 100644 --- a/src/libopensrf/osrf_application.c +++ b/src/libopensrf/osrf_application.c @@ -86,6 +86,9 @@ #define OSRF_METHOD_ATOMIC 4 /*@}*/ +/** + @brief Default size of output buffer. +*/ #define OSRF_MSG_BUFFER_SIZE 10240 /** @@ -307,7 +310,7 @@ int osrfAppRegisterMethod( const char* appName, const char* methodName, } /** - @brief Register a method for a specified application. + @brief Register an extended method for a specified application. @param appName Name of the application that implements the method. @param methodName The fully qualified name of the method. @@ -418,9 +421,43 @@ static osrfMethod* build_method( const char* methodName, const char* symbolName, if(user_data) method->userData = user_data; + method->bufsize = OSRF_MSG_BUFFER_SIZE; return method; } +/** + @brief Set the effective output buffer size for a given method. + @param appName Name of the application. + @param methodName Name of the method. + @param bufsize Desired size of the output buffer, in bytes. + @return Zero if successful, or -1 if the specified method cannot be found. + + A smaller buffer size may result in a lower latency for the first response, since we don't + wait for as many messages to accumulate before flushing the output buffer. On the other + hand a larger buffer size may result in higher throughput due to lower network overhead. + + Since the buffer size is not an absolute limit, it may be set to zero, in which case each + output transport message will contain no more than one RESULT message. + + This function has no effect on atomic methods, because all responses are sent in a single + message anyway. Likewise it has no effect on a method that returns only a single response. +*/ +int osrfMethodSetBufferSize( const char* appName, const char* methodName, size_t bufsize ) { + osrfMethod* method = _osrfAppFindMethod( appName, methodName ); + if( method ) { + osrfLogInfo( OSRF_LOG_MARK, + "Setting outbuf buffer size to %lu for method %s of application %s", + (unsigned long) bufsize, methodName, appName ); + method->bufsize = bufsize; + return 0; + } else { + osrfLogWarning( OSRF_LOG_MARK, + "Unable to set outbuf buffer size to %lu for method %s of application %s", + (unsigned long) bufsize, methodName, appName ); + return -1; + } +} + /** @brief Register all of the system methods for this application. @param app Pointer to the application. @@ -715,7 +752,7 @@ static int _osrfAppRespond( osrfMethodContext* ctx, const jsonObject* data, int // If the new message would overflow the buffer, flush the output buffer first int len_so_far = buffer_length( ctx->session->outbuf ); - if( len_so_far && (strlen( json ) + len_so_far >= OSRF_MSG_BUFFER_SIZE - 3) ) { + if( len_so_far && (strlen( json ) + len_so_far + 3 >= ctx->method->bufsize )) { if( flush_responses( ctx->session, ctx->session->outbuf )) return -1; } -- 2.43.2