Author: bpapez
Date: Fri Aug 17 16:14:12 2007
New Revision: 18203
URL: https://svndev.jahia.net/websvn/listing.php?sc=3D1&rev=3D18203&repname=
=3Djahia
Log:
Control startup session under high load
* first implementation just offering a manual refresh
Modified:
trunk/core/src/java/org/jahia/exceptions/JahiaServerOverloadedException=
.java
trunk/core/src/java/org/jahia/operations/PageGeneratorQueue.java
trunk/core/src/java/org/jahia/operations/valves/CacheWriteValve.java
trunk/core/src/java/org/jahia/operations/valves/EngineValve.java
trunk/core/src/java/org/jahia/settings/SettingsBean.java
trunk/core/src/webapp/WEB-INF/etc/config/jahia.skeleton
Modified: trunk/core/src/java/org/jahia/exceptions/JahiaServerOverloadedExc=
eption.java
URL: https://svndev.jahia.net/websvn/diff.php?path=3D/trunk/core/src/java/o=
rg/jahia/exceptions/JahiaServerOverloadedException.java&rev=3D18203&repname=
=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/core/src/java/org/jahia/exceptions/JahiaServerOverloadedException=
.java (original)
+++ trunk/core/src/java/org/jahia/exceptions/JahiaServerOverloadedException=
.java Fri Aug 17 16:14:12 2007
@@ -9,12 +9,24 @@
*/
public class JahiaServerOverloadedException extends JahiaException
{
+ boolean duringFirstRequest =3D false;
+ int suggestedRetryTime;
//--------------------------------------------------------------------=
-----
/** Default constructor
*/
- public JahiaServerOverloadedException()
+ public JahiaServerOverloadedException(boolean isDuringFirstRequest, in=
t aSuggestedRetryTime)
{
super ("503 - server overloaded", "503 - Server Overloaded",
UNAVAILABLE_ERROR , ERROR_SEVERITY);
+ duringFirstRequest =3D isDuringFirstRequest;
+ suggestedRetryTime =3D aSuggestedRetryTime;
+ }
+ =
+ public int getSuggestedRetryTime() {
+ return suggestedRetryTime;
+ }
+
+ public boolean isDuringFirstRequest() {
+ return duringFirstRequest;
}
}
Modified: trunk/core/src/java/org/jahia/operations/PageGeneratorQueue.java
URL: https://svndev.jahia.net/websvn/diff.php?path=3D/trunk/core/src/java/o=
rg/jahia/operations/PageGeneratorQueue.java&rev=3D18203&repname=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/core/src/java/org/jahia/operations/PageGeneratorQueue.java (origi=
nal)
+++ trunk/core/src/java/org/jahia/operations/PageGeneratorQueue.java Fri Au=
g 17 16:14:12 2007
@@ -20,6 +20,7 @@
import org.jahia.bin.Jahia;
import org.jahia.settings.SettingsBean;
=
+import EDU.oswego.cs.dl.util.concurrent.Latch;
import EDU.oswego.cs.dl.util.concurrent.Semaphore;
import EDU.oswego.cs.dl.util.concurrent.WaiterPreferenceSemaphore;
=
@@ -35,10 +36,12 @@
*/
public class PageGeneratorQueue {
private Map notCacheablePage =3D new FastHashMap(2503);
- private Map generatingPage =3D new HashMap(10);
+ private Map generatingPages =3D new HashMap(10);
private int maxPagesToGenerateInParallel =3D Jahia.getSettings().getMa=
xParallelProcessings();
private long pageGenerationWaitTime =3D Jahia.getSettings().getPageGen=
erationWaitTime();
+ private long pageGenerationWaitTimeOnStartup =3D Jahia.getSettings().g=
etPageGenerationWaitTimeOnStartup(); =
private Semaphore availableProcessings =3D null;
+ private Latch firstRequestLatch =3D null;
=
public PageGeneratorQueue() {
}
@@ -51,8 +54,12 @@
return notCacheablePage;
}
=
- public Map getGeneratingPage() {
- return generatingPage;
+ public Map getGeneratingPages() {
+ return generatingPages;
+ }
+ =
+ public Latch getFirstRequestLatch() {
+ return firstRequestLatch;
}
=
public Semaphore getAvailableProcessings() {
@@ -73,4 +80,12 @@
public long getPageGenerationWaitTime() {
return pageGenerationWaitTime;
}
+ =
+ public long getPageGenerationWaitTimeOnStartup() {
+ return pageGenerationWaitTimeOnStartup;
+ }
+
+ public void setFirstRequestLatch(Latch firstRequestLatch) {
+ this.firstRequestLatch =3D firstRequestLatch;
+ } =
}
Modified: trunk/core/src/java/org/jahia/operations/valves/CacheWriteValve.j=
ava
URL: https://svndev.jahia.net/websvn/diff.php?path=3D/trunk/core/src/java/o=
rg/jahia/operations/valves/CacheWriteValve.java&rev=3D18203&repname=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/core/src/java/org/jahia/operations/valves/CacheWriteValve.java (o=
riginal)
+++ trunk/core/src/java/org/jahia/operations/valves/CacheWriteValve.java Fr=
i Aug 17 16:14:12 2007
@@ -17,6 +17,9 @@
*/package org.jahia.operations.valves;
=
import org.jahia.exceptions.JahiaInitializationException;
+import org.jahia.hibernate.manager.SpringContextSingleton;
+import org.jahia.operations.PageGeneratorQueue;
+import org.jahia.operations.PageState;
import org.jahia.params.ProcessingContext;
import org.jahia.pipelines.PipelineException;
import org.jahia.pipelines.valves.Valve;
@@ -28,9 +31,6 @@
import org.jahia.services.cache.HtmlCacheEntry;
import org.jahia.settings.SettingsBean;
import org.jahia.utils.LanguageCodeConverters;
-import org.jahia.operations.PageState;
-import org.jahia.operations.PageGeneratorQueue;
-import org.jahia.hibernate.manager.SpringContextSingleton;
=
import java.util.Date;
import java.util.Map;
@@ -83,8 +83,8 @@
generatedOutput, curContentType,state);
} catch (java.io.IOException ioe) {
if (logger.isDebugEnabled()) logger.debug("Error while ret=
rieving generated output :", ioe);
- if ((generatorQueue.getGeneratingPage() !=3D null) && (sta=
te !=3D null)) {
- generatorQueue.getGeneratingPage().remove(state.getKey=
());
+ if ((generatorQueue.getGeneratingPages() !=3D null) && (st=
ate !=3D null)) {
+ generatorQueue.getGeneratingPages().remove(state.getKe=
y());
}
}
}
Modified: trunk/core/src/java/org/jahia/operations/valves/EngineValve.java
URL: https://svndev.jahia.net/websvn/diff.php?path=3D/trunk/core/src/java/o=
rg/jahia/operations/valves/EngineValve.java&rev=3D18203&repname=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/core/src/java/org/jahia/operations/valves/EngineValve.java (origi=
nal)
+++ trunk/core/src/java/org/jahia/operations/valves/EngineValve.java Fri Au=
g 17 16:14:12 2007
@@ -18,6 +18,7 @@
=
import java.util.Map;
=
+import org.jahia.bin.Jahia;
import org.jahia.data.JahiaData;
import org.jahia.engines.JahiaEngine;
import org.jahia.exceptions.JahiaException;
@@ -37,71 +38,128 @@
import EDU.oswego.cs.dl.util.concurrent.Latch;
=
/**
- * <p>Title: </p>
- * <p>Description: </p>
- * <p>Copyright: Copyright (c) 2004</p>
- * <p>Company: Jahia Ltd</p>
+ * <p>
+ * Title:
+ * </p>
+ * <p>
+ * Description:
+ * </p>
+ * <p>
+ * Copyright: Copyright (c) 2004
+ * </p>
+ * <p>
+ * Company: Jahia Ltd
+ * </p>
+ * =
* @author Serge Huber
* @version 1.0
*/
=
public class EngineValve implements Valve {
- private static org.apache.log4j.Logger logger =3D
- org.apache.log4j.Logger.getLogger(EngineValve.class);
- =
+ private static org.apache.log4j.Logger logger =3D org.apache.log4j.Log=
ger
+ .getLogger(EngineValve.class);
+
private PageGeneratorQueue generatorQueue;
=
public EngineValve() {
- generatorQueue =3D (PageGeneratorQueue) SpringContextSingleton.get=
Instance().getContext().getBean(PageGeneratorQueue.class.getName());
+ setGeneratorQueue((PageGeneratorQueue) SpringContextSingleton
+ .getInstance().getContext().getBean(
+ PageGeneratorQueue.class.getName()));
}
- public void invoke(Object context, ValveContext valveContext) throws P=
ipelineException {
+
+ public void invoke(Object context, ValveContext valveContext)
+ throws PipelineException {
ProcessingContext processingContext =3D (ProcessingContext) contex=
t;
- // Get the engine instance (can throw a JahiaException)
- String engineName =3D processingContext.getEngine();
+ PageState state =3D (PageState) ValveContext.valveResources.get();
=
// So we did not find the page in the cache
// check if the page is already generating or is generated
// force generation
+ Latch firstRequestLatch =3D null;
+ boolean firstRequest =3D false;
+ synchronized (getGeneratorQueue()) {
+ firstRequestLatch =3D getGeneratorQueue().getFirstRequestLatch=
();
+ if (firstRequestLatch =3D=3D null) {
+ firstRequestLatch =3D new Latch();
+ firstRequest =3D true;
+ getGeneratorQueue().setFirstRequestLatch(firstRequestLatch=
);
+ }
+ }
+ =
+ try {
+ if (firstRequest
+ || firstRequestLatch.attempt(getGeneratorQueue()
+ .getPageGenerationWaitTimeOnStartup())) {
+
+ processEngineRequest(state, processingContext);
+
+ ValveContext.valveResources.set(state);
+ valveContext.invokeNext(context);
+ } else {
+ throw new JahiaServerOverloadedException(true, =
+ Jahia.getSettings().getSuggestedRetryTimeAfterTime=
outOnStartup());
+ }
+ } catch (InterruptedException ie) {
+ logger.debug("The waiting thread has been interrupted :", ie);
+ throw new PipelineException(ie);
+ } catch (Throwable je) {
+ throw new PipelineException(je);
+ } finally {
+ if (firstRequest && firstRequestLatch !=3D null)
+ firstRequestLatch.release();
+ }
+ }
+
+ public void initialize() {
+ }
+
+ /**
+ * Retrieve the requested engine instance.
+ * =
+ * @param name
+ * the engine name
+ * =
+ * @return the reference to the engine, or <code>null</code> when the =
engine name is unknown in the Engines Registry.
+ * =
+ * @throws JahiaException
+ * when the Engines Registry reference could not be re=
trieved.
+ */
+ private JahiaEngine getEngineInstance(String name) throws JahiaExcepti=
on {
+ // Get the Engines Registry
+ EnginesRegistry registry =3D EnginesRegistry.getInstance();
+ if (registry =3D=3D null)
+ throw new JahiaException("Internal Error",
+ "Could not get the Engines Registry instance!",
+ JahiaException.INITIALIZATION_ERROR,
+ JahiaException.ERROR_SEVERITY);
+
+ // Return the requested engine
+ return (JahiaEngine) registry.getEngine(name);
+ }
+
+ private void processEngineRequest(PageState state,
+ ProcessingContext processingContext) throws PipelineException {
+ // Get the engine instance (can throw a JahiaException)
+ String engineName =3D processingContext.getEngine();
Latch latch =3D null;
=
- PageState state =3D (PageState) ValveContext.valveResources.get();
- boolean mustBeWaited =3D false;
- GroupCacheKey entryKey =3D null;
if (state !=3D null
&& state.isCacheable()
- && !generatorQueue.getNotCacheablePage().containsKey(
+ && !getGeneratorQueue().getNotCacheablePage().containsKey(
state.getKey())) {
- entryKey =3D state.getKey();
- Map generatingPages =3D generatorQueue.getGeneratingPage();
- synchronized (generatingPages) {
- if (!generatingPages.containsKey(entryKey)) {
- latch =3D new Latch();
- generatingPages.put(entryKey, latch);
- } else {
- latch =3D (Latch) generatingPages.get(entryKey);
- mustBeWaited =3D true;
- }
- }
- try {
- if (mustBeWaited) {
- if (!latch.attempt(generatorQueue.getPageGenerationWai=
tTime())){
- throw new JahiaServerOverloadedException();
- }
- if (CacheReadValve.checkCache(processingContext))
- return;
- }
- } catch (InterruptedException ie) {
- logger.debug("The waiting thread has been interrupted :", =
ie);
- throw new PipelineException(ie);
- } catch (Throwable je) {
- throw new PipelineException(je);
- }
+
+ latch =3D avoidParallelProcessingOfSamePage(state, processingC=
ontext);
+
+ if (CacheReadValve.checkCache(processingContext))
+ return;
}
+
boolean semaphoreAcquired =3D false;
try {
- if (!generatorQueue.getAvailableProcessings().attempt(
- generatorQueue.getPageGenerationWaitTime())){
- throw new JahiaServerOverloadedException();
+ if (!getGeneratorQueue().getAvailableProcessings().attempt(
+ getGeneratorQueue().getPageGenerationWaitTime())) {
+ throw new JahiaServerOverloadedException(false, =
+ Jahia.getSettings().getSuggestedRetryTimeAfterTime=
out());
} else {
semaphoreAcquired =3D true;
}
@@ -147,57 +205,68 @@
session.setAttribute(
ProcessingContext.SESSION_LAST_REQUESTED_PAGE_ID,
new Integer(processingContext.getPageID()));
- =
- ValveContext.valveResources.set(state);
- valveContext.invokeNext(context);
- =
+
} catch (InterruptedException ie) {
logger.debug("The waiting thread has been interrupted :", ie);
throw new PipelineException(ie);
} catch (Throwable je) {
throw new PipelineException(je);
} finally {
- if (semaphoreAcquired){
- generatorQueue.getAvailableProcessings().release();
+ if (semaphoreAcquired) {
+ getGeneratorQueue().getAvailableProcessings().release();
}
if (latch !=3D null) {
latch.release();
}
if (state !=3D null && state.getKey() !=3D null) {
- synchronized (generatorQueue.getGeneratingPage()) {
- generatorQueue.getGeneratingPage().remove(state.getKey=
());
+ Map generatingPages =3D getGeneratorQueue().getGeneratingP=
ages();
+ synchronized (generatingPages) {
+ generatingPages.remove(state.getKey());
}
}
ServicesRegistry.getInstance().getJahiaEventService()
.fireAggregatedEvents();
}
}
- =
- public void initialize() {
+
+ private Latch avoidParallelProcessingOfSamePage(PageState state,
+ ProcessingContext processingContext) throws PipelineException {
+ Latch latch =3D null;
+ boolean mustWait =3D false;
+ GroupCacheKey entryKey =3D state.getKey();
+ Map generatingPages =3D getGeneratorQueue().getGeneratingPages();
+ synchronized (generatingPages) {
+ if (!generatingPages.containsKey(entryKey)) {
+ latch =3D new Latch();
+ generatingPages.put(entryKey, latch);
+ } else {
+ latch =3D (Latch) generatingPages.get(entryKey);
+ mustWait =3D true;
+ }
+ }
+ try {
+ if (mustWait) {
+ if (!latch.attempt(getGeneratorQueue()
+ .getPageGenerationWaitTime())) {
+ throw new JahiaServerOverloadedException(false,
+ Jahia.getSettings().getSuggestedRetryTimeAfter=
Timeout());
+ }
+ }
+ } catch (InterruptedException ie) {
+ logger.debug("The waiting thread has been interrupted :", ie);
+ throw new PipelineException(ie);
+ } catch (Throwable je) {
+ throw new PipelineException(je);
+ }
+ return latch;
}
- /**
- * Retrieve the requested engine instance.
- * =
- * @param name
- * the engine name
- * =
- * @return the reference to the engine, or <code>null</code> when the =
engine name is unknown in the Engines Registry.
- * =
- * @throws JahiaException
- * when the Engines Registry reference could not be retrie=
ved.
- */
- private JahiaEngine getEngineInstance (String name)
- throws JahiaException {
- // Get the Engines Registry
- EnginesRegistry registry =3D EnginesRegistry.getInstance();
- if (registry =3D=3D null)
- throw new JahiaException("Internal Error",
- "Could not get the Engines Registry i=
nstance!",
- JahiaException.INITIALIZATION_ERROR,
- JahiaException.ERROR_SEVERITY);
=
- // Return the requested engine
- return (JahiaEngine) registry.getEngine(name);
+ public PageGeneratorQueue getGeneratorQueue() {
+ return generatorQueue;
+ }
+
+ public void setGeneratorQueue(PageGeneratorQueue generatorQueue) {
+ this.generatorQueue =3D generatorQueue;
}
=
}
Modified: trunk/core/src/java/org/jahia/settings/SettingsBean.java
URL: https://svndev.jahia.net/websvn/diff.php?path=3D/trunk/core/src/java/o=
rg/jahia/settings/SettingsBean.java&rev=3D18203&repname=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/core/src/java/org/jahia/settings/SettingsBean.java (original)
+++ trunk/core/src/java/org/jahia/settings/SettingsBean.java Fri Aug 17 16:=
14:12 2007
@@ -374,7 +374,10 @@
// Core engine page generation queue configuration parameters
private int maxParallelProcessings =3D 10;
private long pageGenerationWaitTime =3D 1800000; // in milliseconds =
-
+ private long pageGenerationWaitTimeOnStartup =3D 0; // in milliseconds
+ private int suggestedRetryTimeAfterTimeout =3D 60; // in seconds
+ private int suggestedRetryTimeAfterTimeoutOnStartup =3D 10; // in seco=
nds
+ =
private int editModeSessionTimeout =3D 2*60*60; // 2 hours
=
/**
@@ -799,7 +802,10 @@
// Maximum parallel heavy processing threads
maxParallelProcessings =3D getInt("maxParallelProcessings", ma=
xParallelProcessings);
pageGenerationWaitTime =3D getLong("pageGenerationWaitTime", p=
ageGenerationWaitTime); =
-
+ suggestedRetryTimeAfterTimeout =3D getInt("suggestedRetryTimeA=
fterTimeout", suggestedRetryTimeAfterTimeout);
+ pageGenerationWaitTimeOnStartup =3D getLong("pageGenerationWai=
tTimeOnStartup", pageGenerationWaitTimeOnStartup); =
+ suggestedRetryTimeAfterTimeoutOnStartup =3D getInt("suggestedR=
etryTimeAfterTimeoutOnStartup", suggestedRetryTimeAfterTimeoutOnStartup);
+ =
editModeSessionTimeout =3D getInt("editModeSessionTimeout", 2*=
60*60);
=
settings.put("userManagementUserNamePattern", getString(
@@ -2160,6 +2166,18 @@
public long getPageGenerationWaitTime() {
return pageGenerationWaitTime;
}
+ =
+ public int getSuggestedRetryTimeAfterTimeout() {
+ return suggestedRetryTimeAfterTimeout;
+ }
+ =
+ public long getPageGenerationWaitTimeOnStartup() {
+ return pageGenerationWaitTimeOnStartup;
+ } =
+ =
+ public int getSuggestedRetryTimeAfterTimeoutOnStartup() {
+ return suggestedRetryTimeAfterTimeoutOnStartup;
+ } =
=
public int getMaxParallelProcessings() {
return maxParallelProcessings;
Modified: trunk/core/src/webapp/WEB-INF/etc/config/jahia.skeleton
URL: https://svndev.jahia.net/websvn/diff.php?path=3D/trunk/core/src/webapp=
/WEB-INF/etc/config/jahia.skeleton&rev=3D18203&repname=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/core/src/webapp/WEB-INF/etc/config/jahia.skeleton (original)
+++ trunk/core/src/webapp/WEB-INF/etc/config/jahia.skeleton Fri Aug 17 16:1=
4:12 2007
@@ -516,8 +516,21 @@
# processing (page creation not served from the cache)
maxParallelProcessings =3D 10
# This variable controls how long threads are waiting to be able to start
-# generating pages (in heavy load situations)
+# generating pages in heavy load situations (value in milliseconds)
pageGenerationWaitTime =3D 1800000
+# This variable controls the setting of the HTTP Retry-After header, which=
is sent
+# back to the client with a HTTP status code 503 (Service temporarily unav=
ailable). =
+# It could be used also to trigger an automatic reload (value in seconds).
+suggestedRetryTimeAfterTimeout =3D 60
+# This variable controls how long threads are waiting to be able to start
+# generating pages, when load is coming during server startup =
+# (value in milliseconds)
+pageGenerationWaitTimeOnStartup =3D 0
+# This variable controls the setting of the HTTP Retry-After header, which=
is sent
+# back to the client with a HTTP status code 503 (Service temporarily unav=
ailable), =
+# when it was triggered during server startup. It could be used also to tr=
igger =
+# an automatic reload (value in seconds).
+suggestedRetryTimeAfterTimeoutOnStartup =3D 15
=
######################################################################
### Cookie authentification valve config #############################
_______________________________________________
cvs_list mailing list
[email protected]
http://lists.jahia.org/cgi-bin/mailman/listinfo/cvs_list