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

Go to the SVN repository for this file.

1 /* $Id: srv_connections.cpp 100701 2023-08-31 19:21:12Z lavr $
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  * Authors: Maxim Didenko, Dmitry Kazimirov
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
34 #include "netservice_api_impl.hpp"
35 
38 
39 #include <corelib/ncbi_system.hpp>
40 
41 #include <sstream>
42 
43 #ifdef NCBI_OS_LINUX
44 # include <sys/socket.h>
45 # include <netinet/in.h>
46 # include <netinet/tcp.h>
47 #endif
48 
49 
50 #define NCBI_USE_ERRCODE_X ConnServ_Connection
51 
52 #define END_OF_MULTILINE_OUTPUT "END"
53 
55 
56 static const STimeout s_ZeroTimeout = {0, 0};
57 
58 ///////////////////////////////////////////////////////////////////////////
60 {
61  if (!m_ReadCompletely)
63 }
64 
66 {
68 
69  if (!m_FirstLineConsumed) {
72  m_FirstLineConsumed = true;
73  } else if (!m_NetCacheCompatMode)
75  else {
76  try {
78  }
79  catch (CNetSrvConnException& e) {
81  throw;
82 
83  m_ReadCompletely = true;
84  return false;
85  }
86  }
87 
89  return true;
90  else {
91  m_ReadCompletely = true;
92  return false;
93  }
94 }
95 
97 {
98  return m_Impl->ReadLine(output);
99 }
100 
102 {
103  return [] { return new INetServerProperties; };
104 }
105 
106 void INetServerConnectionListener::OnError(const string& err_msg, CNetServer& server)
107 {
108  if (m_ErrorHandler && m_ErrorHandler(err_msg, server)) return;
109 
110  OnErrorImpl(err_msg, server);
111 }
112 
113 void INetServerConnectionListener::OnWarning(const string& warn_msg, CNetServer& server)
114 {
115  if (m_WarningHandler && m_WarningHandler(warn_msg, server)) return;
116 
117  OnWarningImpl(warn_msg, server);
118 }
119 
121 {
122  // No m_ErrorHandler/m_WarningHandler sharing
123 }
124 
126 {
127  // No m_ErrorHandler/m_WarningHandler sharing
128  return *this;
129 }
130 
132 {
133  // Event handlers are not allowed to be changed, only to be set or reset
134  _ASSERT(!(m_ErrorHandler && error_handler));
135  m_ErrorHandler = error_handler;
136 }
137 
139 {
140  // Event handlers are not allowed to be changed, only to be set or reset
141  _ASSERT(!(m_WarningHandler && warning_handler));
142  m_WarningHandler = warning_handler;
143 }
144 
146  SNetServerImpl* server) :
147  m_Server(server),
148  m_Generation(server->m_ServerInPool->m_CurrentConnectionGeneration.Get()),
149  m_NextFree(NULL)
150 {
151  if (TServConn_UserLinger2::GetDefault())
153 }
154 
156 {
157  // Return this connection to the pool.
160  TFastMutexGuard guard(
162 
163  int upper_limit = TServConn_MaxConnPoolSize::GetDefault();
164 
165  if (upper_limit == 0 || m_Server->m_ServerInPool->
166  m_FreeConnectionListSize < upper_limit) {
170  m_Server = NULL;
171  return;
172  }
173  }
174 
175  // Could not return the connection to the pool, delete it.
176  delete this;
177 }
178 
179 #define STRING_LEN(str) (sizeof(str) - 1)
180 #define WARNING_PREFIX "WARNING:"
181 #define WARNING_PREFIX_LEN STRING_LEN(WARNING_PREFIX)
182 
184  bool multiline_output)
185 {
186  switch (m_Socket.ReadLine(result))
187  {
188  case eIO_Success:
189  break;
190  case eIO_Timeout:
191  Abort();
193  "Communication timeout while reading"
194  " (timeout=" << NcbiTimeoutToMs(
195  m_Socket.GetTimeout(eIO_Read)) / 1000.0l << "s)");
196  break;
197  case eIO_Closed:
198  Abort();
199  CONNSERV_THROW_FMT(CNetSrvConnException, eConnClosedByServer, m_Server,
200  "Connection closed");
201  break;
202  default: // invalid socket or request, bailing out
203  Abort();
204  CONNSERV_THROW_FMT(CNetSrvConnException, eCommunicationError, m_Server,
205  "Communication error while reading");
206  }
207 
208  auto& conn_listener = m_Server->m_Service->m_Listener;
209 
210  if (NStr::StartsWith(result, "OK:")) {
211  const char* reply = result.c_str() + STRING_LEN("OK:");
212  size_t reply_len = result.length() - STRING_LEN("OK:");
213  while (reply_len >= WARNING_PREFIX_LEN &&
214  memcmp(reply, WARNING_PREFIX, WARNING_PREFIX_LEN) == 0) {
215  reply += WARNING_PREFIX_LEN;
216  reply_len -= WARNING_PREFIX_LEN;
217  const char* semicolon = strchr(reply, ';');
218  if (semicolon == NULL) {
219  conn_listener->OnWarning(string(reply, reply + reply_len),
220  m_Server);
221  reply_len = 0;
222  break;
223  }
224  conn_listener->OnWarning(string(reply, semicolon), m_Server);
225  reply_len -= semicolon - reply + 1;
226  reply = semicolon + 1;
227  }
228  result.erase(0, result.length() - reply_len);
229  } else if (NStr::StartsWith(result, "ERR:")) {
230  result.erase(0, STRING_LEN("ERR:"));
232  conn_listener->OnError(result, m_Server);
233  result = multiline_output ? string(END_OF_MULTILINE_OUTPUT) : kEmptyStr;
234 
235  } else if (!multiline_output) {
236  if (TServConn_ErrorOnUnexpectedReply::GetDefault()) {
237  conn_listener->OnError("Unexpected reply: " + result, m_Server);
238  } else if (TServConn_WarnOnUnexpectedReply::GetDefault()) {
239  conn_listener->OnWarning("Unexpected reply: " + result, m_Server);
240  }
241  }
242 }
243 
244 
246 {
247  m_Socket.Close();
248 }
249 
251 {
252  m_Socket.Abort();
253 }
254 
256 {
257  Close();
258 }
259 
260 void SNetServerConnectionImpl::WriteLine(const string& line)
261 {
262  // TODO change to "\n" when no old NS/NC servers remain.
263  string str(line + "\r\n");
264 
265  const char* buf = str.data();
266  size_t len = str.size();
267 
268  while (len > 0) {
269  size_t n_written;
270 
271  EIO_Status io_st = m_Socket.Write(buf, len, &n_written);
272 
273  if (io_st != eIO_Success) {
274  Abort();
275 
277  m_Server, "Failed to write: " << IO_StatusStr(io_st));
278  }
279  len -= n_written;
280  buf += n_written;
281  }
282 }
283 
284 string CNetServerConnection::Exec(const string& cmd,
285  bool multiline_output,
286  const STimeout* timeout)
287 {
288  CTimeoutKeeper timeout_keeper(&m_Impl->m_Socket, timeout);
289 
290  m_Impl->WriteLine(cmd);
291 
292  m_Impl->m_Socket.SetCork(false);
293 #ifdef NCBI_OS_LINUX
294  int fd = 0, val = 1;
295  m_Impl->m_Socket.GetOSHandle(&fd, sizeof(fd));
296  setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &val, sizeof(val));
297 #endif
298 
299  string output;
300 
301  m_Impl->ReadCmdOutputLine(output, multiline_output);
302 
303  return output;
304 }
305 
307  const CNetServer::SExecResult& exec_result) :
308  m_Impl(new SNetServerMultilineCmdOutputImpl(exec_result))
309 {
310 }
311 
312 /*************************************************************************/
314  INetServerProperties* server_properties, SThrottleParams throttle_params) :
315  m_Address(std::move(address)),
316  m_ServerProperties(server_properties),
317  m_ThrottleStats(std::move(throttle_params))
318 {
320 
323 
324  m_RankBase = 1103515245 *
325  // XOR the network prefix bytes of the IP address with the port
326  // number (in network byte order) and convert the result
327  // to host order so that it can be used in arithmetic operations.
329  12345;
330 }
331 
333 {
334  CNetServerPool server_pool(m_ServerPool);
335 
336  if (!server_pool)
337  return;
338 
339  // Before resetting the m_Service pointer, verify that no other object
340  // has acquired a reference to this server object yet (between
341  // the time the reference counter went to zero, and the
342  // current moment when m_Service is about to be reset).
343  CFastMutexGuard g(server_pool->m_ServerMutex);
344 
345  server_pool = NULL;
346 
347  if (!Referenced())
348  m_ServerPool = NULL;
349 }
350 
352 {
353  // No need to lock the mutex in the destructor.
355  while (impl != NULL) {
356  SNetServerConnectionImpl* next_impl = impl->m_NextFree;
357  delete impl;
358  impl = next_impl;
359  }
360 }
361 
362 CUrlArgs::TArgs s_GetAttributes(const string& version_string)
363 {
364  CUrlArgs::TArgs rv;
365 
366  try {
367  CUrlArgs args(version_string);
368  rv = std::move(args.GetArgs());
369  }
370  catch (CUrlParserException&) {
371  const char* version = version_string.c_str();
372  const char* prev_part_end = version;
373 
374  string attr_name, attr_value;
375 
376  for (; *version != '\0'; ++version) {
377  if ((*version == 'v' || *version == 'V') &&
378  memcmp(version + 1, "ersion", 6) == 0) {
379  const char* version_number = version + 7;
380  attr_name.assign(prev_part_end, version_number);
381  // Bring the 'v' in 'version' to lower case.
382  attr_name[attr_name.size() - 7] = 'v';
383  while (isspace(*version_number) ||
384  *version_number == ':' || *version_number == '=')
385  ++version_number;
386  const char* version_number_end = version_number;
387  while (isdigit(*version_number_end) ||
388  *version_number_end == '.')
389  ++version_number_end;
390  attr_value.assign(version_number, version_number_end);
391  rv.push_back(
392  CUrlArgs::TArg(attr_name, attr_value));
393  prev_part_end = version_number_end;
394  while (isspace(*prev_part_end) || *prev_part_end == '&')
395  ++prev_part_end;
396  } else if ((*version == 'b' || *version == 'B') &&
397  memcmp(version + 1, "uil", 3) == 0 &&
398  (version[4] == 'd' || version[4] == 't')) {
399  const char* build = version + 5;
400  attr_name.assign(version, build);
401  // Bring the 'b' in 'build' to upper case.
402  attr_name[attr_name.size() - 5] = 'B';
403  while (isspace(*build) || *build == ':' || *build == '=')
404  ++build;
405  attr_value.assign(build);
406  rv.push_back(
407  CUrlArgs::TArg(attr_name, attr_value));
408  break;
409  }
410  }
411 
412  if (prev_part_end < version) {
413  while (isspace(version[-1]))
414  if (--version == prev_part_end)
415  break;
416 
417  if (prev_part_end < version)
418  rv.push_back(CUrlArgs::TArg(
419  "Details", string(prev_part_end, version)));
420  }
421  }
422 
423  return rv;
424 }
425 
426 SNetServerInfoImpl::SNetServerInfoImpl(const string& version_string) :
427  m_Attributes(s_GetAttributes(version_string)),
428  m_NextAttribute(m_Attributes.begin())
429 {
430 }
431 
432 bool SNetServerInfoImpl::GetNextAttribute(string& attr_name, string& attr_value)
433 {
434  if (m_NextAttribute == m_Attributes.end())
435  return false;
436 
437  attr_name = m_NextAttribute->name;
438  attr_value = m_NextAttribute->value;
439  ++m_NextAttribute;
440  return true;
441 }
442 
443 bool CNetServerInfo::GetNextAttribute(string& attr_name, string& attr_value)
444 {
445  return m_Impl->GetNextAttribute(attr_name, attr_value);
446 }
447 
449 {
450  return m_Impl->m_ServerInPool->m_Address;
451 }
452 
453 
455 {
456  for (;;) {
458 
459  if (m_FreeConnectionListSize == 0)
460  return NULL;
461 
462  // Get an existing connection object from the connection pool.
464 
465  m_FreeConnectionListHead = conn->m_NextFree;
467  conn->m_Server = server;
468 
469  guard.Release();
470 
471  // Check if the socket is already connected.
472  if (conn->m_Socket.GetStatus(eIO_Open) != eIO_Success ||
473  conn->m_Generation !=
475  continue;
476 
477  SSOCK_Poll conn_socket_poll_struct = {
478  /* sock */ conn->m_Socket.GetSOCK(),
479  /* event */ eIO_ReadWrite
480  /* revent */ // [out]
481  };
482 
483  if (SOCK_Poll(1, &conn_socket_poll_struct, &s_ZeroTimeout, NULL) ==
484  eIO_Success && conn_socket_poll_struct.revent == eIO_Write)
485  return conn;
486 
487  conn->m_Socket.Close();
488  }
489 }
490 
492 {
493  SConnectDeadline(const STimeout& conn_timeout) :
494  try_timeout(Min(conn_timeout , kMaxTryTimeout)),
495  total_timeout(conn_timeout.sec, conn_timeout.usec),
497  {}
498 
499  const STimeout* GetRemaining() const { return &try_timeout; }
500 
501  bool IsExpired()
502  {
504 
505  if (remaining.IsZero()) return true;
506 
507  remaining.Get(&try_timeout.sec, &try_timeout.usec);
509  return false;
510  }
511 
512  CTimeout GetTotal() const { return total_timeout; }
513 
514 private:
515  static STimeout Min(const STimeout& t1, const STimeout& t2)
516  {
517  if (t1.sec < t2.sec) return t1;
518  if (t1.sec > t2.sec) return t2;
519  if (t1.usec < t2.usec) return t1;
520  return t2;
521  }
522 
526 
527  static const STimeout kMaxTryTimeout;
528 };
529 
530 #ifndef NCBI_OS_MSWIN
532 #else
534 #endif
535 
537 {
539 
540  SNetServerImpl::SConnectDeadline deadline(timeout ? *timeout : m_ServerPool->m_ConnTimeout);
541  auto& socket = conn->m_Socket;
542 
544 
545  socket.SetDataLogging(TServConn_ConnDataLogging::GetDefault() ? eOn : eOff);
546  socket.SetTimeout(eIO_ReadWrite, timeout ? timeout :
548  socket.DisableOSSendDelay();
549  socket.SetReuseAddress(eOn);
550 
552 
553  if (timeout) socket.SetTimeout(eIO_ReadWrite, &m_ServerPool->m_CommTimeout);
554 
555  return conn;
556 }
557 
559  const SSocketAddress& actual, const SSocketAddress& original)
560 {
561  EIO_Status io_st;
562 
563  do {
564  io_st = socket.Connect(CSocketAPI::ntoa(actual.host), actual.port,
566 
567  } while (io_st == eIO_Timeout && !deadline.IsExpired());
568 
569  if (io_st == eIO_Success) return;
570 
571  socket.Close();
572 
573  ostringstream os;
574  os << original.AsString() << ": Could not connect: " << IO_StatusStr(io_st);
575 
576  if (io_st == eIO_Timeout) os << " (" << deadline.GetTotal().GetAsDouble() << "s)";
577 
578  NCBI_THROW(CNetSrvConnException, eConnectionFailure, os.str());
579 }
580 
582  const STimeout* timeout)
583 {
585 
586  // Silently reconnect if the connection was taken
587  // from the pool and it was closed by the server
588  // due to inactivity.
589  while ((conn = GetConnectionFromPool(server)) != NULL) {
590  try {
591  handler.Exec(conn, timeout);
592  return;
593  }
594  catch (CNetSrvConnException& e) {
595  CException::TErrCode err_code = e.GetErrCode();
596  if (err_code != CNetSrvConnException::eWriteFailure &&
598  {
599  throw;
600  }
601  }
602  }
603 
604  handler.Exec(Connect(server, timeout), timeout);
605 }
606 
608 {
609  auto& server_in_pool = *m_ServerInPool;
610  auto& throttle_stats = server_in_pool.m_ThrottleStats;
611 
612  throttle_stats.Check(this);
613 
614  try {
615  server_in_pool.TryExec(this, handler, timeout);
616  }
617  catch (CNetSrvConnException& e) {
618  throttle_stats.Adjust(this, e.GetErrCode());
619  throw;
620  }
621 
622  throttle_stats.Adjust(this, -1); // Success
623 }
624 
626 {
627 public:
628  CNetServerExecHandler(const string& cmd,
629  bool multiline_output,
630  CNetServer::SExecResult& exec_result,
631  INetServerExecListener* exec_listener) :
632  m_Cmd(cmd),
633  m_MultilineOutput(multiline_output),
634  m_ExecResult(exec_result),
635  m_ExecListener(exec_listener)
636  {
637  }
638 
639  virtual void Exec(CNetServerConnection::TInstance conn_impl,
640  const STimeout* timeout);
641 
642  string m_Cmd;
646 };
647 
649  const STimeout* timeout)
650 {
651  m_ExecResult.conn = conn_impl;
652 
653  if (m_ExecListener != NULL)
655 
658  timeout);
659 }
660 
662  bool multiline_output,
663  CNetServer::SExecResult& exec_result, const STimeout* timeout,
664  INetServerExecListener* exec_listener)
665 {
666  CNetServerExecHandler exec_handler(cmd, multiline_output,
667  exec_result, exec_listener);
668 
669  TryExec(exec_handler, timeout);
670 }
671 
672 void SThrottleStats::Adjust(SNetServerImpl* server_impl, int err_code)
673 {
674  _ASSERT(server_impl);
675 
676  if (m_Params.throttle_period <= 0)
677  return;
678 
679  const auto op_result = err_code >= 0; // True, if failure
680 
681  if (op_result && m_Params.connect_failures_only &&
682  (err_code != CNetSrvConnException::eConnectionFailure)) return;
683 
685  const auto& address = server_impl->m_ServerInPool->m_Address;
686 
688  if (!op_result)
690 
692  m_Throttled = true;
693  m_ThrottleMessage = "Server " + address.AsString() +
694  " reached the maximum number of connection failures in a row";
695  }
696  }
697 
699  auto& reg = m_IOFailureRegister.first;
700  auto& index = m_IOFailureRegister.second;
701 
702  if (reg[index] != op_result) {
703  reg[index] = op_result;
704 
705  if (op_result && (reg.count() >= m_Params.io_failure_threshold.numerator)) {
706  m_Throttled = true;
707  m_ThrottleMessage = "Connection to server " + address.AsString() +
708  " aborted as it was considered bad/overloaded";
709  }
710  }
711 
712  if (++index >= m_Params.io_failure_threshold.denominator) index = 0;
713  }
714 
715  if (m_Throttled) {
718  CNetServer server(server_impl);
719  server_impl->m_Service->m_Listener->OnWarning(m_ThrottleMessage, server);
722  }
723 }
724 
726 {
727  _ASSERT(server_impl);
728 
729  if (m_Params.throttle_period <= 0)
730  return;
731 
733 
734  if (m_Throttled) {
735  CTime current_time(GetFastLocalTime());
736  auto duration = current_time - m_ThrottledUntil;
737 
738  if ((duration >= CTimeSpan(0, 0)) &&
741  Reset();
742  const auto& address = server_impl->m_ServerInPool->m_Address;
743  ostringstream os;
744  os << "Disabling throttling for server " << address.AsString() <<
745  " before new attempt after " << duration.AsString() << " seconds wait" <<
746  (m_Params.throttle_until_discoverable ? " and rediscovery" : "");
747  CNetServer server(server_impl);
748  server_impl->m_Service->m_Listener->OnWarning(os.str(), server);
749  return;
750  }
752  }
753 }
754 
756 {
758  m_IOFailureRegister.first.reset();
759  m_IOFailureRegister.second = 0;
760  m_Throttled = false;
761 }
762 
764 {
767 }
768 
770  bool multiline_output, bool retry_on_exception)
771 {
772  CNetServer::SExecResult exec_result;
773 
774  const CTimeout& max_total_time = m_ServerInPool->m_ServerPool->m_MaxTotalTime;
775  CDeadline deadline(max_total_time);
776 
777  unsigned attempt = 0;
778 
779  const auto max_retries = retry_on_exception ? m_Service->GetConnectionMaxRetries() : 0;
780 
781  for (;;) {
782  string warning;
783 
784  try {
785  ConnectAndExec(cmd, multiline_output, exec_result);
786  return exec_result;
787  }
788  catch (CNetSrvConnException& e) {
789  if (++attempt > max_retries ||
791  throw;
792 
793  if (deadline.IsExpired()) {
794  ERR_POST("Timeout (max_connection_time=" <<
795  max_total_time.GetAsMilliSeconds() << "); cmd=" << cmd << "; exception=" << e.GetMsg());
796  throw;
797  }
798 
799  warning = e.GetMsg();
800  }
801  catch (CNetScheduleException& e) {
802  if (++attempt > max_retries ||
804  throw;
805 
806  if (deadline.IsExpired()) {
807  ERR_POST("Timeout (max_connection_time=" <<
808  max_total_time.GetAsMilliSeconds() << "); cmd=" << cmd << "; exception=" << e.GetMsg());
809  throw;
810  }
811 
812  warning = e.GetMsg();
813  }
814 
815  warning += ", reconnecting: attempt ";
816  warning += NStr::NumericToString(attempt);
817  warning += " of ";
818  warning += NStr::NumericToString(max_retries);
819 
820  CNetServer server(this);
821  m_Service->m_Listener->OnWarning(warning, server);
822 
824  }
825 }
826 
827 CNetServer::SExecResult CNetServer::ExecWithRetry(const string& cmd, bool multiline_output)
828 {
829  return m_Impl->ConnectAndExec(cmd, multiline_output, true);
830 }
831 
833 {
834  string cmd("VERSION");
836  auto response = ExecWithRetry(cmd, false).response;
837 
838  // Keep these two lines separate to let the Exec method
839  // above succeed before constructing the object below.
840 
841  return new SNetServerInfoImpl(response);
842 }
843 
844 CNetServerInfo g_ServerInfoFromString(const string& server_info)
845 {
846  return new SNetServerInfoImpl(server_info);
847 }
848 
850 {
851  throttle_period = registry.Get(sections, "throttle_relaxation_period", 0);
852 
853  if (throttle_period <= 0) return;
854 
856  { "throttle_by_consecutive_connection_failures", "throttle_by_subsequent_connection_failures" }, 0);
857 
858  throttle_until_discoverable = registry.Get(sections, "throttle_hold_until_active_in_lb", false);
859  connect_failures_only = registry.Get(sections, "throttle_connect_failures_only", false);
860 
862 }
863 
865 {
866  // These values must correspond to each other
867  const string error_rate = registry.Get(sections, "throttle_by_connection_error_rate", kEmptyStr);
868 
869  if (error_rate.empty()) return;
870 
871  string numerator_str, denominator_str;
872 
873  if (!NStr::SplitInTwo(error_rate, "/", numerator_str, denominator_str)) return;
874 
876 
877  int n = NStr::StringToInt(numerator_str, flags);
878  int d = NStr::StringToInt(denominator_str, flags);
879 
880  if (n > 0) numerator = static_cast<size_t>(n);
881  if (d > 1) denominator = static_cast<size_t>(d);
882 
886  }
887 }
888 
CDeadline.
Definition: ncbitime.hpp:1830
void Release()
Manually force the resource to be released.
Definition: guard.hpp:166
CNanoTimeout – Timeout interval, using nanoseconds.
Definition: ncbitime.hpp:1810
NetSchedule internal exception.
CNetRef< SNetServerConnectionImpl > m_Impl
string Exec(const string &cmd, bool multiline_output=false, const STimeout *timeout=NULL)
Execute remote command 'cmd', wait for the reply, check that it starts with 'OK:',...
CNetServerExecHandler(const string &cmd, bool multiline_output, CNetServer::SExecResult &exec_result, INetServerExecListener *exec_listener)
INetServerExecListener * m_ExecListener
CNetServer::SExecResult & m_ExecResult
virtual void Exec(CNetServerConnection::TInstance conn_impl, const STimeout *timeout)
CNetRef< SNetServerInfoImpl > m_Impl
bool GetNextAttribute(string &attr_name, string &attr_value)
Return the next attribute.
bool ReadLine(string &output)
CNetRef< SNetServerMultilineCmdOutputImpl > m_Impl
const SSocketAddress & GetAddress() const
CNetRef< SNetServerImpl > m_Impl
CNetServerInfo GetServerInfo()
Retrieve basic information about the server as attribute name-value pairs.
SExecResult ExecWithRetry(const string &cmd, bool multiline_output=false)
Execute remote command 'cmd', wait for the reply, check if it starts with 'OK:', and return the remai...
Net Service exception.
CSocket::
CTimeSpan.
Definition: ncbitime.hpp:1313
CTime –.
Definition: ncbitime.hpp:296
CTimeout – Timeout interval.
Definition: ncbitime.hpp:1693
CUrlArgs::
Definition: ncbi_url.hpp:240
CUrlParserException –.
Definition: ncbi_url.hpp:539
virtual void OnExec(CNetServerConnection::TInstance conn_impl, const string &cmd)=0
static CMemoryRegistry registry
Definition: cn3d_tools.cpp:81
void(*)(CSeq_entry_Handle seh, IWorkbench *wb, const CSerialObject &obj) handler
static uch flags
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
static SQLCHAR output[256]
Definition: print.c:5
static const char * str(char *buf, int n)
Definition: stats.c:84
@ eOn
Definition: ncbi_types.h:111
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
void Set(TValue new_value) THROWS_NONE
Set atomic counter value.
Definition: ncbicntr.hpp:185
TValue Get(void) const THROWS_NONE
Get atomic counter value.
Definition: ncbicntr.hpp:168
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
TErrCode GetErrCode(void) const
Get error code.
Definition: ncbiexpt.cpp:453
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
int TErrCode
Definition: ncbiexpt.hpp:889
bool Referenced(void) const THROWS_NONE
Check if object is referenced.
Definition: ncbiobj.hpp:468
virtual const string & Get(const string &section, const string &name, TFlags flags=0) const
Get the parameter value.
Definition: ncbireg.cpp:262
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
EIO_Status Connect(const string &host, unsigned short port, const STimeout *timeout=kDefaultTimeout, TSOCK_Flags flags=fSOCK_LogDefault)
Connect to "host:port".
EIO_Status Close(void)
Close socket.
static unsigned short HostToNetShort(unsigned short value)
EIO_Status ReadLine(string &str)
Read a line from socket (up to CR-LF, LF, or null character, discarding any of the EOLs).
const STimeout * GetTimeout(EIO_Event event) const
Get timeout for I/O in the specified direction.
static string ntoa(unsigned int host)
BSD-like API. NB: when int, "host" must be in network byte order.
EIO_Status SetTimeout(EIO_Event event, const STimeout *timeout)
Set timeout for I/O in the specified direction.
EIO_Status Abort(void)
Abort socket connection.
static unsigned int NetToHostLong(unsigned int value)
EIO_Status GetStatus(EIO_Event direction) const
Return status of *last* I/O operation without making any actual I/O.
EIO_Status SOCK_Poll(size_t n, SSOCK_Poll polls[], const STimeout *timeout, size_t *n_ready)
Block until at least one of the sockets enlisted in "polls" array (of size "n") becomes available for...
Definition: ncbi_socket.c:7083
EIO_Event revent
[in] one of: eIO_Open/Read/Write/ReadWrite
Definition: ncbi_socket.h:969
EIO_Status Write(const void *buf, size_t size, size_t *n_written=0, EIO_WriteMethod how=eIO_WritePersist)
Write to socket.
@ fSOCK_KeepAlive
keep socket alive (if supported by OS)
Definition: ncbi_socket.h:492
@ fSOCK_LogOff
NB: logging is inherited in accepted SOCK.
Definition: ncbi_socket.h:489
#define kEmptyStr
Definition: ncbistr.hpp:123
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
static string ParseEscapes(const CTempString str, EEscSeqRange mode=eEscSeqRange_Standard, char user_char='?')
Parse C-style escape sequences in the specified string.
Definition: ncbistr.cpp:4793
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5412
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:3554
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
@ fAllowTrailingSpaces
Ignore trailing space characters.
Definition: ncbistr.hpp:297
@ fConvErr_NoThrow
Do not throw an exception on error.
Definition: ncbistr.hpp:285
@ fAllowLeadingSpaces
Ignore leading spaces in converted string.
Definition: ncbistr.hpp:294
CNanoTimeout GetRemainingTime(void) const
Get time left to the expiration.
Definition: ncbitime.cpp:3859
CTime & AddSecond(TSeconds seconds=1, EDaylight adl=eDaylightDefault)
Add specified seconds.
Definition: ncbitime.cpp:1880
bool IsExpired(void) const
Check if the deadline is expired.
Definition: ncbitime.hpp:1855
string AsString(const CTimeFormat &format=kEmptyStr, TSeconds out_tz=eCurrentTimeZone) const
Transform time to string.
Definition: ncbitime.cpp:1512
double GetAsDouble(void) const
Get as number of seconds (fractional value).
Definition: ncbitime.cpp:3512
CTime & SetCurrent(void)
Make the time current in the presently active time zone.
Definition: ncbitime.hpp:2301
bool IsZero() const
Definition: ncbitime.cpp:3476
unsigned long GetAsMilliSeconds(void) const
Get as number of milliseconds.
Definition: ncbitime.cpp:3490
CTime GetFastLocalTime(void)
Quick and dirty getter of local time.
Definition: ncbitime.cpp:4167
void Get(unsigned int *sec, unsigned int *microsec) const
Get timeout in seconds and microseconds.
Definition: ncbitime.cpp:3545
const TArgs & GetArgs(void) const
Get the const list of arguments.
Definition: ncbi_url.hpp:300
list< TArg > TArgs
Definition: ncbi_url.hpp:276
unsigned long NcbiTimeoutToMs(const STimeout *timeout)
Definition: ncbi_types.c:40
EIO_Status
I/O status.
Definition: ncbi_core.h:132
unsigned int usec
microseconds (modulo 1,000,000)
Definition: ncbi_types.h:78
const char * IO_StatusStr(EIO_Status status)
Get the text form of an enum status value.
Definition: ncbi_core.c:56
unsigned int sec
seconds
Definition: ncbi_types.h:77
@ eIO_Timeout
timeout expired before any I/O succeeded
Definition: ncbi_core.h:134
@ eIO_Success
everything is fine, no error occurred
Definition: ncbi_core.h:133
@ eIO_Write
write
Definition: ncbi_core.h:121
@ eIO_ReadWrite
eIO_Read | eIO_Write (also, eCONN_OnFlush)
Definition: ncbi_core.h:122
@ eIO_Open
also serves as no-event indicator in SOCK_Poll
Definition: ncbi_core.h:119
@ eIO_Close
also serves as an error indicator in SOCK_Poll
Definition: ncbi_core.h:123
@ eIO_Read
read
Definition: ncbi_core.h:120
Definition of all error codes used in connect services library (xconnserv.lib and others).
char * buf
yy_size_t n
int len
static int version
Definition: mdb_load.c:29
const TYPE & Get(const CNamedParameterList *param)
chrono::system_clock::duration duration
void SleepMilliSec(unsigned long ml_sec, EInterruptOnSignal onsignal=eRestartOnSignal)
int isspace(Uchar c)
Definition: ncbictype.hpp:69
int isdigit(Uchar c)
Definition: ncbictype.hpp:64
void g_AppendClientIPSessionIDHitID(string &cmd)
#define CONNSERV_THROW_FMT(exception_class, err_code, server, message)
CUrlArgs::TArgs s_GetAttributes(const string &version_string)
#define END_OF_MULTILINE_OUTPUT
#define WARNING_PREFIX
#define STRING_LEN(str)
#define WARNING_PREFIX_LEN
static const STimeout s_ZeroTimeout
CNetServerInfo g_ServerInfoFromString(const string &server_info)
CNetServerConnection conn
Name-value pair.
Definition: ncbi_url.hpp:269
void OnError(const string &err_msg, CNetServer &server)
void SetErrorHandler(TEventHandler error_handler)
INetServerConnectionListener & operator=(const INetServerConnectionListener &)
virtual TPropCreator GetPropCreator() const
function< INetServerProperties *()> TPropCreator
virtual void OnErrorImpl(const string &err_msg, CNetServer &server)=0
CNetService::TEventHandler TEventHandler
virtual void OnConnected(CNetServerConnection &connection)=0
virtual void OnWarningImpl(const string &warn_msg, CNetServer &server)=0
void SetWarningHandler(TEventHandler warning_handler)
void OnWarning(const string &warn_msg, CNetServer &server)
SNetServerConnectionImpl(SNetServerImpl *pool)
SNetServerConnectionImpl * m_NextFree
CAtomicCounter::TValue m_Generation
void ReadCmdOutputLine(string &result, bool multiline_output)
void WriteLine(const string &line)
virtual void DeleteThis()
Virtual method "deleting" this object.
static const STimeout kMaxTryTimeout
SConnectDeadline(const STimeout &conn_timeout)
static STimeout Min(const STimeout &t1, const STimeout &t2)
const STimeout * GetRemaining() const
CRef< SNetServerInPool > m_ServerInPool
static void ConnectImpl(CSocket &, SConnectDeadline &, const SSocketAddress &, const SSocketAddress &)
void TryExec(INetServerExecHandler &handler, const STimeout *timeout=NULL)
CNetServer::SExecResult ConnectAndExec(const string &cmd, bool multiline_output, bool retry_on_exception=false)
SNetServerInPool(SSocketAddress address, INetServerProperties *server_properties, SThrottleParams throttle_params)
virtual ~SNetServerInPool()
void TryExec(SNetServerImpl *server, INetServerExecHandler &handler, const STimeout *timeout)
SNetServerConnectionImpl * m_FreeConnectionListHead
CNetServerPool m_ServerPool
virtual void DeleteThis()
Virtual method "deleting" this object.
CNetServerConnection GetConnectionFromPool(SNetServerImpl *server)
CAtomicCounter m_CurrentConnectionGeneration
CFastMutex m_FreeConnectionListLock
CNetServerConnection Connect(SNetServerImpl *server, const STimeout *timeout)
bool GetNextAttribute(string &attr_name, string &attr_value)
SNetServerInfoImpl(const string &version_string)
TAttributes::const_iterator m_NextAttribute
CRef< INetServerConnectionListener > m_Listener
unsigned GetConnectionMaxRetries() const
unsigned long GetConnectionRetryDelay() const
static void ConnectXSite(CSocket &, SNetServerImpl::SConnectDeadline &, const SSocketAddress &, const string &)
I/O polling structure.
Definition: ncbi_socket.h:966
unsigned short port
string AsString() const
void Init(CSynRegistry &registry, const SRegSynonyms &sections)
struct SThrottleParams::SIOFailureThreshold io_failure_threshold
void Init(CSynRegistry &registry, const SRegSynonyms &sections)
void Check(SNetServerImpl *server_impl)
const SThrottleParams m_Params
void Adjust(SNetServerImpl *server_impl, int err_code)
pair< bitset< SThrottleParams::SIOFailureThreshold::kMaxDenominator >, size_t > m_IOFailureRegister
Timeout structure.
Definition: ncbi_types.h:76
#define _ASSERT
int g(Seg_Gsm *spe, Seq_Mtf *psm, Thd_Gsm *tdg)
Definition: thrddgri.c:44
else result
Definition: token2.c:20
Modified on Fri May 24 14:57:20 2024 by modify_doxy.py rev. 669887