1#include "LoadBalancerServer.h"
3#include "IOSocketStream.h"
4#include "Exceptions/SSLException.h"
5#include "HTTPSNetwork.h"
7#include "Utility/Sources.h"
8#include "Heuristics/Connections.h"
14 namespace load_balancer
16 LoadBalancerServer::ServerData::ServerData(utility::BaseConnectionData&& connectionData, std::unique_ptr<BaseLoadBalancerHeuristic>&& heuristic) noexcept :
17 connectionData(move(connectionData)),
18 heuristic(move(heuristic))
23 void LoadBalancerServer::clientConnection(
const string& ip, SOCKET clientSocket, sockaddr addr, function<
void()>& cleanup)
25 static mutex dataMutex;
26 const ServerData* serveData =
nullptr;
29 unique_lock<mutex> lock(dataMutex);
31 serveData = &*min_element
33 allServers.begin(), allServers.end(),
34 [](
const ServerData& left,
const ServerData& right)
36 return (*left.heuristic)() < (*right.heuristic)();
40 serveData->heuristic->onStart();
43 const auto& [connectionData, heuristic] = *serveData;
48 ssl = SSL_new(context);
52 throw web::exceptions::SSLException(__LINE__, __FILE__);
55 if (!SSL_set_fd(ssl,
static_cast<int>(clientSocket)))
59 throw web::exceptions::SSLException(__LINE__, __FILE__);
62 if (
int errorCode = SSL_accept(ssl); errorCode != 1)
64 throw web::exceptions::SSLException(__LINE__, __FILE__, ssl, errorCode);
68 streams::IOSocketStream clientStream
71 make_unique<web::HTTPSNetwork>(clientSocket, ssl, context) :
72 make_unique<web::HTTPNetwork>(clientSocket)
74 streams::IOSocketStream serverStream
77 make_unique<web::HTTPSNetwork>(connectionData.ip, connectionData.port, timeout) :
78 make_unique<web::HTTPNetwork>(connectionData.ip, connectionData.port, timeout)
86 clientStream >> request;
88 if (clientStream.eof())
93 serverStream << request;
95 if (serverStream.eof())
97 HTTPResponse errorResponse;
99 resources->internalServerError(errorResponse,
nullptr);
101 clientStream << errorResponse;
106 serverStream >> response;
108 clientStream << response;
112 unique_lock<mutex> lock(dataMutex);
118 LoadBalancerServer::LoadBalancerServer
120 string_view ip, string_view port, DWORD timeout,
bool serversHTTPS,
121 string_view heuristicName,
const vector<HMODULE>& loadSources,
122 const unordered_map<
string, vector<int64_t>>& allServers,
123 const json::JSONParser& configuration,
const filesystem::path& assets, uint64_t cachingSize,
const filesystem::path& pathToTemplates
134 resources(make_shared<ResourceExecutor>(configuration, assets, cachingSize, pathToTemplates)),
135 serversHTTPS(serversHTTPS)
137 string createHeuristicFunctionName = format(
"create{}Heuristic", heuristicName);
138 createHeuristicFunction heuristicCreateFunction =
nullptr;
140 if (heuristicName ==
"Connections")
142 heuristicCreateFunction = [](string_view ip, string_view port,
bool useHTTPS) ->
void* {
return new Connections(ip, port, useHTTPS); };
146 for (HMODULE source : loadSources)
148 if (heuristicCreateFunction =
reinterpret_cast<createHeuristicFunction
>(utility::load(source, createHeuristicFunctionName)); heuristicCreateFunction)
154 if (!heuristicCreateFunction)
156 throw runtime_error(
"Can't find heuristic");
160 this->allServers.reserve(allServers.size());
162 for (
const auto& [ip, ports] : allServers)
164 for (int64_t port : ports)
166 string portString = to_string(port);
168 this->allServers.emplace_back
170 utility::BaseConnectionData(ip, portString, timeout),
171 unique_ptr<BaseLoadBalancerHeuristic>(
static_cast<BaseLoadBalancerHeuristic*
>(heuristicCreateFunction(ip, portString, serversHTTPS)))