void DestroyResponse(CommunicationID& rRequestID, Response** ppResponse)
{
    PsAssert(ppResponse != NULL);

    if (*ppResponse == NULL)
    {
        return;
    }

    // protect the maps from being changed by other threads using the mutex
    ScopeLock lock(s_mutex);

    // remove from streaming map
    if ((*ppResponse)->m_bStreamingEnabled)
    {
        ResponseMap::iterator iter = g_streamingResponseMap.find(rRequestID);

        if (iter != g_streamingResponseMap.end())
        {
            g_streamingResponseMap.erase(iter);
        }
    }

    SAFE_DELETE(*ppResponse);
    rRequestID = 0;
}
bool MultipleRequestHandler::get_result_response(const ResponseMap& responses,
                                                 const std::string& index,
                                                 ResultResponse** response) {
  ResponseMap::const_iterator it = responses.find(index);
  if (it == responses.end() || it->second->opcode() != CQL_OPCODE_RESULT) {
    return false;
  }
  *response = static_cast<ResultResponse*>(it->second.get());
  return true;
}
//-----------------------------------------------------------------------------
/// ShouldResponseBeSent
///
/// indicates whether a response should be sent to the specified request based
/// on whether or not the request is streaming and is rate limited. If the
/// request is rate limited, but a response can be sent, the "last sent time"
/// will be updated if bUpdateTime is true
///
/// \param requestID id of the request that may or may not be rate limited
/// \param bUpdateTime indicates whether or not the "last sent time" will be
///    updated if the response is rate limited, but allowed to be sent
///
/// \return true if a response should NOT be sent; false otherwise
//-----------------------------------------------------------------------------
bool ShouldResponseBeSent(CommunicationID requestID, bool bUpdateTime)
{
    // protect the maps from being changed by other threads using the mutex
    ScopeLock lock(s_mutex);

    ResponseMap::iterator iterResponse = g_streamingResponseMap.find(requestID);

    if (iterResponse == g_streamingResponseMap.end())
    {
        // don't limit the send because we don't even know it is streaming
        return false;
    }

    Response* pResponse = iterResponse->second;
    PsAssert(pResponse != NULL);

    // if this is a streaming request, only send if rate allows
    if (pResponse->m_bStreamingEnabled == true)
    {
        if (pResponse->m_dwMaxStreamsPerSecond == COMM_MAX_STREAM_RATE ||
            pResponse->m_dwMaxStreamsPerSecond == 0)
        {
            return false;
        }

        DWORD dwCurrTime = g_streamTimer.GetAbsolute();

        if (dwCurrTime - pResponse->m_dwLastSent >= 1000 / pResponse->m_dwMaxStreamsPerSecond)
        {
            if (bUpdateTime)
            {
                pResponse->m_dwLastSent = dwCurrTime;
            }

            return false;
        }
        else
        {
            return true;
        }
    }

    return false;
}
Пример #4
0
void SchemaChangeHandler::on_set(const ResponseMap& responses) {
  elapsed_ms_ += get_time_since_epoch_ms() - start_ms_;

  bool has_error = false;
  for (MultipleRequestHandler::ResponseMap::const_iterator it = responses.begin(),
       end = responses.end(); it != end; ++it) {
    if (check_error_or_invalid_response("SchemaChangeHandler", CQL_OPCODE_RESULT, it->second.get())) {
      has_error = true;
    }
  }

  if (!has_error && has_schema_agreement(responses)) {
    LOG_DEBUG("Found schema agreement in %llu ms",
              static_cast<unsigned long long>(elapsed_ms_));
    request_handler_->set_response(request_response_);
    return;
  } else if (elapsed_ms_ >= MAX_SCHEMA_AGREEMENT_WAIT_MS) {
    LOG_WARN("No schema agreement on live nodes after %llu ms. "
             "Schema may not be up-to-date on some nodes.",
             static_cast<unsigned long long>(elapsed_ms_));
    request_handler_->set_response(request_response_);
    return;
  }

  LOG_DEBUG("Schema still not up-to-date on some live nodes. "
            "Trying again in %d ms", RETRY_SCHEMA_AGREEMENT_WAIT_MS);

  // Try again
  SharedRefPtr<SchemaChangeHandler> handler(
        new SchemaChangeHandler(connection(),
                                request_handler_.get(),
                                request_response_,
                                elapsed_ms_));
  connection()->schedule_schema_agreement(handler,
                                          RETRY_SCHEMA_AGREEMENT_WAIT_MS);
}
//-----------------------------------------------------------------------------
bool MakeResponse(CommunicationID requestID, Response** ppResponse)
{
    // protect the maps from being changed by other threads using the mutex
    ScopeLock lock(s_mutex);

    PsAssert(ppResponse != NULL);

    // first see if we already have this ID as a streaming response
    ResponseMap::iterator iterResponse = g_streamingResponseMap.find(requestID);

    if (iterResponse != g_streamingResponseMap.end())
    {
        *ppResponse = iterResponse->second;
        return true;
    }

    // otherwise we need to create a new response based on the original request
    // so get the request
    RequestMap::iterator iterRequest = g_requestMap.find(requestID);

    if (iterRequest == g_requestMap.end())
    {
        // the original request couldn't be found, so return failure
        return false;
    }

    // need to create a new response
    if (PsNew(*ppResponse) == false)
    {
        return false;
    }

    HTTPRequestHeader* pRequest = iterRequest->second;
    PsAssert(pRequest != NULL);

    if (pRequest->GetReceivedOverSocket() == true)
    {
        (*ppResponse)->client_socket = pRequest->GetClientSocket();
    }
    else
    {
#if defined (_WIN32)
        (*ppResponse)->client_socket = NetSocket::CreateFromDuplicate(pRequest->GetProtoInfo());
#else
        // create a new socket and connect to the streamSocket on the server
        (*ppResponse)->client_socket = NetSocket::Create();

        if ((*ppResponse)->client_socket != NULL)
        {
            osPortAddress portAddress((unsigned short)pRequest->GetPort());
            (*ppResponse)->client_socket->Connect(portAddress);
        }

#endif
    }

    if ((*ppResponse)->client_socket == NULL)
    {
        int Err = NetSocket::LastError();
        Log(logERROR, "Could not create socket: NetSocket failed with error: %ld\n", Err);
        return false;
    }

    // see if this should be added as a streaming response
    gtASCIIString strUrl(pRequest->GetUrl());
    int32 iStream = strUrl.find(STR_STREAM_TOKEN);

    if (iStream >= 0)
    {
        const char* pBuf = strUrl.asCharArray();
        const char* pRate = &pBuf[ iStream + strlen(STR_STREAM_TOKEN)];
        unsigned int uRate = 0;

        // try to get the rate from the command;
        if (sscanf_s(pRate, "%u", &uRate) < 1)
        {
            // default to max rate
            uRate = COMM_MAX_STREAM_RATE;
        }

        // set the response as streaming with the specified rate
        (*ppResponse)->m_bStreamingEnabled = true;
        (*ppResponse)->m_dwMaxStreamsPerSecond = uRate;
        g_streamingResponseMap[ requestID ] = *ppResponse;
    }
    else
    {
        // streaming requests need to be kept around so that
        // additional responses can be directed to the right place,
        // HOWEVER, non-streaming requests only get a single response
        // and we just created the response for it, so it is safe
        // to remove the request from the requestMap. This will
        // help keep communication quick as the number of incoming
        // requests grows.
        RemoveRequest(requestID);
    }

    return true;
}