src.dualinventive.com/dinet/sec-multi-proxy/include/server/TCPConnectionDirector.h

99 lines
2.5 KiB
C++

/*
* Server.h
*
* Created on: Apr 24, 2015
* Author: rheijden
*/
#ifndef INCLUDE_SERVER_TCPCONNECTIONDIRECTOR_H_
#define INCLUDE_SERVER_TCPCONNECTIONDIRECTOR_H_
#include <vector>
#include <memory>
#include <mutex>
#include <atomic>
#include <di/Configuration.h>
#include <di/Mailbox.h>
#define DESIRED_WORKERS(ncon) static_cast<ssize_t>(MAX(10, (ncon / 5)))
class DeviceFacade;
class TCPConnection;
class ProtocolFacade;
struct Message;
class TCPConnectionDirector {
public:
const int kWorkerMailboxTimeoutMs = 50;
const size_t kWorkerSelectTimeoutMs = 10;
const float kMinimumWorkers = 10;
const float kMaximumWorkers = 100;
const float kConnectionsPerWorker = 5;
const float kWorkerMovingAverageFactor = 30;
const float kWorkerFastScalingThreshold = 2;
/**
* constructor of the connection director
* @param c pointer to config
* @param d pointer to device facade
*/
TCPConnectionDirector(const std::shared_ptr<Di::Configuration> &c, const std::shared_ptr<DeviceFacade> &d);
~TCPConnectionDirector();
/**
* create a new connection
* @param fd socket
* @param info
* @return true if .. false if ..
*/
bool newConnection(int fd, const struct sockaddr_in &info);
private:
struct Worker {
std::shared_ptr<std::thread> workerThread;
std::atomic_bool running;
};
std::atomic_bool __running;
uint64_t __connectionTimeoutMs;
std::mutex __workerMutex;
std::shared_ptr<Di::Configuration> __cfg;
std::vector<std::shared_ptr<struct Worker>> __workerList;
std::shared_ptr<Di::Mailbox<TCPConnection>> __mailbox;
std::shared_ptr<ProtocolFacade> __protoFacade;
std::shared_ptr<DeviceFacade> __deviceFacade;
std::atomic_size_t __nConnections;
std::shared_ptr<std::thread> workerScaler;
float __workerCountAverage;
/**
* thread function which adjusts the number of workers to
* the desired amount (based on number of connections)
*/
void __scaleWorkers(void);
/**
* Calculates how many workers are desired
*/
size_t __workerCount(void);
/**
* stop inactive worker
*/
void __terminateWorkers(ssize_t);
/**
* create new worker
*/
void __spawnWorkers(ssize_t);
void __encodeAndWrite(const std::shared_ptr<TCPConnection> &conn, const std::shared_ptr<struct Message> &msg);
void __worker(std::shared_ptr<struct Worker> worker);
void __workerRead(const std::shared_ptr<TCPConnection> &conn);
void __workerMessage(const std::shared_ptr<TCPConnection> &conn, const std::shared_ptr<struct Message> &msg);
};
#endif // INCLUDE_SERVER_TCPCONNECTIONDIRECTOR_H_