Skip to content

Commit

Permalink
ATS-8
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Müller committed Sep 14, 2018
1 parent ccf0083 commit 7e21b64
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/main/java/org/appng/tomcat/session/mongo/MongoStore.java
Expand Up @@ -70,6 +70,9 @@ public class MongoStore extends StoreBase {
/** Property used to store the Session's data. */
protected static final String sessionDataProperty = "data";

/** Property used to store the name of the thread that loaded the session at last */
private static final String THREAD_PROPERTY = "thread";

/** Default Name of the Collection where the Sessions will be stored. */
protected static final String sessionCollectionName = "tomcat.sessions";

Expand Down Expand Up @@ -156,6 +159,17 @@ public class MongoStore extends StoreBase {
/** Mongo Collection for the Sessions */
protected DBCollection collection;

/**
* The maximum time to wait when reading a session that is still used by another thread. 0 means: Don't wait at all.
*/
protected long maxWaitTime = 5000;

/** The time to wait in one iteration when reading a session that is still used by another thread */
protected long waitTime = 50;

// Tomcat's background thread that expires sessions
private static final String CONTAINER_BACKGROUND_PROCESSOR = "ContainerBackgroundProcessor";

/**
* Retrieve the unique Context name for this Manager. This will be used to separate out sessions from different
* application Contexts.
Expand Down Expand Up @@ -251,6 +265,24 @@ public StandardSession load(String id) throws ClassNotFoundException, IOExceptio
/* lookup the session */
DBObject mongoSession = this.collection.findOne(sessionQuery);
if (mongoSession != null) {
boolean waitingEnabled = maxWaitTime > 0;
if (waitingEnabled) {
long waited = 0;
while (mongoSession.containsField(THREAD_PROPERTY) && !String.class
.cast(mongoSession.get(THREAD_PROPERTY)).startsWith(CONTAINER_BACKGROUND_PROCESSOR)
&& waited < maxWaitTime) {
try {
Thread.sleep(waitTime);
waited += waitTime;
} catch (InterruptedException e) {
// ignore
}
getLog().debug(String.format("Session %s is still used by Thread %s", id,
mongoSession.get(THREAD_PROPERTY)));
mongoSession = this.collection.findOne(sessionQuery);
}
}

/* get the properties from mongo */
byte[] data = (byte[]) mongoSession.get(sessionDataProperty);

Expand All @@ -266,6 +298,12 @@ public StandardSession load(String id) throws ClassNotFoundException, IOExceptio
session = (StandardSession) this.manager.createEmptySession();
session.readObjectData(ois);
session.setManager(this.manager);

if (waitingEnabled) {
this.collection.update(sessionQuery, new BasicDBObject("$set",
new BasicDBObject(THREAD_PROPERTY, Thread.currentThread().getName())));
}

if (isDebugEnabled()) {
getLog().debug(String.format("Loaded session %s with query %s in %s ms (lastModified %s)", id,
session, System.currentTimeMillis() - start, new Date(session.getLastAccessedTime())));
Expand Down Expand Up @@ -665,4 +703,20 @@ public void setTimeToLive(int timeToLive) {
this.timeToLive = timeToLive;
}

public long getMaxWaitTime() {
return maxWaitTime;
}

public void setMaxWaitTime(long maxWaitTime) {
this.maxWaitTime = maxWaitTime;
}

public long getWaitTime() {
return waitTime;
}

public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
}

}

0 comments on commit 7e21b64

Please sign in to comment.