int MemCacheClient::Store( const char * aType, MemRequest * aItem, int aCount ) { if (aCount < 1) { mTrace.Trace(CLDEBUG, "Store: ignoring request for %d items", aCount); return 0; } // initialize and find all of the servers for these items int nItemCount = 0; for (int n = 0; n < aCount; ++n) { // ensure that the key doesn't have a space in it CR_ASSERT(NULL == strchr(aItem[n].mKey.data(), ' ')); aItem[n].mServer = FindServer(aItem[n].mKey, aItem[n].mService); if (aItem[n].mServer) { ++nItemCount; } else { aItem[n].mResult = MCERR_NOSERVER; } } if (nItemCount == 0) { mTrace.Trace(CLDEBUG, "Store: ignoring request for all %d items (no servers available)", aCount); return 0; } char szBuf[50]; int nResponses = 0; string_t sRequest; for (int n = 0; n < aCount; ++n) { if (!aItem[n].mServer) continue; // <command name> <key> <flags> <exptime> <bytes> [noreply]\r\n sRequest = aType; sRequest += ' '; sRequest += aItem[n].mKey; snprintf(szBuf, sizeof(szBuf), " %u %ld %u", aItem[n].mFlags, (long) aItem[n].mExpiry, (unsigned)aItem[n].mData.GetReadSize()); sRequest += szBuf; if (*aType == 'c') { // cas snprintf(szBuf, sizeof(szBuf), " %" PRIu64, aItem[n].mCas); sRequest += szBuf; } if (aItem[n].mResult == MCERR_NOREPLY) { sRequest += " noreply"; } sRequest += "\r\n"; // send the request. any socket error causes the server connection // to be dropped, so we return errors for all requests using that server. try { aItem[n].mServer->SendBytes( sRequest.data(), sRequest.length()); aItem[n].mServer->SendBytes( aItem[n].mData.GetReadBuffer(), aItem[n].mData.GetReadSize()); aItem[n].mServer->SendBytes("\r\n", 2); // done with these read bytes aItem[n].mData.CommitReadBytes( aItem[n].mData.GetReadSize()); // if no reply is required then move on to the next request if (aItem[n].mResult == MCERR_NOREPLY) { continue; } // handle this response HandleStoreResponse(aItem[n].mServer, aItem[n]); ++nResponses; } catch (const Socket::Exception & e) { mTrace.Trace(CLINFO, "Store: error '%s' at %s, marking requests as NOSERVER", e.mDetail, aItem[n].mServer->GetAddress()); for (int i = aCount - 1; i >= n; --i) { if (aItem[n].mServer != aItem[i].mServer) continue; aItem[i].mServer = NULL; aItem[i].mResult = MCERR_NOSERVER; } continue; } } return nResponses; }
int MemCacheClient::Store( const char * a_pszType, MemRequest * a_rgItem, int a_nCount ) { if (a_nCount < 1) return 0; // initialize and find all of the servers for these items for (int n = 0; n < a_nCount; ++n) { // ensure that the key doesn't have a space in it assert(NULL == strchr(a_rgItem[n].mKey.data(), ' ')); a_rgItem[n].mServer = FindServer(a_rgItem[n].mKey); if (!a_rgItem[n].mServer) { a_rgItem[n].mResult = MCERR_NOSERVER; } } char szBuf[50]; int nResponses = 0; string_t sRequest; for (int n = 0; n < a_nCount; ++n) { if (!a_rgItem[n].mServer) continue; // <command name> <key> <flags> <exptime> <bytes> [noreply]\r\n sRequest = a_pszType; sRequest += ' '; sRequest += a_rgItem[n].mKey; snprintf(szBuf, sizeof(szBuf), " %u %ld %u", a_rgItem[n].mFlags, (long) a_rgItem[n].mExpiry, a_rgItem[n].mData.GetReadSize()); sRequest += szBuf; if (*a_pszType == 'c') { // cas snprintf(szBuf, sizeof(szBuf), " " SPRINTF_UINT64, a_rgItem[n].mCas); sRequest += szBuf; } if (a_rgItem[n].mResult == MCERR_NOREPLY) { sRequest += " noreply"; } sRequest += "\r\n"; // send the request. any socket error causes the server connection // to be dropped, so we return errors for all requests using that server. try { a_rgItem[n].mServer->SendBytes( sRequest.data(), sRequest.length()); a_rgItem[n].mServer->SendBytes( a_rgItem[n].mData.GetReadBuffer(), a_rgItem[n].mData.GetReadSize()); a_rgItem[n].mServer->SendBytes("\r\n", 2); // done with these read bytes a_rgItem[n].mData.CommitReadBytes( a_rgItem[n].mData.GetReadSize()); // if no reply is required then move on to the next request if (a_rgItem[n].mResult == MCERR_NOREPLY) { continue; } // handle this response HandleStoreResponse(a_rgItem[n].mServer, a_rgItem[n]); ++nResponses; } catch (const ServerSocket::Exception &) { for (int i = a_nCount - 1; i >= n; --i) { if (a_rgItem[n].mServer != a_rgItem[i].mServer) continue; a_rgItem[i].mServer = NULL; a_rgItem[i].mResult = MCERR_NOSERVER; } continue; } } return nResponses; }