Race condition BridgeImpl in multi-threaded environment
-------------------------------------------------------

                 Key: PORTLETBRIDGE-58
                 URL: https://issues.apache.org/jira/browse/PORTLETBRIDGE-58
             Project: MyFaces Portlet Bridge
          Issue Type: Bug
          Components: Impl
    Affects Versions: 1.0.0-beta, 1.0.0-alpha-3
         Environment: Pluto 1.1.5
JSF 1.2 / RI
            Reporter: Stephan Voigt
            Priority: Critical


The implementation in BridgeImpl delegates the calls to the JSF Phases to a 
initially created LifeCycle instance (member of BrideImpl).
In order to implement the LifeCycle acc. JSR-301 all JSF-Phases except 
RENDER_RESPONSE are suppressed using a PhaseListener which calls renderResponse 
on the current FacesContext, so that the further phase processing stops.
The PhaseListener is registered and unregistered in doFacesRender() during a 
render request.

The problem: when executed in multiple threads, calls to doFacesRequest 
(ActionRequests) use the same LifeCycle instance, which causes a race 
condition. The processing of the portlet action will canceled for that request.
We reproduced that behavior in our environment (JSF-RI, Pluto 1.1.5, 
PortletBridge 1.0.0-alpha-3, beta1) using loadtests with 3 or more parallel 
threads.

The problematic code-passage in BridgeImpl (see addPhaseListener and 
removePhaseListener calls):

...
 private void doFacesRender(RenderRequest request,  RenderResponse response, 
FacesContext context, Lifecycle lifecycle, String scopeId,
      List <String> preExistingAttributes)
    throws BridgeException, BridgeUninitializedException, NullPointerException
  {

...

    if (context.getViewRoot() == null)
    {
      // add self as PhaseListener to prevent action phases from
      // executing
      lifecycle.addPhaseListener(this);
      try
      {
        lifecycle.execute(context);
      }
      catch (Exception e)
      {
....
      }
      finally
      {
        lifecycle.removePhaseListener(this);
      }
....

In order to solve the problem, we patched the BridgeImpl class in that way it 
uses a static configuration for the LifeCycle instance with one enabled 
Phase-Listener. The decision when the request processing should be stopped (via 
calling renderResponse() on the FacesContext) is handled using a ThreadLocal 
flag indicating the mode (Action/Render) of the current BridgeRequest.
Please let me know, if I should provide a corresponding patch set (based on the 
beta-1 code line) or if the problem will be solved in a different manner.


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to