//////////////////////////////////////////////////////////////////////////////// /// @brief benchmark thread /// /// @file /// /// DISCLAIMER /// /// Copyright 2004-2012 triagens GmbH, Cologne, Germany /// /// 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. /// /// Copyright holder is triAGENS GmbH, Cologne, Germany /// /// @author Jan Steemann /// @author Copyright 2012, triAGENS GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// #ifndef TRIAGENS_V8_CLIENT_BENCHMARK_THREAD_H #define TRIAGENS_V8_CLIENT_BENCHMARK_THREAD_H 1 #include "Basics/Common.h" #include "BasicsC/hashes.h" #include "Basics/ConditionLocker.h" #include "Basics/ConditionVariable.h" #include "Basics/Thread.h" #include "SimpleHttpClient/SimpleClient.h" #include "SimpleHttpClient/SimpleHttpClient.h" #include "SimpleHttpClient/GeneralClientConnection.h" #include "V8Client/BenchmarkCounter.h" #include "V8Client/BenchmarkOperation.h" using namespace std; using namespace triagens::basics; using namespace triagens::httpclient; using namespace triagens::rest; namespace triagens { namespace v8client { // ----------------------------------------------------------------------------- // --SECTION-- class BenchmarkThread // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @addtogroup Threading /// @{ //////////////////////////////////////////////////////////////////////////////// class BenchmarkThread : public Thread { public: BenchmarkThread (BenchmarkOperation* operation, ConditionVariable* condition, const unsigned long batchSize, BenchmarkCounter* operationsCounter, Endpoint* endpoint, const string& username, const string& password) : Thread("arangob"), _operation(operation), _startCondition(condition), _batchSize(batchSize), _operationsCounter(operationsCounter), _endpoint(endpoint), _username(username), _password(password), _client(0), _connection(0), _time(0.0) { } ~BenchmarkThread () { if (_client != 0) { delete _client; } if (_connection != 0) { delete _connection; } } //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------- // --SECTION-- virtual protected methods // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @addtogroup Threading /// @{ //////////////////////////////////////////////////////////////////////////////// protected: //////////////////////////////////////////////////////////////////////////////// /// @brief the thread program //////////////////////////////////////////////////////////////////////////////// virtual void run () { allowAsynchronousCancelation(); _connection = GeneralClientConnection::factory(_endpoint, 5.0, 10.0, 3); if (_connection == 0) { cerr << "out of memory" << endl; exit(EXIT_FAILURE); } _client = new SimpleHttpClient(_connection, 10.0, true); _client->setUserNamePassword("/", _username, _password); map headerFields; SimpleHttpResult* result = _client->request(SimpleHttpClient::GET, "/_api/version", 0, 0, headerFields); if (! result || ! result->isComplete()) { if (result) { delete result; } cerr << "could not connect to server" << endl; exit(EXIT_FAILURE); } delete result; // wait for start condition to be broadcasted { ConditionLocker guard(_startCondition); guard.wait(); } while (1) { unsigned long numOps = _operationsCounter->next(_batchSize); if (numOps == 0) { break; } if (_batchSize < 1) { executeSingleRequest(); } else { executeBatchRequest(numOps); } } } void executeBatchRequest (const unsigned long numOperations) { } void executeSingleRequest () { Timing timer(Timing::TI_WALLCLOCK); const SimpleHttpClient::http_method type = _operation->type(); const string url = _operation->url(); size_t payloadLength = 0; const char* payload = _operation->payload(&payloadLength); const map& headers = _operation->headers(); SimpleHttpResult* result = _client->request(type, url, payload, payloadLength, headers); _time += ((double) timer.time()) / 1000000.0; if (result == 0) { _operationsCounter->incFailures(); return; } if (result->getHttpReturnCode() >= 400) { _operationsCounter->incFailures(); } delete result; } public: double getTime () const { return _time; } //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------- // --SECTION-- private variables // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @addtogroup Threading /// @{ //////////////////////////////////////////////////////////////////////////////// private: //////////////////////////////////////////////////////////////////////////////// /// @brief the operation to benchmark //////////////////////////////////////////////////////////////////////////////// BenchmarkOperation* _operation; //////////////////////////////////////////////////////////////////////////////// /// @brief condition variable //////////////////////////////////////////////////////////////////////////////// ConditionVariable* _startCondition; //////////////////////////////////////////////////////////////////////////////// /// @brief batch size //////////////////////////////////////////////////////////////////////////////// const unsigned long _batchSize; //////////////////////////////////////////////////////////////////////////////// /// @brief benchmark counter //////////////////////////////////////////////////////////////////////////////// BenchmarkCounter* _operationsCounter; //////////////////////////////////////////////////////////////////////////////// /// @brief endpoint to use //////////////////////////////////////////////////////////////////////////////// Endpoint* _endpoint; //////////////////////////////////////////////////////////////////////////////// /// @brief HTTP username //////////////////////////////////////////////////////////////////////////////// const string _username; //////////////////////////////////////////////////////////////////////////////// /// @brief HTTP password //////////////////////////////////////////////////////////////////////////////// const string _password; //////////////////////////////////////////////////////////////////////////////// /// @brief underlying client //////////////////////////////////////////////////////////////////////////////// triagens::httpclient::SimpleClient* _client; //////////////////////////////////////////////////////////////////////////////// /// @brief connection to the server //////////////////////////////////////////////////////////////////////////////// triagens::httpclient::GeneralClientConnection* _connection; //////////////////////////////////////////////////////////////////////////////// /// @brief time //////////////////////////////////////////////////////////////////////////////// double _time; }; } } //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// #endif // ----------------------------------------------------------------------------- // --SECTION-- END-OF-FILE // ----------------------------------------------------------------------------- // Local Variables: // mode: outline-minor // outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)" // End: