NCBI C++ ToolKit
ncbi_dblb_svcmapper.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbi_dblb_svcmapper.cpp 99864 2023-05-17 19:32:48Z saprykin $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Sergey Sikorskiy
27  *
28  * File Description:
29  * Database service name to server name mapping policy implementation.
30  *
31  */
32 
33 #include <ncbi_pch.hpp>
34 
35 #include "../ncbi_lbsm.h"
36 #include "../ncbi_server_infop.h"
38 #include <connect/ext/ncbi_dblb.h>
39 #include <connect/ncbi_socket.hpp>
40 #include <connect/ncbi_service.h>
41 #include <corelib/ncbiapp.hpp>
42 #include <algorithm>
43 #include <math.h>
44 
45 
47 
48 
49 ///////////////////////////////////////////////////////////////////////////////
51 {
52 public:
53  CCharInserter(vector<const char*>& names)
54  : m_Names(&names)
55  {
56  }
57 
58 public:
59  void operator()(const TSvrRef& server)
60  {
61  m_Names->push_back(server->GetName().c_str());
62  }
63 
64 private:
65  vector<const char*>* m_Names;
66 };
67 
68 
69 
70 ///////////////////////////////////////////////////////////////////////////////
72 {
74 }
75 
76 
78 {
79 }
80 
81 
82 string CDBLB_ServiceMapper::GetName(void) const
83 {
85 }
86 
87 
88 void
90 {
92 
94 }
95 
96 
97 void
99 {
100  // Get current registry ...
102  if (!registry && app) {
103  registry = &app->GetConfig();
104  }
105  if (registry)
106  m_EmptyTTL = registry->GetInt("dblb", "cached_empty_service_ttl", 1);
107  else
108  m_EmptyTTL = 1;
109 #if 0
110  // test code
111  string pref_section = "dblb/preferences";
112  list<string> pref_keys;
113  registry->EnumerateEntries(pref_section, &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;
117  Uint4 host;
118  Uint2 port;
119 
120  NStr::SplitInTwo(preference_info, " \t", endpoint, preference,
122  NStr::SplitInTwo(endpoint, ":", host_str, port_str);
123  host = CSocketAPI::gethostbyname(host_str);
124  if ( !port_str.empty() ) {
125  NStr::StringToNumeric(port_str, &port);
126  }
127  SetPreference(service, TSvrRef(new CDBServer(endpoint, host, port)),
128  NStr::StringToDouble(preference));
129  }
130 #endif
131 }
132 
133 
134 bool CDBLB_ServiceMapper::x_IsEmpty(const string& service,
135  TSERV_Type promiscuity, time_t now)
136 {
137  TSrvSet& exclude_list = m_ExcludeMap[service];
138  ERASE_ITERATE(TSrvSet, it, exclude_list) {
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);
144  m_LBEmptyMap.erase(service);
145  }
146  }
147 
149  if (it != m_LBEmptyMap.end()) {
150  if (it->second.second >= now
151  && (promiscuity & ~it->second.first) == 0) {
152  // We've tried this service already. It is not served by load
153  // balancer. There is no reason to try it again.
154  _TRACE("Service " << service << " is known dead, bypassing LBSM.");
155  return true;
156  }
157  else {
158  m_LBEmptyMap.erase(it);
159  }
160  }
161 
162  return false;
163 }
164 
165 
166 TSvrRef
167 CDBLB_ServiceMapper::GetServer(const string& service)
168 {
170  return x_GetServer(service);
171 }
172 
173 TSvrRef
174 CDBLB_ServiceMapper::x_GetServer(const string& service)
175 {
176  time_t cur_time = time(NULL);
177  if (x_IsEmpty(service, fSERV_IncludeInactive, cur_time)) {
178  return TSvrRef();
179  }
180 
181  const TSrvSet& exclude_list = m_ExcludeMap[service];
182  vector<const char*> skip_names;
183  std::for_each(exclude_list.begin(),
184  exclude_list.end(),
185  CCharInserter(skip_names));
186  skip_names.push_back(NULL);
187 
188  SDBLB_Preference preference;
189  TSvrRef preferred_svr = m_PreferenceMap[service].second;
190  if (!preferred_svr.Empty()) {
191  preference.host = preferred_svr->GetHost();
192  preference.port = preferred_svr->GetPort();
193  preference.pref = m_PreferenceMap[service].first;
194  }
195 
196  SDBLB_ConnPoint cp;
197  char name_buff[256];
198  EDBLB_Status status;
199 
200  const char* svr_name = ::DBLB_GetServer(service.c_str(),
202  preferred_svr.Empty()
203  ? 0
204  : &preference,
205  &skip_names.front(),
206  &cp,
207  name_buff,
208  sizeof(name_buff),
209  &status);
210 
211  if (cp.time == 0) {
212  cp.time = TNCBI_Time(cur_time) + 10;
213  }
214 
215  if (svr_name && *svr_name && status != eDBLB_NoDNSEntry) {
216  return TSvrRef(new CDBServer(svr_name, cp.host, cp.port, cp.time));
217  } else if (cp.host) {
218  return TSvrRef(new CDBServer(kEmptyStr, cp.host, cp.port, cp.time));
219  }
220 
221  _TRACE("Remembering: service " << service << " is dead.");
222  m_LBEmptyMap[service] = make_pair(fSERV_IncludeInactive,
223  cur_time + m_EmptyTTL);
224  return TSvrRef();
225 }
226 
227 void
228 CDBLB_ServiceMapper::GetServersList(const string& service, list<string>* serv_list) const
229 {
230  serv_list->clear();
231  SConnNetInfo* net_info = ConnNetInfo_Create(service.c_str());
232  SERV_ITER srv_it = SERV_Open(service.c_str(),
234  0, net_info);
235  ConnNetInfo_Destroy(net_info);
236  const SSERV_Info* sinfo;
237  while ((sinfo = SERV_GetNextInfo(srv_it)) != NULL) {
238  if (sinfo->time > 0 && sinfo->time != NCBI_TIME_INFINITE) {
239  string server_name(CSocketAPI::ntoa(sinfo->host));
240  if (sinfo->port != 0) {
241  server_name.append(1, ':');
242  server_name.append(NStr::UIntToString(sinfo->port));
243  }
244  serv_list->push_back(server_name);
245  }
246  }
247  SERV_Close(srv_it);
248 }
249 
250 struct SRawOption : public CObject
251 {
253 
256  { }
257 
259  { free(sinfo); }
260 
264 };
265 
266 void
267 CDBLB_ServiceMapper::GetServerOptions(const string& service, TOptions* options)
268 {
270  options->clear();
271  time_t cur_time = time(NULL);
272  if (x_IsEmpty(service, fSERV_Promiscuous, cur_time)) {
273  return;
274  }
275 
276  const auto& preferred_svr = m_PreferenceMap.find(service);
277  if (preferred_svr != m_PreferenceMap.end()
278  && preferred_svr->second.first >= 100.0
279  && preferred_svr->second.second.NotEmpty()) {
280  TSvrRef server = x_GetServer(service),
281  requested = preferred_svr->second.second;
282  if (server.NotEmpty()
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() << '@'
289  server->GetPort()));
290  options->emplace_back
291  (new CDBServerOption(server->GetName(), server->GetHost(),
292  server->GetPort(), 1.0,
294  (TNCBI_Time) server->GetExpireTime()));
295  return;
296  }
297  }
298 
301  SConnNetInfo* net_info = ConnNetInfo_Create(service.c_str());
302  SERV_ITER srv_it = SERV_Open(service.c_str(), type, 0, net_info);
303  ConnNetInfo_Destroy(net_info);
304  // Getting final ratings involves non-trivial postprocessing based on
305  // logic from s_GetNextInfo from ncbi_lbsmd.c and s_Preference and
306  // LB_Select from ncbi_lb.c. There would be no benefit to using
307  // SERV_OpenP here; we need to account for any preference explicitly.
308  const SSERV_Info* sinfo;
309  HOST_INFO hinfo;
310  SLBSM_HostLoad load = { 0.0 };
311  double total = 0.0;
312  TOptions::iterator most_preferred = options->end();
313  TExcludeMap::const_iterator exclusions = m_ExcludeMap.find(service);
314  size_t n = 0;
315  size_t missing_hinfo = 0;
316  list<CRef<SRawOption>> raw_options;
317  while ((sinfo = SERV_GetNextInfoEx(srv_it, &hinfo)) != NULL) {
319  if (sinfo->time <= 0 || sinfo->time == NCBI_TIME_INFINITE
320  || sinfo->rate < SERV_MINIMAL_RATE) {
322  }
323  if (exclusions != m_ExcludeMap.end()) {
324  for (const auto& it : exclusions->second) {
325  if (it->GetHost() == sinfo->host
326  && (it->GetPort() == sinfo->port
327  || it->GetPort() == 0)) {
329  }
330  }
331  }
332  if (hinfo == NULL) {
333  load.status = load.statusBLAST = 0.0;
334  missing_hinfo = true;
335  } else {
336  HINFO_Status(hinfo, &load.status);
337  free(hinfo);
338  }
339  raw_options.emplace_back(new SRawOption(*sinfo, state, load));
340  ++n;
341  }
342  if (missing_hinfo > 0) {
343  SLBSM_HostLoad default_load = { 0.0 };
344  if (missing_hinfo == n) {
345  // Arbitrary, just needs to be non-zero.
346  default_load.status = default_load.statusBLAST = 1.0;
347  } else {
348  // Use the other entries' average status values.
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;
353  }
354  }
355  for (auto& it : raw_options) {
356  if (it->load.status == 0.0) {
357  it->load = default_load;
358  }
359  }
360  }
361  for (const auto& it : raw_options) {
362  string name = SERV_NameOfInfo(it->sinfo);
364  const SLBSM_HostLoad* pload = &it->load;
365  sinfo = it->sinfo;
366  double ranking = LBSM_CalculateStatus(sinfo->rate,
367  0.0 /* fine, unavailable here */,
368  (ESERV_Algo) sinfo->algo, pload);
369  bool update_most_preferred = false;
370  if (ranking > 0.0 && state == CDBServerOption::fState_Normal
371  && preferred_svr != m_PreferenceMap.end()
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)) {
378  ranking *= 1.1; // initial bonus, more adjustments next pass
379  if (most_preferred == options->end()
380  || (*most_preferred)->GetRanking() < ranking) {
381  update_most_preferred = true;
382  }
383  }
384  total += ranking;
385  _TRACE(service << ": " << name << '@'
386  << CSocketAPI::HostPortToString(sinfo->host, sinfo->port)
387  << " -- initial ranking " << ranking << ", state " << state
388  << ", expires " << CTime(sinfo->time));
389  options->emplace_back
390  (new CDBServerOption(name, sinfo->host, sinfo->port, ranking,
391  state, sinfo->time));
392  if (update_most_preferred) {
393  TOptions::reverse_iterator ri = options->rbegin();
394  most_preferred = (++ri).base();
395  }
396  }
397  SERV_Close(srv_it);
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,
402  p0;
403  if (gap >= pref) {
404  p0 = gap;
405  } else {
406  double spread = 14.0 / (double(n) + 12.0);
407  if (gap >= spread / double(n)) {
408  p0 = pref;
409  } else {
410  p0 = 2.0 / spread * gap * pref;
411  }
412  }
413  // No need to preserve the total here, so it's simplest just to
414  // adjust a single ranking (albeit with special-case logic to
415  // avoid the possibility of dividing by zero).
416  double new_ranking;
417  if (p0 == 1.0) {
418  new_ranking = numeric_limits<double>::max();
419  } else {
420  new_ranking = (total - access) * p0 / (1.0 - p0);
421  }
422  const string& name = (*most_preferred)->GetName();
423  Uint4 host = (*most_preferred)->GetHost();
424  Uint2 port = (*most_preferred)->GetPort();
425  _TRACE(service << ": " << name << '@'
426  << CSocketAPI::HostPortToString(host, port)
427  << " -- adjusting ranking to " << new_ranking);
428  most_preferred->Reset
429  (new CDBServerOption(name, host, port, new_ranking,
430  (*most_preferred)->GetState(),
431  (TNCBI_Time) (*most_preferred)->GetExpireTime()));
432 
433  }
434  if (options->empty()) {
435  _TRACE("Remembering: service " << service << " is dead.");
436  m_LBEmptyMap[service] = make_pair(fSERV_Promiscuous,
437  cur_time + m_EmptyTTL);
438  }
439 }
440 
441 void
443  const TSvrRef& preferred_server,
444  double preference)
445 {
447 
448  m_PreferenceMap[service] = make_pair(preference, preferred_server);
449 }
450 
451 
453 {
455 
456  try {
457  handle = extra.GetLowLevelHandle();
458  } catch (CException&) {
459  return false;
460  }
461  if ( !handle ) {
462  return false;
463  }
464 
465  SOCK sock = NULL;
466  try {
467  SOCK_CreateOnTopEx(&handle, sizeof(handle), &sock, NULL, 0,
469  unsigned short port = SOCK_GetRemotePort(sock, eNH_HostByteOrder);
470  unsigned int host;
472  // Could perhaps try to look name up, but this should suffice.
473  string name = CSocketAPI::HostPortToString(host, port);
474  CDBServer server(name, host, port);
475  x_RecordServer(extra, server);
476  SOCK_Close(sock);
477  return true;
478  } catch (exception&) {
479  SOCK_Close(sock);
480  // Log it?
481  return false;
482  } catch (...) {
483  SOCK_Close(sock);
484  throw;
485  }
486 }
487 
488 
491 {
492  return new CDBLB_ServiceMapper(registry);
493 }
494 
495 ///////////////////////////////////////////////////////////////////////////////
496 string
498 {
499  return "DBLB_NAME_MAPPER";
500 }
501 
502 
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.
IDBServiceMapper.
time_t GetExpireTime(void) const
Uint2 GetPort(void) const
const string & GetName(void) const
Uint4 GetHost(void) const
static string GetName(void)
CObject –.
Definition: ncbiobj.hpp:180
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
CTime –.
Definition: ncbitime.hpp:296
IDBServiceMapper.
static void x_RecordServer(I_ConnectionExtra &extra, CDBServer &server)
TExcludeMap m_ExcludeMap
list< CRef< CDBServerOption > > TOptions
IRegistry –.
Definition: ncbireg.hpp:73
I_ConnectionExtra.
virtual TSockHandle GetLowLevelHandle(void) const =0
Get OS handle of the socket represented by the connection.
void erase(iterator pos)
Definition: map.hpp:167
container_type::const_iterator const_iterator
Definition: map.hpp:53
const_iterator end() const
Definition: map.hpp:152
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: set.hpp:45
const_iterator begin() const
Definition: set.hpp:135
void erase(iterator pos)
Definition: set.hpp:151
const_iterator end() const
Definition: set.hpp:136
state()
Definition: sls_alp.cpp:1633
static CMemoryRegistry registry
Definition: cn3d_tools.cpp:81
static const char si[8][64]
Definition: des.c:146
static const struct name_t names[]
static CNcbiApplicationGuard InstanceGuard(void)
Singleton method.
Definition: ncbiapp.cpp:133
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.
Definition: ncbimisc.hpp:843
#define NULL
Definition: ncbistd.hpp:225
#define _TRACE(message)
Definition: ncbidbg.hpp:122
bool NotEmpty(void) const THROWS_NONE
Check if CRef is not empty – pointing to an object and has a non-null value.
Definition: ncbiobj.hpp:726
bool Empty(void) const THROWS_NONE
Check if CRef is empty – not pointing to any object, which means having a null value.
Definition: ncbiobj.hpp:719
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
uint16_t Uint2
2-byte (16-bit) unsigned integer
Definition: ncbitype.h:101
virtual const string & Get(const string &section, const string &name, TFlags flags=0) const
Get the parameter value.
Definition: ncbireg.cpp:262
virtual int GetInt(const string &section, const string &name, int default_value, TFlags flags=0, EErrAction err_action=eThrow) const
Get integer value of specified parameter name.
Definition: ncbireg.cpp:362
virtual void EnumerateEntries(const string &section, list< string > *entries, TFlags flags=fAllLayers) const
Enumerate parameter names for a specified section.
Definition: ncbireg.cpp:514
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define SERV_MINIMAL_RATE
SSERV_InfoCPtr SERV_GetNextInfo(SERV_ITER iter)
Same as "SERV_GetNextInfoEx(., 0)" – i.e.
Definition: ncbi_service.c:936
TNCBI_Time time
void SERV_Close(SERV_ITER iter)
Deallocate the iterator.
Definition: ncbi_service.c:993
int HINFO_Status(const HOST_INFO host_info, double status[2])
Obtain LB host availability status.
TSERV_Algo algo
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.
Definition: ncbi_service.c:809
unsigned int TSERV_Type
Bitwise OR of ESERV_Type[Special].
Definition: ncbi_service.h:94
ESERV_Algo
unsigned int host
unsigned short port
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...
Definition: ncbi_service.c:928
@ fSERV_Standalone
@ fSERV_ReverseDns
LB-DNS translation.
Definition: ncbi_service.h:84
@ fSERV_IncludeInactive
Definition: ncbi_service.h:90
@ fSERV_IncludeDown
Definition: ncbi_service.h:86
@ fSERV_Promiscuous
Evrthng and the kitchen sink.
Definition: ncbi_service.h:92
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).
Definition: ncbi_socket.c:7616
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).
Definition: ncbi_socket.c:7639
EIO_Status SOCK_Close(SOCK sock)
Close the SOCK handle, and destroy all relevant internal data.
Definition: ncbi_socket.c:6855
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,...
Definition: ncbi_socket.c:6717
@ eNH_NetworkByteOrder
Definition: ncbi_socket.h:194
@ eNH_HostByteOrder
Definition: ncbi_socket.h:193
@ fSOCK_KeepOnClose
retain OS handle in SOCK_Close[Ex]()
Definition: ncbi_socket.h:498
#define kEmptyStr
Definition: ncbistr.hpp:123
static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)
Convert string to double.
Definition: ncbistr.cpp:1387
static TNumeric StringToNumeric(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to a numeric value.
Definition: ncbistr.hpp:330
bool empty(void) const
Return true if the represented string is empty (i.e., the length is zero)
Definition: tempstr.hpp:334
static string UIntToString(unsigned int value, TNumToStringFlags flags=0, int base=10)
Convert UInt to string.
Definition: ncbistr.hpp:5108
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.
Definition: ncbistr.cpp:3550
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
Definition: ncbistr.hpp:2498
unsigned int TNCBI_Time
Definition: ncbi_types.h:145
#define NCBI_TIME_INFINITE
Definition: ncbi_types.h:147
SConnNetInfo * ConnNetInfo_Create(const char *service)
void ConnNetInfo_Destroy(SConnNetInfo *net_info)
yy_size_t n
SNetStorageObjectState< SNetStorageObjectDirectState< TBase > > TState
Definition: state.hpp:107
@ fDBLB_AllowFallbackToStandby
Definition: ncbi_dblb.h:78
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)
Definition: ncbi_dblb.c:112
EDBLB_Status
Definition: ncbi_dblb.h:67
@ eDBLB_NoDNSEntry
Definition: ncbi_dblb.h:71
CRef< CDBServer > TSvrRef
double LBSM_CalculateStatus(double rate, double fine, ESERV_Algo algo, const SLBSM_HostLoad *load)
Definition: ncbi_lbsmd.c:1457
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.
T max(T x_, T y_)
unsigned short port
Definition: ncbi_dblb.h:92
TNCBI_Time time
Definition: ncbi_dblb.h:93
unsigned int host
Definition: ncbi_dblb.h:91
unsigned short port
Definition: ncbi_dblb.h:85
unsigned int host
Definition: ncbi_dblb.h:84
double status
Definition: ncbi_lbsm.h:106
double statusBLAST
Definition: ncbi_lbsm.h:107
SSERV_Info * sinfo
SLBSM_HostLoad load
CDBServerOption::TState TState
SRawOption(const SSERV_Info &si, TState st, const SLBSM_HostLoad &l)
Definition: type.c:6
void free(voidpf ptr)
Modified on Sat Dec 02 09:23:10 2023 by modify_doxy.py rev. 669887