[ 
https://issues.jboss.org/browse/RF-13674?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Val Blant updated RF-13674:
---------------------------

    Description: 
<a4j:push />  works properly on Tomcat 7, but fails on WebLogic 12c. 

{code:title=Page.xhtml|borderStyle=solid}
<a4j:push address="systemLinks" >  
  <a4j:ajax event="dataavailable" render="systemLinksPanel" />  
</a4j:push>  
  
<a4j:outputPanel id="systemLinksPanel">  
     stuff here  
</a4j:outputPanel>  
{code}

{code:title=Java Code}
TopicKey topicKey = new TopicKey("systemLinks");  
TopicsContext topicsContext = TopicsContext.lookup();  
topicsContext.publish(topicKey, "fly, you fools!");  
{code}

On Tomcat 7 this work perfectly, and always refreshes '_systemLinksPanel_' when 
data is published. 

On Weblogic 12c the data is not flushed correctly. If you use Wireshark, you'd 
see the following response coming back from the server:
{panel:title=Tomcat 7}
3b
<"topic":"systemLinks","data":"fly, you fools!","number":0>
0
{panel}

{panel:title=Weblogic 12c}
003b
<"topic":"systemLinks","data":"fly, you fools!","number":0>
{panel}

*Note the missing zero terminator line in the WebLogic response!*

I narrowed down the problem to the following:
{code:title=org.richfaces.application.push.impl.RequestImpl}
    public synchronized void 
onBroadcast(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> 
event) {
        MessageDataScriptString serializedMessages = (MessageDataScriptString) 
event.getMessage();
        
getSession().clearBroadcastedMessages(serializedMessages.getLastSequenceNumber());

        hasActiveBroadcaster = false;

        if (isPolling()) {
            event.getResource().resume(); // <= THIS LINE
        } else {
            postMessages();
        }
    }
{code}

There is nothing wrong with this in principle, but it does not work due to a 
bug in Atmosphere 0.8.4. Calling _AtmosphereResource.resume()_ at this point 
seems reasonable, since it is supposed to properly finish/commit the 
_HttpServletResponse_.  However, this does not work on WebLogic 12c and leads 
to incorrectly flushed data demonstrated above. 

The underlying problem seems to be the fact that _AtmosphereResource.resume()_ 
method interrupts the thread which flushed the socket Writer before a call to 
_asyncContext.complete()_ is made:
{code}
public AtmosphereResource resume() {
....
 if (!b.isDestroyed()) {
     b.removeAtmosphereResource(event.getResource());
 }
....
 asyncSupport.action(this); // <= This is where asyncContext.complete() is 
called
}
{code}

I have verified that calling _asyncContext.complete()_ before we clean up 
Atmosphere resources fixes the problem.

Here's the fix, which needs to go into _RequestImpl.onBroadcast_:
{code:title=org.richfaces.application.push.impl.RequestImpl}
    public synchronized void 
onBroadcast(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> 
event) {
  ..............
        if (isPolling()) {

// This is the workaround. Completing AsyncContext before cleaning up 
Atmosphere resources
// seems to make this work everywhere.
//
AsyncContext asyncContext = (AsyncContext) 
        event
                .getResource()
                .getRequest()
                .getAttribute("org.atmosphere.container.asyncContext");

   if ( asyncContext != null ) {
        asyncContext.complete();
   }

            event.getResource().resume();
        } else {
            postMessages();
        }
    }
  ..............
{code}

I am attaching a very simple WAR file that demonstrates the problem clearly. 
The demo app does not use Richfaces, b/c I wanted to remove all unnecessary 
complexity. Instead I created a couple of simple classes that mimic the 
behavior of _org.richfaces.webapp.PushHandlerFilter_ and 
_org.richfaces.application.push.impl.RequestImpl_. In the demo app, 
_MeteorRequest = RequestImpl_, which is where the fix needs to go.

Please note that according to the Atmosphere author, this problem is fixed in 
2.1 branch. Here's the discussion: 
https://groups.google.com/forum/#!topic/atmosphere-framework/KCKlSmbMrRo

  was:
<a4j:push />  works properly on Tomcat 7, but fails on WebLogic 12c. 

{code:title=Page.xhtml|borderStyle=solid}
<a4j:push address="systemLinks" >  
  <a4j:ajax event="dataavailable" render="systemLinksPanel" />  
</a4j:push>  
  
<a4j:outputPanel id="systemLinksPanel">  
     stuff here  
</a4j:outputPanel>  
{code}

{code:title=Java Code}
TopicKey topicKey = new TopicKey("systemLinks");  
TopicsContext topicsContext = TopicsContext.lookup();  
topicsContext.publish(topicKey, "fly, you fools!");  
{code}

On Tomcat 7 this work perfectly, and always refreshes '_systemLinksPanel_' when 
data is published. 

On Weblogic 12c the data is not flushed correctly. If you use Wireshark, you'd 
see the following response coming back from the server:
{panel:title=Tomcat 7}
3b
<"topic":"systemLinks","data":"fly, you fools!","number":0>
0
{panel}

{panel:title=Weblogic 12c}
003b
<"topic":"systemLinks","data":"fly, you fools!","number":0>
{panel}

*Note the missing zero terminator line in the WebLogic response!*

I narrowed down the problem to the following:
{code:title=org.richfaces.application.push.impl.RequestImpl}
    public synchronized void 
onBroadcast(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> 
event) {
        MessageDataScriptString serializedMessages = (MessageDataScriptString) 
event.getMessage();
        
getSession().clearBroadcastedMessages(serializedMessages.getLastSequenceNumber());

        hasActiveBroadcaster = false;

        if (isPolling()) {
            event.getResource().resume(); // <= THIS LINE
        } else {
            postMessages();
        }
    }
{code}

There is nothing wrong with this in principle, but it does not work due to a 
bug in Atmosphere 0.8.4. Calling _AtmosphereResource.resume()_ at this point 
seems reasonable, since it is supposed to properly finish/commit the 
_HttpServletResponse_.  However, this does not work on WebLogic 12c and leads 
to incorrectly flushed data demonstrated above. 

The underlying problem seems to be the fact that _AtmosphereResource.resume()_ 
method interrupts the thread which flushed the socket Writer before a call to 
_asyncContext.complete()_ is made:
{code}
public AtmosphereResource resume() {
....
 if (!b.isDestroyed()) {
     b.removeAtmosphereResource(event.getResource());
 }
....
 asyncSupport.action(this); // <= This is where asyncContext.complete() is 
called
}
{code}

I have verified that calling _asyncContext.complete()_ before we clean up 
Atmosphere resources fixes the problem.

Here's the fix, which needs to go into _RequestImpl.onBroadcast_:
{code:title=org.richfaces.application.push.impl.RequestImpl}
    public synchronized void 
onBroadcast(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> 
event) {
  ..............
        if (isPolling()) {

// This is the workaround. Completing AsyncContext before cleaning up 
Atmosphere resources
// seems to make this work everywhere.
//
AsyncContext asyncContext = (AsyncContext) 
        event
                .getResource()
                .getRequest()
                .getAttribute("org.atmosphere.container.asyncContext");

   if ( asyncContext != null ) {
        asyncContext.complete();
   }

            event.getResource().resume();
        } else {
            postMessages();
        }
    }
  ..............
{code}

I am attaching a very simple WAR file that demonstrates the problem clearly. 
The demo app does not use Richfaces, b/c I wanted to remove all unnecessary 
complexity. Instead I created a couple of simple classes that mimic the 
behavior of _org.richfaces.webapp.PushHandlerFilter_ and 
_org.richfaces.application.push.impl.RequestImpl_. In the demo app, 
_MeteorRequest = RequestImpl_, which is where the fix needs to go.




> a4j:push broken on WebLogic 12c
> -------------------------------
>
>                 Key: RF-13674
>                 URL: https://issues.jboss.org/browse/RF-13674
>             Project: RichFaces
>          Issue Type: Bug
>      Security Level: Public(Everyone can see) 
>          Components: component-push/poll
>    Affects Versions: 4.2.0.Final
>         Environment: WebLogic 12c
>            Reporter: Val Blant
>         Attachments: atmosphere-weblogic12c-bug-0.8.4-sources.jar, 
> atmosphere-weblogic12c-bug-0.8.4.war
>
>
> <a4j:push />  works properly on Tomcat 7, but fails on WebLogic 12c. 
> {code:title=Page.xhtml|borderStyle=solid}
> <a4j:push address="systemLinks" >  
>   <a4j:ajax event="dataavailable" render="systemLinksPanel" />  
> </a4j:push>  
>   
> <a4j:outputPanel id="systemLinksPanel">  
>      stuff here  
> </a4j:outputPanel>  
> {code}
> {code:title=Java Code}
> TopicKey topicKey = new TopicKey("systemLinks");  
> TopicsContext topicsContext = TopicsContext.lookup();  
> topicsContext.publish(topicKey, "fly, you fools!");  
> {code}
> On Tomcat 7 this work perfectly, and always refreshes '_systemLinksPanel_' 
> when data is published. 
> On Weblogic 12c the data is not flushed correctly. If you use Wireshark, 
> you'd see the following response coming back from the server:
> {panel:title=Tomcat 7}
> 3b
> <"topic":"systemLinks","data":"fly, you fools!","number":0>
> 0
> {panel}
> {panel:title=Weblogic 12c}
> 003b
> <"topic":"systemLinks","data":"fly, you fools!","number":0>
> {panel}
> *Note the missing zero terminator line in the WebLogic response!*
> I narrowed down the problem to the following:
> {code:title=org.richfaces.application.push.impl.RequestImpl}
>     public synchronized void 
> onBroadcast(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> 
> event) {
>         MessageDataScriptString serializedMessages = 
> (MessageDataScriptString) event.getMessage();
>         
> getSession().clearBroadcastedMessages(serializedMessages.getLastSequenceNumber());
>         hasActiveBroadcaster = false;
>         if (isPolling()) {
>             event.getResource().resume(); // <= THIS LINE
>         } else {
>             postMessages();
>         }
>     }
> {code}
> There is nothing wrong with this in principle, but it does not work due to a 
> bug in Atmosphere 0.8.4. Calling _AtmosphereResource.resume()_ at this point 
> seems reasonable, since it is supposed to properly finish/commit the 
> _HttpServletResponse_.  However, this does not work on WebLogic 12c and leads 
> to incorrectly flushed data demonstrated above. 
> The underlying problem seems to be the fact that 
> _AtmosphereResource.resume()_ method interrupts the thread which flushed the 
> socket Writer before a call to _asyncContext.complete()_ is made:
> {code}
> public AtmosphereResource resume() {
> ....
>  if (!b.isDestroyed()) {
>      b.removeAtmosphereResource(event.getResource());
>  }
> ....
>  asyncSupport.action(this); // <= This is where asyncContext.complete() is 
> called
> }
> {code}
> I have verified that calling _asyncContext.complete()_ before we clean up 
> Atmosphere resources fixes the problem.
> Here's the fix, which needs to go into _RequestImpl.onBroadcast_:
> {code:title=org.richfaces.application.push.impl.RequestImpl}
>     public synchronized void 
> onBroadcast(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> 
> event) {
>   ..............
>         if (isPolling()) {
> // This is the workaround. Completing AsyncContext before cleaning up 
> Atmosphere resources
> // seems to make this work everywhere.
> //
> AsyncContext asyncContext = (AsyncContext) 
>       event
>               .getResource()
>               .getRequest()
>               .getAttribute("org.atmosphere.container.asyncContext");
>    if ( asyncContext != null ) {
>       asyncContext.complete();
>    }
>             event.getResource().resume();
>         } else {
>             postMessages();
>         }
>     }
>   ..............
> {code}
> I am attaching a very simple WAR file that demonstrates the problem clearly. 
> The demo app does not use Richfaces, b/c I wanted to remove all unnecessary 
> complexity. Instead I created a couple of simple classes that mimic the 
> behavior of _org.richfaces.webapp.PushHandlerFilter_ and 
> _org.richfaces.application.push.impl.RequestImpl_. In the demo app, 
> _MeteorRequest = RequestImpl_, which is where the fix needs to go.
> Please note that according to the Atmosphere author, this problem is fixed in 
> 2.1 branch. Here's the discussion: 
> https://groups.google.com/forum/#!topic/atmosphere-framework/KCKlSmbMrRo



--
This message was sent by Atlassian JIRA
(v6.2.6#6264)
_______________________________________________
richfaces-issues mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/richfaces-issues

Reply via email to