У меня есть код, который использует asio coroutine для получения файла с использованием http, получает асинхронно.
Теперь я пытаюсь изменить этот код, чтобы получить 24 файла, я хочу сделать контейнер, который имеет boost :: futures ", а не std :: futures ", чтобы я мог использовать wait_for_any для обработки готового к использованию будущего.
я хочу преобразовать свою сопрограмму во что-то, что сохраняет асинхронный http get, и в то же время возвращает правильное имя файла при окончании http get" или ошибка ".
это моя сопрограмма:
void HTTPRequest::Execute(boost::asio::yield_context yield_r, std::string request_name, boost::shared_ptr<std::map<std::string, boost::shared_ptr<HTTPResponse>>> mHTTPClient_Responses_Map_shared_pointer)
//4-9-2020 trial of promise
//13std::string HTTPRequest::Execute(boost::asio::yield_context yield_r, boost::promise<std::string> &p, std::string request_name, boost::shared_ptr<std::map<std::string, boost::shared_ptr<HTTPResponse>>> mHTTPClient_Responses_Map_shared_pointer)
{
std::map<std::string, boost::shared_ptr<HTTPResponse>> & mHTTPClient_Responses_Map = boost::ref(*mHTTPClient_Responses_Map_shared_pointer).get() ;
ptime startFetch = second_clock::local_time();
boost::unique_lock<boost::mutex> cancel_lock(mCancelMutex);
if (mWasCancelled)
{
cancel_lock.unlock();
OnFinish(boost::system::error_code(boost::asio::error::operation_aborted));
m_formatting_ostream << "Request #" << this->GetId() << " for " << mUrl << " has been cancelled by the user at start of HTTPRequest::Execute coroutine." << std::endl;
m_formatting_ostream.flush();
////allam2020 change UniqueSignalValue to url
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "cancelExecute", request_name, m_formatting_ostream_string);
m_formatting_ostream.clear();
//p.set_value(request_name);
//return request_name;
}
cancel_lock.unlock();
bool iterator_failed = true;//// allam 2020 where is this variable changed?????????? is it before SendRequest()??????? after async_connect retruns successfully
boost::system::error_code ec;
for (auto iterator_resolve : *mRequestSharedPtrVecResolverIterator)
{
BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Request #" << this->GetId() << " for " << mUrl <<" trying to send request using " << iterator_resolve->endpoint().address().to_string() << std::endl;
// Compose the request message.
mRequestBuf += "GET " + mUri + " HTTP/1.1\r\n";
// Add mandatory header.
mRequestBuf += "Host: " + mHost + "\r\n";
mRequestBuf += "\r\n";
for (int mIrange : boost::irange(0, ATTEMPTS))
{
HTTPRequest::mIrange = mIrange;
////allam2020 1111111111111111111111111111111111111111111111111111111111
resolver_iterator iterator_connect = boost::asio::async_connect(mSock, iterator_resolve, yield_r[ec]);////allam 2020 this gets us back to io_stream_run
if (ec.value() == boost::system::errc::errc_t::success)//(ec.value()==0)
{
////allam 2020
iterator_failed = false;//????????????/////???????
boost::unique_lock<boost::mutex> cancel_lock(mCancelMutex);
if (mWasCancelled)
{
cancel_lock.unlock();
OnFinish(boost::system::error_code(boost::asio::error::operation_aborted));
m_formatting_ostream << "Request #" << this->GetId() << " for " << mUrl << " has been cancelled by the user after returning from async_connect inside HTTPRequest::Execute using"<< iterator_resolve->endpoint().address().to_string() << std::endl;
m_formatting_ostream.flush();
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "cancel_async_connect_Execute", iterator_resolve->endpoint().address().to_string(),m_formatting_ostream_string);
m_formatting_ostream.clear();
//p.set_value(request_name);
//return request_name;
}
cancel_lock.unlock();
// Send the request message.
SendRequest(yield_r);////alllam 2020 VVVVVVVVIIIIIIIIIIIIIPPPPPPPPPPP MILESTONE
}
else if (ec.value() != boost::system::errc::errc_t::success)//(ec.value()==0) //(ec.value() != 0)
{
OnFinish(ec);
BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) <<"Request #" << this->GetId() << " for " << mUrl <<" failed after trying " << mIrange << "times" << " to async_connect inside HTTPRequest::Execute " << std::endl;
continue;
}
////allam 2020 now test for mContinue_for ,this is done for other functions recurdively called inside SendRequest
if (mContinue_for==true)
{
mContinue_for = !(mContinue_for);
boost::this_thread::sleep_for(boost::chrono::seconds(mIrange));
continue;
}
// Response is correct.
//log str_status_code
//Logger.info("Fetched {0} completed in {1}s".format(id, time.time() - start))
//allam2020
m_formatting_ostream << "Request #" << this->GetId() << " for " << mUrl << "Fetched " << mUrl << " completed in : " << (second_clock::local_time() - startFetch) << "with HTTP code :" << mResponsePtr->get_status_code() << "\n" << "and the code reasonPhrase is :" << HttpStatus::reasonPhrase(static_cast<int>(mResponsePtr->get_status_code())) << "with certain resolver iterator " << iterator_resolve->endpoint().address().to_string() << std::endl;
m_formatting_ostream.flush();
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "http_request_completed", HttpStatus::reasonPhrase(static_cast<int>(mResponsePtr->get_status_code())), m_formatting_ostream_string);
m_formatting_ostream.clear();
//if len(buffer.getbuffer()) <= 0:
if (mResponsePtr->get_response_buf().size() <= 0)
{
//Logger.info("Buffer for {0} is empty ".format(id))
//allam2020
m_formatting_ostream << "Request #" << this->GetId() << " for " << mUrl << "Fetched " << mUrl << " with Buffer for " << mUrl << " is empty " << "\n" << "with HTTP code :" << mResponsePtr->get_status_code() << "\n" << "and the code reasonPhrase is :" << HttpStatus::reasonPhrase(static_cast<int>(mResponsePtr->get_status_code())) << std::endl;
m_formatting_ostream.flush();
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "http_request_completed_empty", HttpStatus::reasonPhrase(static_cast<int>(mResponsePtr->get_status_code())), m_formatting_ostream_string);
m_formatting_ostream.clear();
}
//continue work on response
////std::string response_name = "response_" + request_name;////allam 2020 make this member variable????????????//4-22-2020 yes
mHTTPRequest_response_name = "response_" + request_name;
mHTTPClient_Responses_Map[mHTTPRequest_response_name] = GetResponseSharedPtr();
break;
}
//the following conditions test the result of send request
if (mSendRequest == 0)
{
if (mReadStatusLine == 0)
{
if (mHttp_1_1 == 0)
{
if (mStatusCodeNot200 == 0)
{
if (mReadResponseHeaders == 0)
{
if (mReadResponseBody == 0)
{
////allam2020 4-4-2020 no error present and response is recieved in its mHTTPResponse SO DO NOTHING
}
else if (mReadResponseBody != 0)
{
m_formatting_ostream << "Request #" << this->GetId() << " for " << mUrl << " has failed completely after trying" << ATTEMPTS << "times" << " to async_read inside HTTPRequest::ReadResponseBody to get ResponseBody " << "with certain resolver iterator " << iterator_resolve->endpoint().address().to_string() << std::endl;
m_formatting_ostream.flush();
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "failed_async_read_inside_HTTPRequest_ReadResponseBody", "requestFailed_ReadResponseBody_Iterator_ " + iterator_resolve->endpoint().address().to_string(),m_formatting_ostream_string);
m_formatting_ostream.clear();
}
}
else if (mReadResponseHeaders != 0)
{
m_formatting_ostream << "Request #" << this->GetId() << " for " << mUrl << " has failed completely after trying" << ATTEMPTS << "times" << " to async_read_until inside HTTPRequest::ReadResponseHeadersto get ResponseHeaders " << "with certain resolver iterator " << iterator_resolve->endpoint().address().to_string() << std::endl;
m_formatting_ostream.flush();
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "failed_async_read_until_inside_HTTPRequest_ReadResponseHeaders", "requestFailed_ReadResponseHeaders_Iterator_ " + iterator_resolve->endpoint().address().to_string(), m_formatting_ostream_string);
m_formatting_ostream.clear();
}
}
else if (mStatusCodeNot200 != 0)
{
m_formatting_ostream << "Request #" << this->GetId() << " for " << mUrl << " has failed completely after" << ATTEMPTS << "times" << " to async_read_until inside HTTPRequest::ReadStatusLine because of status_code not 200:" << http_errors::invalid_response << "the error code is :" << mStatusCode << "\n" << "and the error reasonPhrase is :" << HttpStatus::reasonPhrase(static_cast<int>(std::stoul(mStatusCode))) << "with certain resolver iterator " << iterator_resolve->endpoint().address().to_string() << std::endl;
m_formatting_ostream.flush();
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "failed_StatusCodeNot200_inside_HTTPRequest_ReadStatusLine", "requestFailed_ReadStatusLine_StatusCodeNot200:" + mStatusCode + "_Iterator_ " + iterator_resolve->endpoint().address().to_string(), m_formatting_ostream_string);
m_formatting_ostream.clear();
}
}
else if (mHttp_1_1 != 0)
{
////4-2-2020
m_formatting_ostream << "Request #" << this->GetId() << " for " << mUrl << " after trying " << ATTEMPTS << "times" << " to async_read_until inside HTTPRequest::ReadStatusLine because of bad not http/1.1 version response" << mHTTP_Version << "recieved with certain resolver iterator " << iterator_resolve->endpoint().address().to_string() << std::endl;
m_formatting_ostream.flush();
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "failed_Http_1_1_inside_HTTPRequest_ReadStatusLine", "requestFailed_ReadStatusLine_Http_1_1_Iterator " + iterator_resolve->endpoint().address().to_string(), m_formatting_ostream_string);
m_formatting_ostream.clear();
}
}
else if (mReadStatusLine != 0)
{
////4-2-2020
m_formatting_ostream << "Request #" << this->GetId() << " for " << mUrl << " after trying " << ATTEMPTS << "times" << " to async_read_until inside HTTPRequest::ReadStatusLine with certain resolver iterator " << iterator_resolve->endpoint().address().to_string() << std::endl;
m_formatting_ostream.flush();
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "failed_async_read_until_inside_HTTPRequest_ReadStatusLine", "requestFailed_ReadStatusLine_Iterator " + iterator_resolve->endpoint().address().to_string(), m_formatting_ostream_string);
m_formatting_ostream.clear();
}
}
else if (mSendRequest != 0)
{
////4-2-2020
m_formatting_ostream << "Request #" << this->GetId() << " for " << mUrl << " after trying " << ATTEMPTS << "times" << " to async_write inside HTTPRequest::SendRequest with certain resolver iterator " << iterator_resolve->endpoint().address().to_string() << std::endl;
m_formatting_ostream.flush();
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "failed_async_write_inside_HTTPRequest_SendRequest", "requestFailed_SendRequest_Iterator " + iterator_resolve->endpoint().address().to_string(), m_formatting_ostream_string);
m_formatting_ostream.clear();
}
if (iterator_failed == true)
{
m_formatting_ostream << "Request failed for " << mUrl << " after trying " << ATTEMPTS << "times" << " to async_connect inside HTTPRequest::Execute with certain resolver iterator "<< iterator_resolve->endpoint().address().to_string() << std::endl;
m_formatting_ostream.flush();
////allam 2020 i might need to pass iterator resolve which has failed
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "failed_async_connect_inside_HTTPRequest_Execute", "requestFailed_Iterator " + iterator_resolve->endpoint().address().to_string(), m_formatting_ostream_string);
m_formatting_ostream.clear();
continue;////allam 2020 here i should continue for next iterator
}
}
if (iterator_failed == true)
{
m_formatting_ostream << "Request failed for " << mUrl << " after trying " << ATTEMPTS << "times" << " to async_connect inside HTTPRequest::Execute with ALL resolver iterators" << std::endl;
m_formatting_ostream.flush();
////allam 2020 i might need to pass iterator resolve which has failed
boost_log_function(mHTTPRequest_LoggingInstance_shared_pointer, "failed_async_connect_inside_HTTPRequest_Execute", "requestFailed_Iterator" + GetmUrlLogger(),m_formatting_ostream_string);////allam2020 ?????i might need to change this from GetmUrlLogger to request name argument of Execute???????????????????4-2-2020
m_formatting_ostream.clear();
////allam 2020 here i should return from execute because no resolved address could be used so the whole execute request operation failed
//p.set_value(request_name);
//return request_name;
}
////allam2020 should i put if conditions for mSendRequest ....mReadResponseBody????? to identify final complete error at these functions and end of 5 attempts
}
есть другие функции SendRequest ..., которые вызываются из Execute, но я не помещал их, чтобы сделать меньше кода.
при необходимости я буду опубликовать их.