Lucee / ColdFusion - блокировка области сеанса в кластере и одновременный доступ к переменным сеанса - PullRequest
4 голосов
/ 20 марта 2019

Этот вопрос относится к приложению Lucee 5.x.Я не уверен, есть ли различия между тем, как ACF и Lucee обрабатывают области сеансов в кластере.

Справочная информация: Я реализую функцию autoLogin() в application.cfc - в onRequestStart() - он ищет токен, который хранится в куки, а затем использует его для аутентификации пользователя.Как только токен используется, он заменяется новым значением, а cookie обновляется.Если токен не найден или не работает, cookie удаляется.Блокировка сеанса используется для предотвращения попыток входа пользователя в систему из нескольких одновременных запросов, что может привести к непреднамеренным побочным эффектам.

Все основные функции для этого работают (на одном узле), но мне нужно сделать этокластер удобно.Кластер уже настроен правильно (this.sessionCluster = true; в application.cfc вместе с общим экземпляром Memcached, который хранит данные сеанса), и он работает нормально.

Основные вопросы, которые у меня есть: (ссылка на код ниже)

  1. В приведенном ниже коде используется эксклюзивная блокировка сеанса для предотвращения одновременного выполнения кода входа в систему одновременными запросами. Как бы вы заменили приведенную ниже блокировку сеанса на такую, которая блокирует сеанс по всему кластеру?

  2. В приведенном ниже коде предполагается, что изменения переменных сеанса можно увидеть сразу, Верно ли это, когда переменная сеанса изменяется на одном узле, а затем параллельный запрос на другом узле пытается получить доступ к этой же переменной?Если нет, есть ли способ обновить область сеанса, чтобы обеспечить получение последней версии?

Ниже представлена ​​функция autoLogin (): (работает на одном узле)

private void function autoLogin () {

    // multiple, concurrent requests could be hitting this on different nodes in the cluster

    // if we're already logged in, nothing to do
    if (session.isLoggedIn) {
        return;
    }

    // get the auth token if it exists
    var token = cookie.keyExists("auth") && isValid("uuid", cookie.auth) ? cookie.auth : "";
    if (token == "") {
        // if a token doesn't exists, nothing to do
        return;
    }

    // assertion: user is not logged in and an auth token exists
    // attempt to login using the token, but make sure that only one 
    // request does this at a time - wrap with an exclusive session lock

    // lock the session - how would you do this on a cluster?
    lock scope="session" type="exclusive" timeout="10" throwontimeout=false {
        // check if logged in again - another thread may have succeeded while this
        // thread was waiting for the lock to open
        if (!session.loggedIn) {
            // we can only call this once if user is not logged in!
            application.auth.loginWithToken(authToken=token);
        }
    }

} // autoLogin()
...