Lucee 6.0.3 and memcache session storage

Hi, hoping for some help here. We’re running Lucee 6.0.3 in Commandbox within Docker (local) and Kubernetes (dev/test). I haven’t been able to get sessions to persist container replacement or local docker stop/starts.

We are migrating our applications from ACF 2018 to Lucee 6.x. In ACF we used Redis cache in AWS for session storage. I have set up Memcache in AWS and installed the Memcache extension and set up the cache connection in Lucee with .cfconfig.json:

"caches":{
        "sessions":{
            "class":"org.lucee.extension.io.cache.memcache.MemCacheRaw",
            "custom":{
                "alive_check":"true",
                "buffer_size":"1",
                "failback":"true",
                "failover":"true",
                "initial_connections":"1",
                "maint_thread_sleep":"5",
                "max_busy_time":"30",
                "max_idle_time":"600",
                "max_spare_connections":"32",
                "min_spare_connections":"1",
                "nagle_alg":"true",
                "servers":"<AWS CACHE ENDPOINT>:11211",
                "socket_connect_to":"3",
                "socket_timeout":"30",
                "storage_format":"Binary"
            },
            "readOnly":"false",
            "storage":"true"
        }
    },
    "sessionMangement":"true",
    "sessionType": "jee",
    "sessionStorage":"sessions",
    "sessionTimeout":"0,4,0,0",
    "sessionMaximumTimeout": "0,4,0,0",

And this is in Application.cfc

this.sessionManagement  = true;
this.sessionType = "jee";
this.sessionStorage = "sessions";
this.sessionCluster = true;
this.setClientCookies = true;
this.setDomainCookies = true;

In my auth page we set a staff id in the session

<cfset session.staff_id = qLogin.staff_id>

And onSessionStart in Application.cfc we check for that to be set to validate a user is authenticated

<cffunction name="onRequestStart">
		<cfargument name="targetPage" type="string" required="true">
		
		<cfif structKeyExists(URL, "reloadCache") AND URL.reloadCache >
			<cfset PagePoolClear() />
			<cfset SystemCacheClear() />
		</cfif>
		
		<cfscript>
			request.core = createObject("component", "/mvc/core").init();
		</cfscript>
		<!--- send an unauthorized user to the login page --->
		<cfif not structKeyExists(session, "staff_id")
				and left(cgi.query_string, 10) & "/" neq request.config.login_page
				and cgi.path_info does not contain "/" & request.config.login_office_page
				and cgi.path_info does not contain "/" & request.config.resetpw_page
				and left(cgi.path_info, 10) neq "/internal/"
                and left(cgi.path_info, 5) neq "/api/"
				and not arrayContains(request.config.public_paths, cgi.path_info)
				and not arrayContains(request.config.public_scripts, cgi.script_name)>

			<!--- for ajax requests send a json unsuccessful status with a message --->
			<cfif request.core.isAjaxRequest()>
				<cfcontent type="application/json; charset=utf-8" reset="true">
				<cfoutput>#serializeJSON({ success = false, green = true, unauthorized = true,
					message = "Your session has been expired, please log in on another page and try again." })#</cfoutput>
				<cfabort>
			</cfif>

			<cfset var back = replace(request.pageUrl, request.homeUrl, "")>
			<cfset var backUrl = request.secureUrl & request.config.login_page & (back neq "" ? "?back=" & back : "")>
			
			<cflocation url="#backUrl#" addtoken="no">
			<cfreturn false>
		<cfelse>
			<!---check if password needs to be updated--->
			<cfif structKeyExists(session, "pw_modify_dt") and cgi.path_info does not contain "/" & request.config.resetpw_page and cgi.script_name does not contain "StaffModel.cfc" and cgi.path_info does not contain "/" & request.config.login_office_page>
				<cfif dateDiff("d", session.pw_modify_dt, Now()) GTE 90>
					<cflocation url="#request.homeUrl#auth/reset-pw/" addtoken="false">
				</cfif>
			</cfif>

			<!---if this session var doesnt exist, get/set--->
			<cfif !structKeyExists(session, "staff_division_id_list") and structKeyExists(session, "staff_id")>
				<cfset session.staff_division_id_list = request.core.model("Staff").getDivisionsForStaff(session.staff_id) />
			</cfif>

		</cfif>

		<cfreturn true>
	</cffunction>

I’m not sure where to go from here. I’ve tried both cfml and jee session types. I see activity in AWS looking at the memcache metrics, and the cache connection verifies fine in Lucee admin. Any suggestions the community has would be greatly appreciated!

After a bit of debug logging I found something interesting. If I dump out sessionid from the application I get something like this:

D2C2C5CFE04B96EAECDA0B4FD1DCB2FF_695e5a99-c1df-457a-b298-b35d501339bc_0

However, after I turned on trace logging on “Scope”, I could see messages where Lucee is attempting to query memcache for the sessionid in this format:

D2C2C5CFE04B96EAECDA0B4FD1DCB2FF/695e5a99-c1df-457a-b298-b35d501339bc

Full log example:

[INFO] 2024-07-10T15:26:18-04:00 runwar.context - "INFO","XNIO-1 task-8","07/10/2024","15:26:18","scope-context","load existing data from cache [sessions] to create session scope for D2C2C5CFE04B96EAECDA0B4FD1DCB2FF/eb82fe21-6113-4a2d-8e42-52044f829605"

[INFO] 2024-07-10T15:26:18-04:00 runwar.context - Starting login
[INFO] 2024-07-10T15:26:19-04:00 runwar.context - submit
[INFO] 2024-07-10T15:26:19-04:00 runwar.context - Login IP not restrcited
[INFO] 2024-07-10T15:26:20-04:00 runwar.context - Auth passed, session started
[INFO] 2024-07-10T15:26:20-04:00 runwar.context - {"csrf_token":{},"PW_MODIFY_DT":createDateTime(2024,6,13,13,3,20,96,"America/New_York"),"cfid":"eb82fe21-6113-4a2d-8e42-52044f829605","lastvisit":createDateTime(2024,7,10,15,25,58,630,"America/New_York"),"sessionid":"D2C2C5CFE04B96EAECDA0B4FD1DCB2FF_eb82fe21-6113-4a2d-8e42-52044f829605_0","STAFF_DIVISION_ID_LIST":"1,117","timecreated":createDateTime(2024,7,10,15,4,47,868,"America/New_York"),"STAFF_ID":89446908,"urltoken":"CFID=eb82fe21-6113-4a2d-8e42-52044f829605&CFTOKEN=0","cftoken":"0"}
[INFO] 2024-07-10T15:26:20-04:00 runwar.context - "ERROR","XNIO-1 task-8","07/10/2024","15:26:20","scope-context","org.postgresql.jdbc.PgResultSetMetaData