fix core while streaming and getting EPIPE.

but it seems like firefox and firefox only
has a bug it in when streaming json
with high start values like &s=20000&q=type:json
This commit is contained in:
Matt Wells
2015-01-28 19:53:38 -08:00
parent 2501292516
commit f76f0c77d8
4 changed files with 48 additions and 13 deletions

@ -106,6 +106,7 @@ Msg40::Msg40() {
m_lastChunk = false;
m_didSummarySkip = false;
m_omitCount = 0;
m_printCount = 0;
//m_numGigabitInfos = 0;
}
@ -1961,8 +1962,12 @@ bool Msg40::gotSummary ( ) {
// do not print it if before the &s=X start position though
if ( m_si && m_numDisplayed <= m_si->m_firstResultNum ){
log("msg40: hiding #%"INT32" (%"UINT32")(d=%"INT64")",
m_printi,mr->m_contentHash32,mr->m_docId);
if ( m_printCount == 0 )
log("msg40: hiding #%"INT32" (%"UINT32")"
"(d=%"INT64")",
m_printi,mr->m_contentHash32,mr->m_docId);
m_printCount++;
if ( m_printCount == 100 ) m_printCount = 0;
m20->reset();
continue;
}
@ -2063,6 +2068,8 @@ bool Msg40::gotSummary ( ) {
m_printedTail = true;
printSearchResultsTail ( st );
if ( m_sendsIn < m_sendsOut ) { char *xx=NULL;*xx=0; }
if ( g_conf.m_logDebugTcp )
log("tcp: disabling streamingMode now");
// this will be our final send
st->m_socket->m_streamingMode = false;
}
@ -5657,9 +5664,12 @@ bool Msg40::printSearchResult9 ( int32_t ix , int32_t *numPrintedSoFar ,
// i guess we can print "Next 10" link
m_moreToCome = true;
// hide if above limit
log(LOG_INFO,"msg40: hiding above docsWanted "
"#%"INT32" (%"UINT32")(d=%"INT64")",
m_printi,mr->m_contentHash32,mr->m_docId);
if ( m_printCount == 0 )
log(LOG_INFO,"msg40: hiding above docsWanted "
"#%"INT32" (%"UINT32")(d=%"INT64")",
m_printi,mr->m_contentHash32,mr->m_docId);
m_printCount++;
if ( m_printCount == 100 ) m_printCount = 0;
// do not exceed what the user asked for
return true;
}
@ -5678,8 +5688,8 @@ bool Msg40::printSearchResult9 ( int32_t ix , int32_t *numPrintedSoFar ,
}
log(LOG_INFO,"msg40: printing #%"INT32" (%"UINT32")(d=%"INT64")",
m_printi,mr->m_contentHash32,mr->m_docId);
// log(LOG_INFO,"msg40: printing #%"INT32" (%"UINT32")(d=%"INT64")",
// m_printi,mr->m_contentHash32,mr->m_docId);
// count it
m_numPrinted++;

@ -335,6 +335,7 @@ class Msg40 {
int32_t m_tasksRemaining;
int32_t m_printCount;
// buffer we deserialize from, allocated by Msg17, but we free it
char *m_buf;

@ -194,6 +194,15 @@ bool sendReply ( State0 *st , char *reply ) {
}
*/
// if we had a broken pipe from the browser while sending
// them the search results, then we end up closing the socket fd
// in TcpServer::sendChunk() > sendMsg() > destroySocket()
if ( s->m_numDestroys ) {
log("results: not sending back error on destroyed socket "
"sd=%"INT32"",s->m_sd);
return true;
}
int32_t status = 500;
if (savedErr == ETOOMANYOPERANDS ||
savedErr == EBADREQUEST ||
@ -3137,6 +3146,12 @@ bool printSearchResultsTail ( State0 *st ) {
msg40->printFacetTables ( sb );
if ( st->m_header ) sb->safePrintf("}\n");
//////////////////////
// for some reason if we take too long to write out this
// tail we get a SIGPIPE on a firefox browser.
//////////////////////
// all done for json
return true;
}

@ -1393,8 +1393,8 @@ int32_t TcpServer::readSocket ( TcpSocket *s ) {
// }
if ( g_conf.m_logDebugTcp )
logf(LOG_DEBUG,"tcp: readSocket: reading on sd=%"INT32"",
(int32_t)s->m_sd);
logf(LOG_DEBUG,"tcp: readSocket: reading on sd=%"INT32"",
(int32_t)s->m_sd);
// do the read
int n;
@ -1735,10 +1735,14 @@ int32_t TcpServer::writeSocket ( TcpSocket *s ) {
}
if ( toSend <= 0 ) return 0;
// debug msg
if ( g_conf.m_logDebugTcp )
logf(LOG_DEBUG,"tcp: writeSocket: writing %"INT32" bytes on %"INT32"",
toSend,(int32_t)s->m_sd);
logf(LOG_DEBUG,"tcp: writeSocket: writing %"INT32" bytes "
"(of %"INT32" bytes total) "
"on %"INT32"",
toSend,toSend,(int32_t)s->m_sd);
retry10:
@ -1764,9 +1768,14 @@ int32_t TcpServer::writeSocket ( TcpSocket *s ) {
// a core... so check g_errno here.
// actually for m_useSSL it does not set errno...
if ( ! g_errno && m_useSSL ) g_errno = ESSLERROR;
if ( g_errno != EAGAIN ) return -1;
g_errno = 0;
// debug msg
if ( g_errno != EAGAIN ) {
//if ( g_conf.m_logDebugTcp )
log("tcp: ::send returned %"INT32" err=%s"
,n,mstrerror(g_errno));
return -1;
}
g_errno = 0;
//log("........... TcpServer write blocked on %i\n",
//s->m_sd);
return 0;