diff options
Diffstat (limited to 'fbench/src/fbench/client.h')
-rw-r--r-- | fbench/src/fbench/client.h | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/fbench/src/fbench/client.h b/fbench/src/fbench/client.h new file mode 100644 index 00000000000..4e78d2d6adc --- /dev/null +++ b/fbench/src/fbench/client.h @@ -0,0 +1,199 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#pragma once + +#include <util/clientstatus.h> +#include <fstream> +#include <atomic> +#include <thread> + +#define FBENCH_DELIMITER "\n[--xxyyzz--FBENCH_MAGIC_DELIMITER--zzyyxx--]\n" + +/** + * This struct contains arguments used to control a single client. + * Each client runs in a separate thread. This struct do not own the + * strings it references. + **/ +struct ClientArguments +{ + /** + * Sequential number identifying this client. + **/ + int _myNum; + + /** + * The total number of clients controlled by the parent fbench + * application + **/ + int _totNum; + + /** + * Pattern that combined with the client number will become the name + * of the file containing the urls this client should request. + **/ + const char *_filenamePattern; + + /** + * Pattern that combined with the client number will become the name + * of the file this client should dump url content to. If this + * pattern is set to NULL no output file is generated. + **/ + const char *_outputPattern; + + /** + * The server the client should fetch urls from. + **/ + const char *_hostname; + + /** + * The server port where the webserver is running. + **/ + int _port; + + /** + * The minimum number of milliseconds between two requests from this + * client. + **/ + long _cycle; + + /** + * Number of milliseconds to wait before making the first request. + * This will be different for different clients and helps distribute + * the requests. + **/ + long _delay; + + /** + * Number of requests that should be made before we start logging + * response times. This is included so fbench startup slugginess + * will not affect the benchmark results. + **/ + int _ignoreCount; + + /** + * Minimum number of bytes allowed in a response for a request to be + * successful. If a response contains fewer bytes than this number, + * the request will be logged as a failure even if no errors + * occurred. + **/ + int _byteLimit; + + /** + * Number of times this client is allowed to re-use the urls in the + * input query file. + **/ + int _restartLimit; + + /** + * Max line size in the input query data. Longer lines than this + * will be skipped. + **/ + int _maxLineSize; + + /** + * Indicate wether keep-alive connections should be enabled for this + * client. + **/ + bool _keepAlive; + + /** + * Indicate whether to add benchmark data coverage headers + **/ + bool _headerBenchmarkdataCoverage; + + uint64_t _queryfileOffset; + uint64_t _queryfileBytes; + bool _singleQueryFile; + std::string _queryStringToAppend; + std::string _extraHeaders; + std::string _authority; + + ClientArguments(int myNum, int totNum, + const char *filenamePattern, + const char *outputPattern, + const char *hostname, int port, + long cycle, long delay, + int ignoreCount, int byteLimit, + int restartLimit, int maxLineSize, + bool keepAlive, bool headerBenchmarkdataCoverage, + uint64_t queryfileOffset, uint64_t queryfileBytes, bool singleQueryFile, + const std::string & queryStringToAppend, const std::string & extraHeaders, + const std::string &authority) + : _myNum(myNum), + _totNum(totNum), + _filenamePattern(filenamePattern), + _outputPattern(outputPattern), + _hostname(hostname), + _port(port), + _cycle(cycle), + _delay(delay), + _ignoreCount(ignoreCount), + _byteLimit(byteLimit), + _restartLimit(restartLimit), + _maxLineSize(maxLineSize), + _keepAlive(keepAlive), + _headerBenchmarkdataCoverage(headerBenchmarkdataCoverage), + _queryfileOffset(queryfileOffset), + _queryfileBytes(queryfileBytes), + _singleQueryFile(singleQueryFile), + _queryStringToAppend(queryStringToAppend), + _extraHeaders(extraHeaders), + _authority(authority) + { + } + +private: + ClientArguments(const ClientArguments &); + ClientArguments &operator=(const ClientArguments &); +}; + +/** + * This class implements a single test client. The clients are run in + * separate threads to simulate several simultanious users. The + * operation of a client is controlled through an instance of the + * @ref ClientArguments class. + **/ +class Client +{ +private: + std::unique_ptr<ClientArguments> _args; + std::unique_ptr<ClientStatus> _status; + Timer::UP _reqTimer; + Timer::UP _cycleTimer; + Timer::UP _masterTimer; + std::unique_ptr<HTTPClient> _http; + std::unique_ptr<FileReader> _reader; + std::unique_ptr<std::ofstream> _output; + int _linebufsize; + char *_linebuf; + std::atomic<bool> _stop; + std::atomic<bool> _done; + std::thread _thread; + + Client(const Client &); + Client &operator=(const Client &); + static void runMe(Client * client); + void run(); + +public: + typedef std::unique_ptr<Client> UP; + /** + * The client arguments given to this method becomes the + * responsibility of the client. + **/ + Client(ClientArguments *args); + + /** + * Delete objects owned by this client, including the client arguments. + **/ + ~Client(); + + /** + * @return A struct containing status info for this client. + **/ + const ClientStatus & GetStatus() { return *_status; } + void start(); + void stop(); + bool done(); + void join(); +}; + |