Esempio n. 1
0
CDBConnectionFactory::CRuntimeData&
CDBConnectionFactory::GetRuntimeData(const CRef<IConnValidator> validator)
{
    string validator_name;
    if (validator) {
        validator_name = validator->GetName();
    }
    return GetRuntimeData(validator_name);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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()) {
Esempio n. 4
0
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;
}