// . this is called // . destroys the UdpSlot if false is returned static void handleRequest20(UdpSlot *slot, int32_t netnice) { // . check g_errno // . before, we were not sending a reply back here and we continued // to process the request, even though it was empty. the slot // had a NULL m_readBuf because it could not alloc mem for the read // buf i'm assuming. and the slot was saved in a line below here... // state20->m_msg22.m_parent = slot; if ( g_errno ) { log(LOG_WARN, "net: Msg20 handler got error: %s.",mstrerror(g_errno)); log(LOG_ERROR,"%s:%s:%d: call sendErrorReply.", __FILE__, __func__, __LINE__); g_udpServer.sendErrorReply ( slot , g_errno ); return; } // ensure request is big enough if ( slot->m_readBufSize < (int32_t)sizeof(Msg20Request) ) { log(LOG_ERROR,"%s:%s:%d: call sendErrorReply. Bad request size", __FILE__, __func__, __LINE__); g_udpServer.sendErrorReply ( slot , EBADREQUESTSIZE ); return; } // parse the request Msg20Request *req = (Msg20Request *)slot->m_readBuf; // . turn the string offsets into ptrs in the request // . this is "destructive" on "request" int32_t nb = req->deserialize(); // sanity check if ( nb != slot->m_readBufSize ) { g_process.shutdownAbort(true); } // sanity check, the size include the \0 if ( req->m_collnum < 0 ) { log(LOG_WARN, "query: Got empty collection in msg20 handler. FIX! " "from ip=%s port=%i",iptoa(slot->getIp()),(int)slot->getPort()); log(LOG_ERROR,"%s:%s:%d: call sendErrorReply.", __FILE__, __func__, __LINE__); g_udpServer.sendErrorReply ( slot , ENOTFOUND ); return; } int64_t cache_key = req->makeCacheKey(); const void *cached_summary; size_t cached_summary_len; if(g_stable_summary_cache.lookup(cache_key, &cached_summary, &cached_summary_len) || g_unstable_summary_cache.lookup(cache_key, &cached_summary, &cached_summary_len)) { log(LOG_DEBUG, "query: Summary cache hit"); sendCachedReply(req,cached_summary,cached_summary_len,slot); return; } else log(LOG_DEBUG, "query: Summary cache miss"); // if it's not stored locally that's an error if ( req->m_docId >= 0 && ! Titledb::isLocal ( req->m_docId ) ) { log(LOG_WARN, "query: Got msg20 request for non-local docId %" PRId64, req->m_docId); log(LOG_ERROR,"%s:%s:%d: call sendErrorReply.", __FILE__, __func__, __LINE__); g_udpServer.sendErrorReply ( slot , ENOTLOCAL ); return; } // sanity if ( req->m_docId == 0 && ! req->ptr_ubuf ) { //g_process.shutdownAbort(true); } log( LOG_WARN, "query: Got msg20 request for docid of 0 and no url for " "collnum=%" PRId32" query %s",(int32_t)req->m_collnum,req->ptr_qbuf); log(LOG_ERROR,"%s:%s:%d: call sendErrorReply.", __FILE__, __func__, __LINE__); g_udpServer.sendErrorReply ( slot , ENOTFOUND ); return; } int64_t startTime = gettimeofdayInMilliseconds(); // alloc a new state to get the titlerec Msg20State *state; try { state = new Msg20State(slot,req); } catch(...) { g_errno = ENOMEM; log("query: msg20 new(%" PRId32"): %s", (int32_t)sizeof(XmlDoc), mstrerror(g_errno)); log(LOG_ERROR,"%s:%s:%d: call sendErrorReply. error=%s", __FILE__, __func__, __LINE__, mstrerror( g_errno )); g_udpServer.sendErrorReply ( slot, g_errno ); return; } mnew(state, sizeof(*state), "xd20"); // ok, let's use the new XmlDoc.cpp class now! state->m_xmldoc.setMsg20Request(req); // set the callback state->m_xmldoc.setCallback(state, gotReplyWrapperxd); // set set time state->m_xmldoc.m_setTime = startTime; state->m_xmldoc.m_cpuSummaryStartTime = 0; // . now as for the msg20 reply! // . TODO: move the parse state cache into just a cache of the // XmlDoc itself, and put that cache logic into XmlDoc.cpp so // it can be used more generally. Msg20Reply *reply = state->m_xmldoc.getMsg20Reply ( ); // this is just blocked if ( reply == (void *)-1 ) return; // got it? gotReplyWrapperxd (state); }
// . this is called // . destroys the UdpSlot if false is returned void handleRequest20 ( UdpSlot *slot , long netnice ) { // . check g_errno // . before, we were not sending a reply back here and we continued // to process the request, even though it was empty. the slot // had a NULL m_readBuf because it could not alloc mem for the read // buf i'm assuming. and the slot was saved in a line below here... // state20->m_msg22.m_parent = slot; if ( g_errno ) { log("net: Msg20 handler got error: %s.",mstrerror(g_errno)); g_udpServer.sendErrorReply ( slot , g_errno ); return; } // ensure request is big enough if ( slot->m_readBufSize < (long)sizeof(Msg20Request) ) { g_udpServer.sendErrorReply ( slot , EBADREQUESTSIZE ); return; } // parse the request Msg20Request *req = (Msg20Request *)slot->m_readBuf; // . turn the string offsets into ptrs in the request // . this is "destructive" on "request" long nb = req->deserialize(); // sanity check if ( nb != slot->m_readBufSize ) { char *xx = NULL; *xx = 0; } // sanity check, the size include the \0 if ( req->size_coll <= 1 || *req->ptr_coll == '\0' ) { log("query: Got empty collection in msg20 handler. FIX!"); char *xx =NULL; *xx = 0; } // if it's not stored locally that's an error if ( req->m_docId >= 0 && ! g_titledb.isLocal ( req->m_docId ) ) { log("query: Got msg20 request for non-local docId %lli", req->m_docId); g_udpServer.sendErrorReply ( slot , ENOTLOCAL ); return; } // sanity if ( req->m_docId == 0 && ! req->ptr_ubuf ) { char *xx=NULL;*xx=0; } long long startTime = gettimeofdayInMilliseconds(); // alloc a new state to get the titlerec XmlDoc *xd; try { xd = new (XmlDoc); } catch ( ... ) { g_errno = ENOMEM; log("query: msg20 new(%i): %s", sizeof(XmlDoc), mstrerror(g_errno)); g_udpServer.sendErrorReply ( slot, g_errno ); return; } mnew ( xd , sizeof(XmlDoc) , "xd20" ); // ok, let's use the new XmlDoc.cpp class now! xd->set20 ( req ); // encode slot xd->m_slot = slot; // set the callback xd->setCallback ( xd , gotReplyWrapperxd ); // set set time xd->m_setTime = startTime; xd->m_cpuSummaryStartTime = 0; // . now as for the msg20 reply! // . TODO: move the parse state cache into just a cache of the // XmlDoc itself, and put that cache logic into XmlDoc.cpp so // it can be used more generally. Msg20Reply *reply = xd->getMsg20Reply ( ); // this is just blocked if ( reply == (void *)-1 ) return; // got it? gotReplyWrapperxd ( xd ); }