35 #include "../ncbi_lbsm.h"
36 #include "../ncbi_server_infop.h"
111 string pref_section =
"dblb/preferences";
112 list<string> pref_keys;
114 for (
const string& service : pref_keys) {
115 const string& preference_info =
registry->
Get(pref_section, service);
116 CTempString endpoint, preference, host_str, port_str;
124 if ( !port_str.
empty() ) {
139 if ((*it)->GetExpireTime() <= now) {
140 _TRACE(
"For " << service <<
": erasing from excluded server '"
141 << (*it)->GetName() <<
"', host " << (*it)->GetHost()
142 <<
", port " << (*it)->GetPort());
143 exclude_list.
erase(it);
150 if (it->second.second >= now
151 && (promiscuity & ~it->second.first) == 0) {
154 _TRACE(
"Service " << service <<
" is known dead, bypassing LBSM.");
176 time_t cur_time = time(
NULL);
182 vector<const char*> skip_names;
183 std::for_each(exclude_list.
begin(),
186 skip_names.push_back(
NULL);
190 if (!preferred_svr.
Empty()) {
202 preferred_svr.
Empty()
217 }
else if (cp.
host) {
221 _TRACE(
"Remembering: service " << service <<
" is dead.");
240 if (sinfo->
port != 0) {
241 server_name.append(1,
':');
244 serv_list->push_back(server_name);
271 time_t cur_time = time(
NULL);
278 && preferred_svr->second.first >= 100.0
279 && preferred_svr->second.second.NotEmpty()) {
281 requested = preferred_svr->second.second;
283 && (requested->GetHost() == server->
GetHost()
284 || requested->GetHost() == 0)
285 && (requested->GetPort() == server->
GetPort()
286 || requested->GetPort() == 0)) {
287 _TRACE(service <<
": latching to " << server->
GetName() <<
'@'
290 options->emplace_back
312 TOptions::iterator most_preferred = options->end();
315 size_t missing_hinfo = 0;
316 list<CRef<SRawOption>> raw_options;
324 for (
const auto& it : exclusions->second) {
325 if (it->GetHost() == sinfo->
host
326 && (it->GetPort() == sinfo->
port
327 || it->GetPort() == 0)) {
334 missing_hinfo =
true;
342 if (missing_hinfo > 0) {
344 if (missing_hinfo ==
n) {
349 double scale = 1.0 / (
n - missing_hinfo);
350 for (
const auto& it : raw_options) {
351 default_load.
status += it->load.status * scale;
352 default_load.
statusBLAST += it->load.statusBLAST * scale;
355 for (
auto& it : raw_options) {
356 if (it->load.status == 0.0) {
357 it->load = default_load;
361 for (
const auto& it : raw_options) {
369 bool update_most_preferred =
false;
372 && preferred_svr->second.first > 0.0
373 && preferred_svr->second.second.NotEmpty()
374 && (preferred_svr->second.second->GetHost() == sinfo->
host
375 || preferred_svr->second.second->GetHost() == 0)
376 && (preferred_svr->second.second->GetPort() == sinfo->
port
377 || preferred_svr->second.second->GetPort() == 0)) {
379 if (most_preferred == options->end()
380 || (*most_preferred)->GetRanking() < ranking) {
381 update_most_preferred =
true;
385 _TRACE(service <<
": " << name <<
'@'
387 <<
" -- initial ranking " << ranking <<
", state " <<
state
389 options->emplace_back
392 if (update_most_preferred) {
393 TOptions::reverse_iterator ri = options->rbegin();
394 most_preferred = (++ri).base();
398 if (
n >= 2 && most_preferred != options->end()) {
399 double pref = preferred_svr->second.first * 0.01,
400 access = (*most_preferred)->GetRanking(),
401 gap = access / total,
406 double spread = 14.0 / (double(
n) + 12.0);
407 if (gap >= spread /
double(
n)) {
410 p0 = 2.0 / spread * gap * pref;
420 new_ranking = (total - access) * p0 / (1.0 - p0);
422 const string& name = (*most_preferred)->GetName();
423 Uint4 host = (*most_preferred)->GetHost();
424 Uint2 port = (*most_preferred)->GetPort();
425 _TRACE(service <<
": " << name <<
'@'
427 <<
" -- adjusting ranking to " << new_ranking);
428 most_preferred->Reset
430 (*most_preferred)->GetState(),
431 (
TNCBI_Time) (*most_preferred)->GetExpireTime()));
434 if (options->empty()) {
435 _TRACE(
"Remembering: service " << service <<
" is dead.");
443 const TSvrRef& preferred_server,
478 }
catch (exception&) {
499 return "DBLB_NAME_MAPPER";
void operator()(const TSvrRef &server)
vector< const char * > * m_Names
CCharInserter(vector< const char * > &names)
TSvrRef x_GetServer(const string &service)
virtual void GetServerOptions(const string &service, TOptions *options)
Get an annotated list of all servers for the given service.
CDBLB_ServiceMapper(const IRegistry *registry=NULL)
static IDBServiceMapper * Factory(const IRegistry *registry)
TPreferenceMap m_PreferenceMap
virtual void GetServersList(const string &service, list< string > *serv_list) const
Get list of all servers for the given service disregarding any exclusions.
bool x_IsEmpty(const string &service, TSERV_Type promiscuity, time_t now)
virtual TSvrRef GetServer(const string &service)
Map a service to a server.
void ConfigureFromRegistry(const IRegistry *registry=NULL)
virtual ~CDBLB_ServiceMapper(void)
virtual void SetPreference(const string &service, const TSvrRef &preferred_server, double preference=100.0)
Set up mapping preferences for a service preference - value between 0 and 100 (0 means *no particular...
virtual void Configure(const IRegistry *registry=NULL)
virtual bool RecordServer(I_ConnectionExtra &extra) const
Given a connection that succeeded even though this service mapper was unable to identify a good serve...
virtual string GetName(void) const
CDBServerOption – CDBServer extended with additional information that helps maintain a balanced pool ...
@ fState_Normal
Fully available.
@ fState_Penalized
Penalized by the load balancer.
@ fState_Excluded
Excluded by DBAPI.
time_t GetExpireTime(void) const
Uint2 GetPort(void) const
const string & GetName(void) const
Uint4 GetHost(void) const
static string GetName(void)
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
static void x_RecordServer(I_ConnectionExtra &extra, CDBServer &server)
list< CRef< CDBServerOption > > TOptions
container_type::const_iterator const_iterator
container_type::iterator iterator
const_iterator end() const
const_iterator find(const key_type &key) const
const_iterator begin() const
const_iterator end() const
static const char si[8][64]
static const struct name_t names[]
static CNcbiApplicationGuard InstanceGuard(void)
Singleton method.
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
#define ERASE_ITERATE(Type, Var, Cont)
Non-constant version with ability to erase current element, if container permits.
bool NotEmpty(void) const THROWS_NONE
Check if CRef is not empty – pointing to an object and has a non-null value.
bool Empty(void) const THROWS_NONE
Check if CRef is empty – not pointing to any object, which means having a null value.
uint32_t Uint4
4-byte (32-bit) unsigned integer
uint16_t Uint2
2-byte (16-bit) unsigned integer
virtual const string & Get(const string §ion, const string &name, TFlags flags=0) const
Get the parameter value.
virtual int GetInt(const string §ion, const string &name, int default_value, TFlags flags=0, EErrAction err_action=eThrow) const
Get integer value of specified parameter name.
virtual void EnumerateEntries(const string §ion, list< string > *entries, TFlags flags=fAllLayers) const
Enumerate parameter names for a specified section.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
#define SERV_MINIMAL_RATE
SSERV_InfoCPtr SERV_GetNextInfo(SERV_ITER iter)
Same as "SERV_GetNextInfoEx(., 0)" – i.e.
void SERV_Close(SERV_ITER iter)
Deallocate the iterator.
int HINFO_Status(const HOST_INFO host_info, double status[2])
Obtain LB host availability status.
SERV_ITER SERV_Open(const char *service, TSERV_Type types, unsigned int preferred_host, const SConnNetInfo *net_info)
Same as "SERV_OpenEx(., ., ., ., 0, 0)" – i.e.
unsigned int TSERV_Type
Bitwise OR of ESERV_Type[Special].
SSERV_InfoCPtr SERV_GetNextInfoEx(SERV_ITER iter, HOST_INFO *host_info)
Get the next server meta-address, optionally accompanied by the host parameters made available by the...
@ fSERV_ReverseDns
LB-DNS translation.
@ fSERV_Promiscuous
Evrthng and the kitchen sink.
void SOCK_GetPeerAddress(SOCK sock, unsigned int *host, unsigned short *port, ENH_ByteOrder byte_order)
Get host and port of the socket's peer (remote end).
static string HostPortToString(unsigned int host, unsigned short port)
See SOCK_HostPortToString()
unsigned short SOCK_GetRemotePort(SOCK sock, ENH_ByteOrder byte_order)
Get remote port of the socket (the port it is connected to).
EIO_Status SOCK_Close(SOCK sock)
Close the SOCK handle, and destroy all relevant internal data.
static string ntoa(unsigned int host)
BSD-like API. NB: when int, "host" must be in network byte order.
static unsigned int gethostbyname(const string &host, ESwitch log=eOff)
Return 0 on error.
EIO_Status SOCK_CreateOnTopEx(const void *handle, size_t handle_size, SOCK *sock, const void *data, size_t size, TSOCK_Flags flags)
[SERVER-side] Create a SOCKet on top of either an OS-dependent "handle" (file descriptor on Unix,...
@ fSOCK_KeepOnClose
retain OS handle in SOCK_Close[Ex]()
static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)
Convert string to double.
static TNumeric StringToNumeric(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to a numeric value.
bool empty(void) const
Return true if the represented string is empty (i.e., the length is zero)
static string UIntToString(unsigned int value, TNumToStringFlags flags=0, int base=10)
Convert UInt to string.
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
#define NCBI_TIME_INFINITE
SConnNetInfo * ConnNetInfo_Create(const char *service)
void ConnNetInfo_Destroy(SConnNetInfo *net_info)
SNetStorageObjectState< SNetStorageObjectDirectState< TBase > > TState
@ fDBLB_AllowFallbackToStandby
const char * DBLB_GetServer(const char *lb_name, TDBLB_Flags flags, const SDBLB_Preference *preference, const char *const skip_servers[], SDBLB_ConnPoint *conn_point, char *server_name_buf, size_t server_name_buflen, EDBLB_Status *result)
CRef< CDBServer > TSvrRef
double LBSM_CalculateStatus(double rate, double fine, ESERV_Algo algo, const SLBSM_HostLoad *load)
SSERV_Info * SERV_CopyInfoEx(const SSERV_Info *orig, const char *name)
const char * SERV_NameOfInfo(const SSERV_Info *info)
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
static SLJIT_INLINE sljit_ins st(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
static SLJIT_INLINE sljit_ins l(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
CDBServerOption::TState TState
SRawOption(const SSERV_Info &si, TState st, const SLBSM_HostLoad &l)