Lucee/ColdFusion - Locking session scope across a cluster and accessing session vars concurrently

317 views Asked by At

This question applies to a Lucee 5.x application. I'm not sure if there are differences between how ACF and Lucee handle session scopes across a cluster.

Background: I'm implementing an autoLogin() function in application.cfc - in onRequestStart() - that looks for a token that's stored in a cookie, and then uses it to authenticate the user. Once a token has been used, it gets replaced with a new value, and the cookie is updated. When a token is not found or doesn't work, the cookie is deleted. A session lock is used to prevent multiple concurrent requests from attempting to login the user, which would have unintended side effects.

All the core functionality for this works (on a single node), but I need to make it cluster-friendly. The cluster is already setup correctly (this.sessionCluster = true; in application.cfc, along with a shared Memcached instance that stores session data), and it works fine.

The main questions I have are: (referencing the code below)

  1. The code below uses an exclusive session lock to prevent concurrent requests from executing the login code at the same time. How would you replace the session lock below with one that locks the session across the whole cluster?

  2. The code below assumes that changes to session variables can be seen immediately. Is this true when a session variable is changed on one node, and then a concurrent request on another node tries to access that same variable? If not, is there a way to refresh the session scope to ensure you're getting the latest?

Below is the autoLogin() function: (works on a single node)

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()
0

There are 0 answers