void LimitlessRouterMonitor::Open()

in src/limitless/limitless_router_monitor.cc [39:87]


void LimitlessRouterMonitor::Open(
    bool block_and_query_immediately,
    const SQLTCHAR *connection_string_c_str,
    int host_port,
    unsigned int interval_ms,
    std::shared_ptr<std::vector<HostInfo>>& limitless_routers,
    std::shared_ptr<std::mutex>& limitless_routers_mutex
) {
    this->interval_ms = interval_ms;
    this->limitless_routers = limitless_routers;
    this->limitless_routers_mutex = limitless_routers_mutex;

    SQLHENV henv = SQL_NULL_HANDLE;
    SQLHDBC conn = SQL_NULL_HANDLE;

    this->connection_string = StringHelper::ToSQLSTR(connection_string_c_str);

    // disable limitless for the monitor
    RDSREGEX limitless_enabled_pattern(LIMITLESS_ENABLED_KEY TEXT("=") BOOL_TRUE);
    SQLSTR limitless_disabled = LIMITLESS_ENABLED_KEY TEXT("=") BOOL_FALSE;
    this->connection_string = std::regex_replace(this->connection_string, limitless_enabled_pattern, limitless_disabled);

    SQLRETURN rc = SQLAllocHandle(SQL_HANDLE_ENV, nullptr, &henv);
    if (!OdbcHelper::CheckResult(rc, "LimitlessRouterMonitor: SQLAllocHandle failed", henv, SQL_HANDLE_ENV)) {
        return; // fatal error; don't open thread
    }

    SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>(SQL_OV_ODBC3), 0);

    if (block_and_query_immediately) {
        rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &conn);
        if (!OdbcHelper::CheckResult(rc, "LimitlessRouterMonitor: SQLAllocHandle failed", conn, SQL_HANDLE_DBC)) {
            OdbcHelper::Cleanup(henv, conn, SQL_NULL_HSTMT);
            return; // fatal error; don't open thread
        }

        rc = SQLDriverConnect(conn, nullptr, AS_SQLTCHAR(this->connection_string.c_str()), SQL_NTS, nullptr, 0, nullptr, SQL_DRIVER_NOPROMPT);
        if (SQL_SUCCEEDED(rc)) {
            // initial connection was successful, immediately populate caller's limitless routers
            *limitless_routers = LimitlessQueryHelper::QueryForLimitlessRouters(conn, host_port);
        } else {
            // not successful, ensure limitless routers is empty 
            limitless_routers->clear();
        }
    }

    // start monitoring thread; if block_and_query_immediately is false, then conn is SQL_NULL_HANDLE, and the thread will connect after the monitor interval has passed
    this->monitor_thread = std::make_shared<std::thread>(&LimitlessRouterMonitor::Run, this, henv, conn, reinterpret_cast<SQLTCHAR *>(this->connection_string.data()), SQL_NTS, host_port);
}