LP#1268619: websocket translator: only cache connected recipients; use request_rec...
authorBill Erickson <berick@esilibrary.com>
Thu, 29 Nov 2012 22:15:39 +0000 (17:15 -0500)
committerBill Erickson <berick@esilibrary.com>
Sun, 4 May 2014 20:10:34 +0000 (16:10 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
src/gateway/osrf_websocket_translator.c

index 898837e..2cb66c6 100644 (file)
@@ -72,7 +72,7 @@
 typedef struct _osrfWebsocketTranslator {
     const WebSocketServer *server;
     apr_pool_t *main_pool; // standalone per-process pool
-    apr_pool_t *session_pool; // child of trans->main_pool; per-session TODO: use apache connection pool instead
+    apr_pool_t *session_pool; // child of trans->main_pool; per-session
     apr_hash_t *session_cache; 
     apr_thread_t *responder_thread;
     int client_connected;
@@ -94,13 +94,19 @@ void* APR_THREAD_FUNC osrf_responder_thread_main(apr_thread_t *thread, void *dat
 
     transport_message *tmsg;
     jsonObject *msg_wrapper;
+    osrfList *msg_list;
+    osrfMessage *one_msg;
     char *msg_string;
+    int i;
 
     while (1) {
+        // TODO: RELEASE THREAD MUTEX
 
         tmsg = client_recv(osrf_handle, -1);
 
         if (!tmsg) continue; // early exit on interrupt
+
+        // TODO: THREAD MUTEX LOCK STARTS
         
         // discard responses received after client disconnect
         if (!trans->client_connected) {
@@ -111,7 +117,6 @@ void* APR_THREAD_FUNC osrf_responder_thread_main(apr_thread_t *thread, void *dat
             continue; 
         }
 
-
         osrfLogDebug(OSRF_LOG_MARK, 
             "WS received opensrf response for thread=%s, xid=%s", 
                 tmsg->thread, tmsg->osrf_xid);
@@ -136,22 +141,38 @@ void* APR_THREAD_FUNC osrf_responder_thread_main(apr_thread_t *thread, void *dat
         trans->server->send(trans->server, MESSAGE_TYPE_TEXT, 
             (unsigned char*) msg_string, strlen(msg_string));
 
-        // capture the true message sender
-        // TODO: this will grow to add one entry per client session.  
-        // need to ensure that connected-sessions don't last /too/ long or create 
-        // a last-touched timeout mechanism to periodically remove old  entries
-        if (!apr_hash_get(trans->session_cache, tmsg->thread, APR_HASH_KEY_STRING)) {
+        msg_list = osrfMessageDeserialize(tmsg->body, NULL);
+        for (i = 0; i < msg_list->size; i++) {
+            one_msg = OSRF_LIST_GET_INDEX(msg_list, i);
 
-            osrfLogDebug(OSRF_LOG_MARK, 
-                "WS caching sender thread=%s, sender=%s", tmsg->thread, tmsg->sender);
+            /*  if our client just successfully connected to an opensrf service,
+                cache the sender so that future calls on this thread will use
+                the correct recipient.  
+                TODO: this cache will grow to add one entry per client session.  
+                Even when entries are removed, they are not cleaned up until the
+                session_pool is destroyed.  We need to ensure that client sessions
+                don't last too long and/or create a last-touched timeout mechanism 
+                to periodically remove old entries. */
+            if (one_msg && one_msg->m_type == STATUS && 
+                    one_msg->status_code == OSRF_STATUS_OK) {
+
+                if (!apr_hash_get(trans->session_cache, 
+                        tmsg->thread, APR_HASH_KEY_STRING)) {
+
+                    osrfLogDebug(OSRF_LOG_MARK, 
+                        "WS caching sender thread=%s, sender=%s", 
+                        tmsg->thread, tmsg->sender);
 
-            apr_hash_set(trans->session_cache, 
-                apr_pstrdup(trans->session_pool, tmsg->thread),
-                APR_HASH_KEY_STRING, 
-                apr_pstrdup(trans->session_pool, tmsg->sender));
+                    apr_hash_set(trans->session_cache, 
+                        apr_pstrdup(trans->session_pool, tmsg->thread),
+                        APR_HASH_KEY_STRING, 
+                        apr_pstrdup(trans->session_pool, tmsg->sender));
+                }
+            }
         }
 
         free(msg_string);
+        osrfListFree(msg_list);
         jsonObjectFree(msg_wrapper);
         message_free(tmsg);                                                         
     }
@@ -242,7 +263,8 @@ void* CALLBACK on_connect_handler(const WebSocketServer *server) {
 
     // create a standalone pool for the session cache values, which will be
     // destroyed on client disconnect.
-    if (apr_pool_create(&pool, trans->main_pool) != APR_SUCCESS) {
+    //if (apr_pool_create(&pool, trans->main_pool) != APR_SUCCESS) {
+    if (apr_pool_create(&pool, r->pool) != APR_SUCCESS) {
         osrfLogError(OSRF_LOG_MARK, "WS Unable to create apr_pool");
         return NULL;
     }
@@ -480,7 +502,14 @@ void CALLBACK on_disconnect_handler(
     trans->client_connected = 0;
 
     apr_hash_clear(trans->session_cache);
+
+    /*
+    It's not necessary to destroy our session_pool, since
+    it's a child of the apache request_rec pool, which is 
+    destroyed after client disconnect.
     apr_pool_destroy(trans->session_pool);
+    */
+    
     trans->session_pool = NULL;
     trans->session_cache = NULL;