Forums de discussion

Sequential execution of ajax in portlets

Benjamin Cassan, modifié il y a 10 années.

Sequential execution of ajax in portlets

New Member Publications: 15 Date d'inscription: 02/01/13 Publications récentes
Hi,

I have the following situation, with liferay 6.1 and JSF 2 portlets:
- One instance of a portlet A
- several instances of a portlet B

On an action by the user, the portlet A fires an event with ActionResponse.setEvent. This event is received by all B portlets, by a class implementing BridgeEventHandler. It loads a new xhtml view as content for the portlets. This view, once loaded, has javascript automatically clicking on a h:commandLink, with f:ajax defined with a listener.
The listener is a method of a managed bean in view scope, that is supposed to send a request, to process data from the answer, for updating some fields of the view.

It works, but not as I was expected. The idea of the Ajax, is to have a parallel processing of the listeners. So the display of a response in an instance of portlet B is not blocked by the request on another instance of portlet B.

Unfortunately, I see in logs that all the ajax processing, for all portlets, is done by the same thread, sequentially... So a blocking request in a listener blocks other listeners.

So is there a way to have parallel processing for theses ajax calls? Something in configuration that I didn't set? Or maybe Ajax is only a part of what I should do?
thumbnail
Neil Griffin, modifié il y a 10 années.

RE: Sequential execution of ajax in portlets

Liferay Legend Publications: 2655 Date d'inscription: 27/07/05 Publications récentes
Hi Benjamin,

When you wrote:
Unfortunately, I see in logs that all the ajax processing, for all portlets, is done by the same thread, sequentially... So a blocking request in a listener blocks other listeners.


Are you assuming that it is the same thread because the output of all of the ResourceRequests appears sequentially? In order to know for sure, you could add something like this to one of the methods of your managed beans that gets invoked during the Ajax requests:

System.err.println("Executing in thread: " + Thread.currentThread().toString());


My best guess would be that they are all executing in separate threads, as it is the job of the servlet container to dispatch each request in a separate thread.

It might be the case that since all of your JSF portlets are sharing the same "jsf.js" client javascript library, that the Ajax requests are getting queued in a sequential manner. The reason why the JSF implementation (Mojarra or MyFaces) would have a queue would be to prevent double-clicks firing double requests and things like that. If that's the case, then that would be a webapp assumption (perhaps better thought of as a portlet incompatibility) in the JSF implementation.

Kind Regards,

Neil
Benjamin Cassan, modifié il y a 10 années.

RE: Sequential execution of ajax in portlets

New Member Publications: 15 Date d'inscription: 02/01/13 Publications récentes
For another problem, I added the display of the thread name in the log4j logs. This is how I saw that it was the same thread.

I tried, using the same source code, to create another portlet (another war file and portlet name) that does the same thing, and I added it in the page. But same behavior, it is always the same thread.

I found a workaround. In fact not a workaround, but a better way to do the effect I wanted. My main purpose is to update the content of the portlet after a request, without having to wait for the others. By having "render-weight" to 0 for the portlet, and calling the request during the loading of the page, I have the expected behavior:
  • each portlet is rendered by a different thread
  • no need for Ajax anymore due to the parallel display of the portlets
  • a long request does not block the display of the other portlets
  • and there is a "waiting" animation, so everything I need


So it resolves all my problems. But I could do it because the Ajax was called when the page is loaded, and I can afford to refresh all the content of a portlet. I could not use this solution for partial update for instance.