📄 http_client.pc
字号:
/* * NAME: AppHttpClientProcessDoneThinking. * PURPOSE: After waiting the think period, either request the next * document, or select a new http server and start over. * PARAMETERS: node - pointer to the node which received the message. * clientPtr - pointer to the client's data structure * RETURN: none. */void AppHttpClientProcessDoneThinking(GlomoNode *node, GlomoAppHttpClient *clientPtr){ if (clientPtr->documentsOnCurrentServer > 0) { long primaryRequestLength; clientPtr->documentsOnCurrentServer--; clientPtr->stats.pageItems = AppHttpClientDetermineItemCount(clientPtr);#ifdef DEBUG printf(" There are %d items on this NEXT page.\n", clientPtr->stats.pageItems);#endif clientPtr->stats.pageItems--; primaryRequestLength = AppHttpClientDeterminePrimaryRequestLength(clientPtr);#ifdef DEBUG printf(" Primary request length = %d\n", primaryRequestLength);#endif AppHttpClientSendPrimaryRequest(node, clientPtr, primaryRequestLength); } else { NODE_ADDR serverAddr = AppHttpClientSelectNewServer(clientPtr); clientPtr->documentsOnCurrentServer = AppHttpClientConsecutiveDocumentRetrievals(clientPtr);#ifdef DEBUG printf(" Request %d documents on server address %ld\n", clientPtr->documentsOnCurrentServer, serverAddr);#endif if (serverAddr != clientPtr->remoteAddr) { clocktype sum; sum = clientPtr->avgSessionLength * clientPtr->numSessions; clientPtr->sessionFinish = simclock(); sum += (clientPtr->sessionFinish - clientPtr->sessionStart); clientPtr->numSessions++; clientPtr->avgSessionLength = sum / clientPtr->numSessions; AppTcpSendData(node, TRANSPORT_PROTOCOL_TCP, clientPtr->connectionId, "c", 1); AppTcpCloseConnection(node, TRANSPORT_PROTOCOL_TCP, clientPtr->connectionId); AppTcpOpenConnectionWithPriority(node, TRANSPORT_PROTOCOL_TCP, APP_HTTP_CLIENT, serverAddr, (short)APP_HTTP_SERVER, clientPtr->uniqueId, 0, NON_REAL_TIME);#ifdef DEBUG printf(" DONE with this server.\n");#endif } else { long primaryRequestLength; clientPtr->documentsOnCurrentServer = AppHttpClientConsecutiveDocumentRetrievals(clientPtr); clientPtr->documentsOnCurrentServer--; clientPtr->stats.pageItems = AppHttpClientDetermineItemCount(clientPtr);#ifdef DEBUG printf(" There are %d items on this page.\n", clientPtr->stats.pageItems);#endif clientPtr->stats.pageItems--; primaryRequestLength = AppHttpClientDeterminePrimaryRequestLength(clientPtr);#ifdef DEBUG printf(" Primary request length = %d\n", primaryRequestLength);#endif AppHttpClientSendPrimaryRequest(node, clientPtr, primaryRequestLength); } clientPtr->remoteAddr = serverAddr; }}/* * NAME: AppHttpClientProcessWaitReplyTimer. * PURPOSE: Do nothing if the packet reception was successful, * otherwise, check if the server has not responded within * the allotted threshhold. If not, request the next * document. If so, reset the timer. * PARAMETERS: node - pointer to the node which received the message. * clientPtr - pointer to the client's data structure * RETURN: none. */void AppHttpClientProcessWaitReplyTimer(GlomoNode *node, GlomoAppHttpClient *clientPtr){ if (clientPtr->state == IDLE) return; else if ((clientPtr->state == WAIT_PRIMARY_RESPONSE) || (clientPtr->state == WAIT_SECONDARY_RESPONSE)) { if (clientPtr->lastReceiveTime < (simclock() - clientPtr->threshhold)) { clocktype sum; sum = clientPtr->avgSessionLength * clientPtr->numSessions; clientPtr->sessionFinish = simclock(); sum += (clientPtr->sessionFinish - clientPtr->sessionStart); clientPtr->numSessions++; clientPtr->avgSessionLength = sum / clientPtr->numSessions; clientPtr->sessionStart = simclock(); AppHttpClientProcessDoneThinking(node, clientPtr); } else if (clientPtr->state == WAIT_PRIMARY_RESPONSE) { AppHttpClientSendWaitReplyTimer(node, clientPtr, WAIT_PRIMARY_REPLY_TIMER); } else if (clientPtr->state == WAIT_SECONDARY_RESPONSE) { AppHttpClientSendWaitReplyTimer(node, clientPtr, WAIT_SECONDARY_REPLY_TIMER); } else assert(FALSE); } else assert(FALSE);}/* * NAME: AppHttpClientProcessReplyPacket. * PURPOSE: Process a Reply Packet from the server. This packet is marked * as the last one corresponding to a specific request. * PARAMETERS: node - pointer to the node which received the message. * clientPtr - pointer to the client's data structure * RETURN: none. */void AppHttpClientProcessReplyPacket(GlomoNode *node, GlomoAppHttpClient *clientPtr){ if (clientPtr->stats.pageItems > 0) { long secondaryRequestLength = AppHttpClientDetermineSecondaryRequestLength(clientPtr);#ifdef DEBUG printf(" Secondary Request Length %d\n", secondaryRequestLength);#endif AppHttpClientSendSecondaryRequest(node, clientPtr, secondaryRequestLength); clientPtr->stats.pageItems--; } else { double thinkTimeDouble = AppHttpClientDetermineThinkTime(clientPtr); clocktype thinkTime = (thinkTimeDouble * SECOND); char buf[80]; clientPtr->numPages++; if (thinkTime > clientPtr->threshhold) thinkTime = (thinkTime % clientPtr->threshhold); ctoa(thinkTime, buf);#ifdef DEBUG printf(" Thinking for %s.......%f\n", buf, thinkTimeDouble);#endif clientPtr->state = IDLE; AppHttpClientSendThinkTimer(node, clientPtr, thinkTime); } }/* * NAME: AppHttpClientConsecutiveDocumentRetrievals. * PURPOSE: Return the number of consecutive document retrievals for the * current server. * PARAMETERS: clientPtr - pointer to the client's data structure * RETURN: the number of consecutive document retrievals. */long AppHttpClientConsecutiveDocumentRetrievals(GlomoAppHttpClient *clientPtr){ extern const DoubleDistElement *HttpConsecutiveDocsDistTable; extern const int HttpConsecutiveDocsDistLength; double u = pc_erand(clientPtr->seed); float value; int midpoint = DoubleDistFindIndex(HttpConsecutiveDocsDistTable, HttpConsecutiveDocsDistLength, u);#ifdef DEBUG printf(" u = %f\n", u); printf("AppHttpClientConsecutiveDocumentRetrievals(of %d) = %d\n", HttpConsecutiveDocsDistLength, midpoint);#endif if (midpoint < 0) value = HttpConsecutiveDocsDistTable[0].value; else value = DoubleDistEmpiricalIntegralInterpolate( HttpConsecutiveDocsDistTable[midpoint].cdf, HttpConsecutiveDocsDistTable[midpoint+1].cdf, HttpConsecutiveDocsDistTable[midpoint].value, HttpConsecutiveDocsDistTable[midpoint+1].value, u);#ifdef DEBUG printf(" midpoint = %d, value = %f\n", midpoint, value);#endif return value;}/* * NAME: AppHttpClientSelectNewServer. * PURPOSE: Return the address for the next selected server * PARAMETERS: clientPtr - pointer to the client's data structure * RETURN: the node address for the next server to communicate with. */NODE_ADDR AppHttpClientSelectNewServer(GlomoAppHttpClient *clientPtr){ long serverIndex; double tryCdf, u; // Get a Uniform[0,1] random variable u = pc_erand(clientPtr->seed); // Invert the CDF tryCdf = 0.0; serverIndex = 1; while (TRUE) { if (serverIndex > clientPtr->num_servers) { assert(FALSE); } tryCdf += (1.0 / (double) serverIndex); if (tryCdf / clientPtr->Zipf_constant >= u) { break; } serverIndex++; } serverIndex--;#ifdef DEBUG printf("serverIndex = %ld\n", serverIndex);#endif return clientPtr->servers[serverIndex];}/* * NAME: AppHttpClientDetermineThinkTime. * PURPOSE: Return the amount of time to think for, before the next * request. * PARAMETERS: clientPtr - pointer to the client's data structure * RETURN: the amount of time to wait. */double AppHttpClientDetermineThinkTime(GlomoAppHttpClient *clientPtr){ extern const DoubleDistElement *HttpThinkTimeDistTable; extern const int HttpThinkTimeDistLength; double u = pc_erand(clientPtr->seed); double value; int midpoint = DoubleDistFindIndex(HttpThinkTimeDistTable, HttpThinkTimeDistLength, u);#ifdef DEBUG printf(" u = %f\n", u); printf("AppHttpClientDetermineThinkTime(of %d) = %d\n", HttpThinkTimeDistLength, midpoint);#endif if (midpoint < 0) value = HttpThinkTimeDistTable[0].value; else value = DoubleDistEmpiricalContinuousInterpolate( HttpThinkTimeDistTable[midpoint].cdf, HttpThinkTimeDistTable[midpoint+1].cdf, HttpThinkTimeDistTable[midpoint].value, HttpThinkTimeDistTable[midpoint+1].value, u);#ifdef DEBUG printf(" midpoint = %d, value = %f\n", midpoint, value);#endif return value;}/* * NAME: AppHttpClientDetermineItemCount. * PURPOSE: Return the number of items on this particular page. * PARAMETERS: clientPtr - pointer to the client's data structure * RETURN: the number of items. */long AppHttpClientDetermineItemCount(GlomoAppHttpClient *clientPtr){ extern const DoubleDistElement *HttpFilesPerDocumentDistTable; extern const int HttpFilesPerDocumentDistLength; double u = pc_erand(clientPtr->seed); float value; int midpoint = DoubleDistFindIndex(HttpFilesPerDocumentDistTable, HttpFilesPerDocumentDistLength, u);#ifdef DEBUG printf(" u = %f\n", u); printf("AppHttpClientDetermineItemCount(of %d) = %d\n", HttpFilesPerDocumentDistLength, midpoint);#endif if (midpoint < 0) value = HttpFilesPerDocumentDistTable[0].value; else value = DoubleDistEmpiricalIntegralInterpolate( HttpFilesPerDocumentDistTable[midpoint].cdf, HttpFilesPerDocumentDistTable[midpoint+1].cdf, HttpFilesPerDocumentDistTable[midpoint].value, HttpFilesPerDocumentDistTable[midpoint+1].value, u);#ifdef DEBUG printf(" midpoint = %d, value = %f\n", midpoint, value);#endif return value;}/* * NAME: AppHttpClientDetermineSecondaryRequestLength. * PURPOSE: Return the number of bytes in the secondary request * PARAMETERS: clientPtr - pointer to the client's data structure * RETURN: the number of bytes. */long AppHttpClientDetermineSecondaryRequestLength( GlomoAppHttpClient *clientPtr){ extern const DoubleDistElement *HttpSecondaryRequestDistTable; extern const int HttpSecondaryRequestDistLength; double u = pc_erand(clientPtr->seed); float value; int midpoint = DoubleDistFindIndex(HttpSecondaryRequestDistTable, HttpSecondaryRequestDistLength, u);#ifdef DEBUG printf(" u = %f\n", u); printf("AppHttpClientDetermineSecondaryRequestLength(of %d) = %d\n", HttpSecondaryRequestDistLength, midpoint);#endif if (midpoint < 0) value = HttpSecondaryRequestDistTable[0].value; else value = DoubleDistEmpiricalIntegralInterpolate( HttpSecondaryRequestDistTable[midpoint].cdf, HttpSecondaryRequestDistTable[midpoint+1].cdf, HttpSecondaryRequestDistTable[midpoint].value, HttpSecondaryRequestDistTable[midpoint+1].value, u);#ifdef DEBUG printf(" midpoint = %d, value = %f\n", midpoint, value);#endif return value;}/* * NAME: AppHttpClientDeterminePrimaryRequestLength. * PURPOSE: Return the number of bytes in the primary request * PARAMETERS: clientPtr - pointer to the client's data structure * RETURN: the number of bytes. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -