CDBConnectionFactory::CRuntimeData& CDBConnectionFactory::GetRuntimeData(const CRef<IConnValidator> validator) { string validator_name; if (validator) { validator_name = validator->GetName(); } return GetRuntimeData(validator_name); }
static bool resolveAddr(part_t* pPart, void* addr) { if (!between((word_t)addr, 0x02000000, 0x03000000)) return false; addr = memCached(addr); if ((word_t)addr < (word_t)__end__) { pPart->name = "(kernel)"; pPart->module = NULL; pPart->offset = (word_t)addr; return true; } module_t module = LdrResolveAddr(addr); if (!module) return false; pPart->name = GetRuntimeData(module)->name; pPart->module = module; pPart->offset = addr - module; return true; }
CDB_Connection* CDBConnectionFactory::DispatchServerName( SOpeningContext& ctx, const CDBConnParams& params) { CDB_Connection* t_con = NULL; // I_DriverContext::SConnAttr curr_conn_attr(conn_attr); const string service_name(params.GetServerName()); bool do_not_dispatch = params.GetParam("do_not_dispatch") == "true"; string cur_srv_name; Uint4 cur_host = 0; Uint2 cur_port = 0; CRuntimeData& rt_data = GetRuntimeData(params.GetConnValidator()); // Try to connect up to a given number of alternative servers ... unsigned int alternatives = GetMaxNumOfServerAlternatives(); list<TSvrRef> tried_servers; bool full_retry_made = false; for ( ; !t_con && alternatives > 0; --alternatives ) { TSvrRef dsp_srv; if (do_not_dispatch) { cur_srv_name = params.GetServerName(); cur_host = params.GetHost(); cur_port = params.GetPort(); } // It is possible that a server name won't be provided. // This is possible when somebody uses a named connection pool. // In this case we even won't try to map it. else if (!service_name.empty()) { dsp_srv = rt_data.GetDBServiceMapper().GetServer(service_name); if (dsp_srv.Empty() && tried_servers.empty()) { _TRACE("List of servers for service " << service_name << " is exhausted. Giving excluded a try."); rt_data.CleanExcluded(service_name); dsp_srv = rt_data.GetDBServiceMapper().GetServer(service_name); } if (dsp_srv.Empty()) { m_Errors.push_back(new CDB_Exception(DIAG_COMPILE_INFO, NULL, CDB_Exception::EErrCode(0), "Service mapper didn't return any server for " + service_name, eDiag_Error, 0)); return NULL; } if (dsp_srv->GetName() == service_name && dsp_srv->GetHost() == 0 && dsp_srv->GetPort() == 0 && !tried_servers.empty()) { if (full_retry_made) { if (!m_TryServerToo) { m_Errors.push_back(new CDB_Exception(DIAG_COMPILE_INFO, NULL, CDB_Exception::EErrCode(0), "No more servers to try (didn't try " + service_name + " as server name)", eDiag_Error, 0)); return NULL; } } else { _TRACE("List of servers for service " << service_name << " is exhausted. Giving excluded a try."); rt_data.CleanExcluded(service_name); ITERATE(list<TSvrRef>, it, tried_servers) { rt_data.Exclude(service_name, *it); } full_retry_made = true; continue; } } // If connection attempts will take too long mapper can return // the same server once more. Let's not try to connect to it // again. bool found = false; ITERATE(list<TSvrRef>, it, tried_servers) { if (**it == *dsp_srv) { rt_data.Exclude(service_name, dsp_srv); found = true; break; } } if (found) continue; // curr_conn_attr.srv_name = dsp_srv->GetName(); cur_srv_name = dsp_srv->GetName(); cur_host = dsp_srv->GetHost(); cur_port = dsp_srv->GetPort(); } else if (params.GetParam("pool_name").empty()) {
CDB_Connection* CDBConnectionFactory::MakeDBConnection( I_DriverContext& ctx, const CDBConnParams& params) { CFastMutexGuard mg(m_Mtx); CDB_UserHandler::ClearExceptions(m_Errors); CDB_Connection* t_con = NULL; CRuntimeData& rt_data = GetRuntimeData(params.GetConnValidator()); TSvrRef dsp_srv = rt_data.GetDispatchedServer(params.GetServerName()); // Prepare to collect messages, whose proper severity depends on whether // ANY attempt succeeds. impl::CDBHandlerStack ultimate_handlers; {{ const impl::CDriverContext* ctx_impl = dynamic_cast<impl::CDriverContext*>(&ctx); if (params.GetOpeningMsgHandlers().GetSize() > 0) { ultimate_handlers = params.GetOpeningMsgHandlers(); } else if (ctx_impl != NULL) { ultimate_handlers = ctx_impl->GetCtxHandlerStack(); } else { ultimate_handlers.Push(&CDB_UserHandler::GetDefault()); } }} SOpeningContext opening_ctx(ctx); CRef<CDB_UserHandler_Deferred> handler (new CDB_UserHandler_Deferred(ultimate_handlers)); opening_ctx.handlers.Push(&*handler, eTakeOwnership); // Store original query timeout ... unsigned int query_timeout = ctx.GetTimeout(); // Set "validation timeouts" ... ctx.SetTimeout(CalculateConnectionTimeout(ctx)); ctx.SetLoginTimeout(CalculateLoginTimeout(ctx)); if ( dsp_srv.Empty() ) { // We are here either because server name was never dispatched or // because a named connection pool has been used before. // Dispatch server name ... t_con = DispatchServerName(opening_ctx, params); } else { // Server name is already dispatched ... string single_server(params.GetParam("single_server")); // We probably need to re-dispatch it ... if (single_server != "true" && GetMaxNumOfDispatches() && rt_data.GetNumOfDispatches(params.GetServerName()) >= GetMaxNumOfDispatches()) { // We definitely need to re-dispatch it ... // Clean previous info ... rt_data.SetDispatchedServer(params.GetServerName(), TSvrRef()); t_con = DispatchServerName(opening_ctx, params); } else { // We do not need to re-dispatch it ... // Try to connect. try { // I_DriverContext::SConnAttr cur_conn_attr(conn_attr); // cur_conn_attr.srv_name = dsp_srv->GetName(); CDB_DBLB_Delegate cur_params( dsp_srv->GetName(), dsp_srv->GetHost(), dsp_srv->GetPort(), params); cur_params.SetOpeningMsgHandlers() = opening_ctx.handlers; // MakeValidConnection may return NULL here because a newly // created connection may not pass validation. t_con = MakeValidConnection(opening_ctx, // cur_conn_attr, cur_params); } catch (CDB_Exception& ex) { // m_Errors.push_back(ex.Clone()); opening_ctx.handlers.PostMsg(&ex); if (params.GetConnValidator()) { opening_ctx.conn_status = params.GetConnValidator()->ValidateException(ex); } } if (!t_con) { // We couldn't connect ... if (single_server != "true") { // Server might be temporarily unavailable ... // Check conn_status ... if (opening_ctx.conn_status == IConnValidator::eTempInvalidConn) { rt_data.IncNumOfValidationFailures(params.GetServerName(), dsp_srv); } // Re-dispatch ... t_con = DispatchServerName(opening_ctx, params); } } else { // Dispatched server is already set, but calling of this method // will increase number of successful dispatches. rt_data.SetDispatchedServer(params.GetServerName(), dsp_srv); } } } // Restore original connection timeout ... ctx.SetTimeout(query_timeout); // Restore original query timeout ... if (t_con) { t_con->SetTimeout(query_timeout); } x_LogConnection(opening_ctx, t_con, params); handler->Flush((t_con == NULL) ? eDiagSevMax : eDiag_Warning); return t_con; }