diff --git a/core/src/main/java/lucee/runtime/functions/system/SessionCommit.java b/core/src/main/java/lucee/runtime/functions/system/SessionCommit.java
new file mode 100644
index 0000000000..13750b0f9c
--- /dev/null
+++ b/core/src/main/java/lucee/runtime/functions/system/SessionCommit.java
@@ -0,0 +1,15 @@
+package lucee.runtime.functions.system;
+
+import lucee.runtime.PageContext;
+import lucee.runtime.PageContextImpl;
+import lucee.runtime.exp.PageException;
+import lucee.runtime.ext.function.Function;
+
+public class SessionCommit implements Function {
+ private static final long serialVersionUID = -2243745577257724777L;
+
+ public static String call(PageContext pc) throws PageException {
+ ((PageContextImpl) pc).sessionScope().touchAfterRequest(pc);
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/java/lucee/runtime/type/scope/storage/IKHandlerCache.java b/core/src/main/java/lucee/runtime/type/scope/storage/IKHandlerCache.java
index 34c48dd278..78e9b59c5c 100644
--- a/core/src/main/java/lucee/runtime/type/scope/storage/IKHandlerCache.java
+++ b/core/src/main/java/lucee/runtime/type/scope/storage/IKHandlerCache.java
@@ -36,16 +36,16 @@ public IKStorageValue loadData(PageContext pc, String appName, String name, Stri
Object val = cache.getValue(key, null);
if (val instanceof byte[][]) {
ScopeContext.info(log,
- "load existing data from cache [" + name + "] to create " + strType + " scope for " + pc.getApplicationContext().getName() + "/" + pc.getCFID());
+ "Load existing byte data from cache [" + name + "] to create " + strType + " scope for " + pc.getApplicationContext().getName() + "/" + pc.getCFID());
return new IKStorageValue((byte[][]) val);
}
else if (val instanceof IKStorageValue) {
ScopeContext.info(log,
- "load existing data from cache [" + name + "] to create " + strType + " scope for " + pc.getApplicationContext().getName() + "/" + pc.getCFID());
+ "Load existing data from cache [" + name + "] to create " + strType + " scope for " + pc.getApplicationContext().getName() + "/" + pc.getCFID());
return (IKStorageValue) val;
}
else {
- ScopeContext.info(log, "create new " + strType + " scope for " + pc.getApplicationContext().getName() + "/" + pc.getCFID() + " in cache [" + name + "]");
+ ScopeContext.info(log, "Create new [" + strType + "] scope for [" + pc.getApplicationContext().getName() + "/" + pc.getCFID() + "] in cache [" + name + "]");
}
return null;
}
@@ -70,6 +70,7 @@ else if (existingVal != null) {
cache.remove(key);
}
}
+ ScopeContext.info(log, "Store scope for [" + pc.getApplicationContext().getName() + "/" + pc.getCFID() + "] in cache [" + name + "]");
}
catch (Exception e) {
ScopeContext.error(log, e);
diff --git a/core/src/main/java/resource/fld/core-base.fld b/core/src/main/java/resource/fld/core-base.fld
index 6801064a3d..fb20d83c6d 100755
--- a/core/src/main/java/resource/fld/core-base.fld
+++ b/core/src/main/java/resource/fld/core-base.fld
@@ -12646,7 +12646,16 @@ You can find a list of all available timezones in the Lucee administrator (Setti
string
-
+
+
+
+ SessionCommit
+ lucee.runtime.functions.system.SessionCommit
+ Force saving the session to storage, useful when sessionCluster is enabled.
+
+ void
+
+
diff --git a/test/tickets/LDEV2135.cfc b/test/tickets/LDEV2135.cfc
index 9b26bb5862..752d99c55b 100644
--- a/test/tickets/LDEV2135.cfc
+++ b/test/tickets/LDEV2135.cfc
@@ -2,6 +2,9 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="session" {
function run( testResults , testBox ) {
describe( "Test suite for LDEV-2135 using memory", function() {
+
+ //beforeEach(function (currentSpec, data){ _beforeEach(currentSpec, data); });
+
it( title='thread looses session variables - sessionCluster=false', body=function( currentSpec ) {
test( {sessionCluster: false, sessionStorage: "memory"} );
});
@@ -12,21 +15,27 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="session" {
});
describe( title="Test suite for LDEV-2135 using redis", skip=skipRedis(), body=function() {
+
+ //beforeEach(function (currentSpec, data){ _beforeEach(currentSpec, data); });
+
it( title='thread looses session variables - redis- sessionCluster=false', body=function( currentSpec ) {
test( {sessionCluster: false, sessionStorage: "redis"} );
});
- it( title='thread looses session variables - redis - sessionCluster=true', skip=true, body=function( currentSpec ) {
+ it( title='thread looses session variables - redis - sessionCluster=true', body=function( currentSpec ) {
test( {sessionCluster: true, sessionStorage: "redis"} );
});
});
describe( title="Test suite for LDEV-2135 using memcached", skip=skipMemcached(), body=function() {
+
+ //beforeEach(function (currentSpec, data){ _beforeEach(currentSpec, data); });
+
it( title='thread looses session variables - memcached -sessionCluster=false', body=function( currentSpec ) {
test( {sessionCluster: false, sessionStorage: "memcached"} );
});
- it( title='thread looses session variables - memcached -sessionCluster=true', skip=true, body=function( currentSpec ) {
+ it( title='thread looses session variables - memcached -sessionCluster=true', body=function( currentSpec ) {
test( {sessionCluster: true, sessionStorage: "memcached"} );
});
});
@@ -44,7 +53,7 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="session" {
cfid: first.session.cfid,
cftoken: first.session.cftoken
};
-
+ // systemOutput("-- before secondRequest.cfm", true);
var second = _InternalRequest(
template : "#uri#/cfml-session/secondRequest.cfm",
url: args,
@@ -76,4 +85,9 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="session" {
private function skipMemcached(){
return (structCount(server.getTestService( "memcached" )) eq 0);
}
+
+ private function _beforeEach(currentSpec, data){
+ systemOutput("", true);
+ systemOutput(currentspec, true);
+ }
}
\ No newline at end of file
diff --git a/test/tickets/LDEV2135/cfml-session/secondRequest.cfm b/test/tickets/LDEV2135/cfml-session/secondRequest.cfm
index 3613e86033..4dce77cfc4 100644
--- a/test/tickets/LDEV2135/cfml-session/secondRequest.cfm
+++ b/test/tickets/LDEV2135/cfml-session/secondRequest.cfm
@@ -1,4 +1,8 @@
- //systemOutput(session.toJson(), true);
+ if (!structKeyExists(session, "ldev3125")){
+ //systemOutput(session.toJson(), true);
+ throw "key session.ldev3125 missing";
+ }
+ //systemOutput(session.ldev3125.toJson(), true);
echo(session.ldev3125.toJson());
\ No newline at end of file
diff --git a/test/tickets/LDEV2135/cfml-session/testThreadSession.cfm b/test/tickets/LDEV2135/cfml-session/testThreadSession.cfm
index b6065d5dd6..dc3eeda44c 100644
--- a/test/tickets/LDEV2135/cfml-session/testThreadSession.cfm
+++ b/test/tickets/LDEV2135/cfml-session/testThreadSession.cfm
@@ -1,4 +1,5 @@
+ //systemOutput(url.toJson(), true);
session.ldev3125 = {};
session.ldev3125.sessionCluster = url.sessionCluster;
session.ldev3125.start = 'survived';
@@ -13,15 +14,17 @@
thread name="#name#" {
try {
ArrayAppend( session.ldev3125.threads, thread.name );
- sleep( 10 );
+ // sleep( 10 ); // might need to be 1000
throw(type="blah", message="boom");
} catch(any e) {
- writedump(session.ldev3125);
+ dump(session.ldev3125);
}
}
}
-
+ session.ldev3125.beforeJoin = 'hello';
thread action="join" name="#_threads.toList()#";
session.ldev3125.afterJoin = 'goodbye';
echo( session.ldev3125.toJson() );
+ //systemOutput(session.toJson(), true);
+ sessionCommit();
\ No newline at end of file