Skip to content

Commit

Permalink
Merge pull request #6637 from breakponchito/FISH-8174-improve-thread-…
Browse files Browse the repository at this point in the history
…expire-validation-to-read-lastaccesstime

Fish 8174 improve thread expire validation to read lastaccesstime
  • Loading branch information
breakponchito authored May 24, 2024
2 parents aaa24bd + 28340ae commit 294ec57
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
* limitations under the License.
*/

// Portions Copyright 2024 Payara Foundation and/or affiliates

package org.apache.catalina;


Expand Down Expand Up @@ -368,6 +370,12 @@ public interface Container {
*/
void backgroundProcess();

/**
* Execute periodic task to get last values added on the session storage, those values
* can be added by another instance on the cluster.
*/
void backgroundSessionUpdate();


/**
* Add a new child Container to those associated with this Container,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
* limitations under the License.
*/

// Portions Copyright 2024 Payara Foundation and/or its affiliates

package org.apache.catalina;


Expand Down Expand Up @@ -387,5 +389,15 @@ public interface Session {
/**
* unlock the session from foreground
*/
public void unlockForeground();
public void unlockForeground();

/**
* This method is to get the last time this session was accessed by the request from the client.
*/
public long getThisAccessedTime();

/**
* This method is to set the value of the accessed time
*/
public void setThisAccessedTime(long accessedTime);
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//Portions Copyright [2016-2022] [Payara Foundation]
// Portions Copyright 2016-2024 Payara Foundation and/or its affiliates

package org.apache.catalina.connector;

Expand Down Expand Up @@ -2911,7 +2911,6 @@ public void setWebConnection(WebConnection wc) {
// ------------------------------------------------------ Protected Methods

protected Session doGetSession(boolean create) {

// There cannot be a session if no context has been assigned yet
if (context == null) {
return null;
Expand Down Expand Up @@ -2954,6 +2953,7 @@ protected Session doGetSession(boolean create) {
if (session != null && !session.isValid()) {
session = null;
}

if (session != null) {
session.access();
return session;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Portions Copyright [2019-2021] Payara Foundation and/or affiliates
// Portions Copyright 2019-2024 Payara Foundation and/or affiliates

package org.apache.catalina.core;

Expand Down Expand Up @@ -308,12 +308,24 @@ public Void run() {
private Thread thread = null;


/**
* The background thread to validate lastaccesstime and accessedtime values.
*/
private Thread sessionThread = null;


/**
* The background thread completion semaphore.
*/
private volatile boolean threadDone = false;


/**
* The session background thread completion semaphore.
*/
private volatile boolean threadSessionDone = false;


/**
* Indicates whether ContainerListener instances need to be notified
* of a particular configuration event.
Expand Down Expand Up @@ -1235,6 +1247,9 @@ public synchronized void start() throws LifecycleException {
// Start our thread
threadStart();

//Start the session validation thread
threadSessionStart();

// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
Expand Down Expand Up @@ -1263,6 +1278,9 @@ public synchronized void stop() throws LifecycleException {
// Stop our thread
threadStop();

//Stop our session validation thread
threadSessionStop();

// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
Expand Down Expand Up @@ -1508,6 +1526,13 @@ public void setBasic(GlassFishValve valve) {
public void backgroundProcess() {
}

/**
* Execute periodic task to get last values added on the session storage, those values
* can be added by another instance on the cluster.
*/
@Override
public void backgroundSessionUpdate() {
}

// ------------------------------------------------------ Protected Methods

Expand Down Expand Up @@ -1720,6 +1745,21 @@ protected void threadStart() {

}

/**
* Start the session background thread that will periodically check session storage values
* to update lastaccesstime and accessedTime.
*/
protected void threadSessionStart() {
if (sessionThread != null)
return;
threadSessionDone = false;
String threadName = "ContainerBackgroundSessionProcessor[" + toString() + "]";
sessionThread = new Thread(new ContainerBackgroundSessionProcessor(), threadName);
sessionThread.setDaemon(true);
sessionThread.start();

}


/**
* Stop the background thread that is periodically checking for
Expand All @@ -1742,6 +1782,24 @@ protected void threadStop() {

}

/**
* Stopping the background thread that is periodically checking storage sessions
* to update lastaccesstime and accessedTime to validate timeouts.
*/
protected void threadSessionStop() {
if (sessionThread == null) {
return;
}

this.threadSessionDone = true;
sessionThread.interrupt();
try {
sessionThread.join();
} catch (InterruptedException e) {
//Ignore
}
sessionThread = null;
}

// -------------------------------------- ContainerExecuteDelay Inner Class

Expand Down Expand Up @@ -1794,4 +1852,56 @@ protected void processChildren(Container container, ClassLoader cl) {

}

/**
* Thread class to invoke the backgroundSessionUpdate method
* of this container and its children after 500 milliseconds.
*/
protected class ContainerBackgroundSessionProcessor implements Runnable {

@Override
public void run() {
if(manager != null) {
while (!threadSessionDone) {
try {
//this will calculate the interval depending on the configured timeout from the application
Thread.sleep( (manager.getMaxInactiveInterval() / 2) * 1000L);
} catch (InterruptedException e) {
// Ignore
}
if (!threadSessionDone) {
Container parent = (Container) getMappingObject();
ClassLoader cl =
Thread.currentThread().getContextClassLoader();
if (parent.getLoader() != null) {
cl = parent.getLoader().getClassLoader();
}
processChildren(parent, cl);
}
}
}
}

protected void processChildren(Container container, ClassLoader cl) {
try {
if (container.getLoader() != null) {
Thread.currentThread().setContextClassLoader
(container.getLoader().getClassLoader());
}
container.backgroundSessionUpdate();
} catch (Throwable t) {
log.log(Level.SEVERE, LogFacade.EXCEPTION_INVOKES_PERIODIC_OP, t);
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
Container[] children = container.findChildren();
for (Container child : children) {
if (child.getBackgroundProcessorDelay() <= 0) {
processChildren(child, cl);
}
}
}

}


}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Portions Copyright [2016-2022] [Payara Foundation and/or its affiliates]
// Portions Copyright 2016-2024 Payara Foundation and/or its affiliates

package org.apache.catalina.core;

Expand Down Expand Up @@ -208,8 +208,6 @@
* @version $Revision: 1.48 $ $Date: 2007/07/25 00:52:04 $
*/

// Portions Copyright [2016-2021] [Payara Foundation and/or its affiliates]

public class StandardContext
extends ContainerBase
implements Context, ServletContext
Expand Down Expand Up @@ -5756,6 +5754,9 @@ public synchronized void start() throws LifecycleException {

// Start ContainerBackgroundProcessor thread
super.threadStart();
// Start ContainerBackgroundSessionProcessor thread
super.threadSessionStart();


// Configure and call application filters
filterStart();
Expand Down Expand Up @@ -6192,6 +6193,23 @@ public void backgroundProcess() {
// END S1AS8PE 4965017
}

/**
* Execute periodic task to get last values added on the session storage, those values
* can be added by another instance on the cluster.
*/
@Override
public void backgroundSessionUpdate() {
if ((getManager() != null)) {
if (getManager() instanceof StandardManager) {
((StandardManager) getManager()).processExpires();
} else if (getManager() instanceof PersistentManagerBase) {
PersistentManagerBase pManager =
(PersistentManagerBase) getManager();
pManager.backgroundSessionUpdate();
}
}
}


// ------------------------------------------------------ Protected Methods

Expand Down
Loading

0 comments on commit 294ec57

Please sign in to comment.