better simple and async web FullTest

This commit is contained in:
lganzzzo 2018-12-13 17:47:58 +02:00
parent b16b9493d8
commit 062411e072
8 changed files with 181 additions and 18 deletions

105
test/web/FullAsyncTest.cpp Normal file
View File

@ -0,0 +1,105 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "FullAsyncTest.hpp"
#include "oatpp/test/web/app/Client.hpp"
#include "oatpp/test/web/app/ControllerAsync.hpp"
#include "oatpp/web/client/HttpRequestExecutor.hpp"
#include "oatpp/web/server/AsyncHttpConnectionHandler.hpp"
#include "oatpp/web/server/HttpRouter.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/network/virtual_/client/ConnectionProvider.hpp"
#include "oatpp/network/virtual_/server/ConnectionProvider.hpp"
#include "oatpp/network/virtual_/Interface.hpp"
namespace oatpp { namespace test { namespace web {
bool FullAsyncTest::onRun() {
auto interface = oatpp::network::virtual_::Interface::createShared("virtualhost");
auto serverConnectionProvider = oatpp::network::virtual_::server::ConnectionProvider::createShared(interface);
auto clientConnectionProvider = oatpp::network::virtual_::client::ConnectionProvider::createShared(interface);
serverConnectionProvider->setSocketMaxAvailableToReadWrtie(1, 1);
clientConnectionProvider->setSocketMaxAvailableToReadWrtie(1, 1);
auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
auto router = oatpp::web::server::HttpRouter::createShared();
auto connectionHandler = oatpp::web::server::AsyncHttpConnectionHandler::createShared(router);
auto controller = app::ControllerAsync::createShared(objectMapper);
controller->addEndpointsToRouter(router);
auto requestExecutor = oatpp::web::client::HttpRequestExecutor::createShared(clientConnectionProvider);
auto client = app::Client::createShared(requestExecutor, objectMapper);
auto server = oatpp::network::server::Server::createShared(serverConnectionProvider, connectionHandler);
std::thread clientThread([client, server, connectionHandler]{
for(v_int32 i = 0; i < 10; i ++) {
try {
auto response = client->getRoot();
auto text = response->readBodyToString();
OATPP_LOGD("client", "body='%s'", text->c_str());
} catch(std::runtime_error e) {
OATPP_LOGD("client", "error='%s'", e.what());
}
}
try {
connectionHandler->stop();
server->stop();
client->getRoot();
OATPP_LOGD("client", "stoped");
} catch(std::runtime_error e) {
OATPP_LOGD("client", "stoped with e");
}
});
std::thread serverThread([server]{
server->run();
});
clientThread.join();
serverThread.join();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
return true;
}
}}}

View File

@ -0,0 +1,42 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_test_web_FullAsyncTest_hpp
#define oatpp_test_web_FullAsyncTest_hpp
#include "oatpp/test/UnitTest.hpp"
namespace oatpp { namespace test { namespace web {
class FullAsyncTest : public UnitTest {
public:
FullAsyncTest():UnitTest("TEST[web::FullAsyncTest]"){}
bool onRun() override;
};
}}}
#endif /* oatpp_test_web_FullAsyncTest_hpp */

View File

@ -42,11 +42,6 @@
namespace oatpp { namespace test { namespace web {
namespace {
}
bool FullTest::onRun() {
auto interface = oatpp::network::virtual_::Interface::createShared("virtualhost");
@ -71,7 +66,7 @@ bool FullTest::onRun() {
auto server = oatpp::network::server::Server::createShared(serverConnectionProvider, connectionHandler);
std::thread clientThread([client]{
std::thread clientThread([client, server]{
for(v_int32 i = 0; i < 10; i ++) {
@ -85,6 +80,14 @@ bool FullTest::onRun() {
}
try {
server->stop();
client->getRoot();
OATPP_LOGD("client", "stoped");
} catch(std::runtime_error e) {
OATPP_LOGD("client", "stoped with e");
}
});
std::thread serverThread([server]{

View File

@ -50,7 +50,7 @@ public:
ENDPOINT_ASYNC_INIT(Root)
Action act() {
return _return(controller->createResponse(Status::CODE_200, "Hello World Async!!!"));
return _return(controller->createResponse(Status::CODE_200, "Hello World Async!!! " + request->getHeader("host")));
}
};

View File

@ -64,7 +64,7 @@ void AsyncHttpConnectionHandler::Task::run(){
oatpp::async::Processor processor;
while(true) {
while(m_isRunning) {
/* Load all waiting connections into processor */
consumeConnections(processor);
@ -77,10 +77,7 @@ void AsyncHttpConnectionHandler::Task::run(){
std::unique_lock<std::mutex> lock(m_taskMutex);
if(processor.isEmpty()) {
/* No tasks in the processor. Wait for incoming connections */
//OATPP_LOGD("proc", "waiting for new connections");
while (m_connections.getFirstNode() == nullptr) {
m_taskCondition.wait(lock);
}
m_taskCondition.wait_for(lock, std::chrono::milliseconds(500));
} else {
/* There is still something in slow queue. Wait and get back to processing */
/* Waiting for IO is not Applicable here as slow queue may contain NON-IO tasks */

View File

@ -63,6 +63,7 @@ private:
oatpp::concurrency::SpinLock::Atom m_atom;
Connections m_connections;
private:
bool m_isRunning;
HttpRouter* m_router;
std::shared_ptr<const oatpp::web::protocol::http::incoming::BodyDecoder> m_bodyDecoder;
std::shared_ptr<handler::ErrorHandler> m_errorHandler;
@ -75,6 +76,7 @@ private:
const std::shared_ptr<handler::ErrorHandler>& errorHandler,
HttpProcessor::RequestInterceptors* requestInterceptors)
: m_atom(false)
, m_isRunning(true)
, m_router(router)
, m_bodyDecoder(bodyDecoder)
, m_errorHandler(errorHandler)
@ -97,6 +99,10 @@ private:
m_taskCondition.notify_one();
}
void stop() {
m_isRunning = false;
}
};
private:
@ -150,6 +156,12 @@ public:
void handleConnection(const std::shared_ptr<oatpp::data::stream::IOStream>& connection) override;
void stop() {
for(v_int32 i = 0; i < m_threadCount; i ++) {
m_tasks[i]->stop();
}
}
};
}}}

View File

@ -111,11 +111,11 @@ oatpp::async::Action HttpProcessor::Coroutine::onHeadersParsed(const RequestHead
auto& bodyStream = m_inStream;
bodyStream->setBufferPosition(headersReadResult.bufferPosStart, headersReadResult.bufferPosEnd);
auto request = protocol::http::incoming::Request::createShared(headersReadResult.startingLine,
m_currentRoute.matchMap,
headersReadResult.headers,
bodyStream,
m_bodyDecoder);
m_currentRequest = protocol::http::incoming::Request::createShared(headersReadResult.startingLine,
m_currentRoute.matchMap,
headersReadResult.headers,
bodyStream,
m_bodyDecoder);
auto currInterceptor = m_requestInterceptors->getFirstNode();
while (currInterceptor != nullptr) {

View File

@ -116,7 +116,11 @@ protected:
}
std::shared_ptr<OutgoingResponse> processUrl(const std::shared_ptr<protocol::http::incoming::Request>& request) override {
return (m_controller->*m_method)(request);
if(m_method != nullptr) {
return (m_controller->*m_method)(request);
} else {
return m_controller->handleError(Status::CODE_500, "Using simple model for Async endpoint");
}
}
Action processUrlAsync(oatpp::async::AbstractCoroutine* parentCoroutine,