Fórum

simultaneous requests to same portlet issue

Barbalace Daniela, modificado 12 Anos atrás.

simultaneous requests to same portlet issue

New Member Postagens: 6 Data de Entrada: 12/01/12 Postagens Recentes
Hi all,

I'm new to Liferay and I'm developing a portlet in order to extract statistics from a data source.
The portlet has a tab contains a form for input stats parameter (that calls a portlet action method). When the form is submitted, the portlet extracts database records, process them and finally produces an arraylist of serializable objects and puts it in the action request attributes for the jsp page.
The issue happens when I try to submit two requests from two different browser and with different parameters to the same portlet. If the requests overlap, then data returned to jsp are inconsistent and the lists seem merged. This happens if the portlet is either instantiable or not.

Anybody could help me?

Thanks in advance

Regards
thumbnail
David H Nebinger, modificado 12 Anos atrás.

RE: simultaneous requests to same portlet issue

Liferay Legend Postagens: 14919 Data de Entrada: 02/09/06 Postagens Recentes
My guess would be that although the portlet has two different threads for each request, you're using some thread-unsafe object to retrieve and return the information which results in the merging of the retrieved data into results.
Barbalace Daniela, modificado 12 Anos atrás.

RE: simultaneous requests to same portlet issue

New Member Postagens: 6 Data de Entrada: 12/01/12 Postagens Recentes
Hi David,
thanks a lot for your response. Currently I'm using a private field of type ArrayList in the portlet class which is then sent using the actionRequest.setAttribute(...) method to jsp.
Here's an excerpt of the code:

The form :
<portlet:actionurl name="extractDailyReport" var="extractDailyReportURL" />

<aui:form action="<%= extractDailyReportURL.toString()%>" method="post">

	<h3>title:</h3>
	<aui:fieldset>
		<table>
			<tbody>
				<tr>
					<td>Report Date:</td>
					<td><aui:field-wrapper>
							<liferay-ui:input-date dayValue="<%= defaultValueDate.get(Calendar.DATE) %>" dayParam="day" disabled="<%= false %>" firstDayOfWeek="<%= defaultValueDate.getFirstDayOfWeek() - 1 %>" monthParam="month" monthValue="<%= defaultValueDate.get(Calendar.MONTH) %>" yearParam="year" yearValue="<%= defaultValueDate.get(Calendar.YEAR) %>" yearRangeStart="<%= 2011 %>" yearRangeEnd="<%= defaultValueDate.get(Calendar.YEAR) %>" />
						</aui:field-wrapper></td>
				</tr>
				<tr>
					<td></td>
					<td><aui:button type="submit" value="Extract" />
					</td>
				</tr>
			</tbody>
		</table>
	</aui:fieldset>
</aui:form>


The action method:

public class ReportsPortlet extends MVCPortlet {

private List<reportdao> repDAOList = new ArrayList<reportdao>();
public void extractDailyReport(ActionRequest request,
			ActionResponse response) throws Exception {
... 
repDAOList.clear();
... construct repDAOList...

request.setAttribute("scommesse", repDAOList);


..}

</reportdao></reportdao>


And last, the jsp to show reports results:


&lt;%
List<reportdao> scmList = (List<reportdao>) request.getAttribute("scommesse");
%&gt;
	<liferay-ui:search-container emptyresultsmessage="there-are-no-report-result" iteratorurl="<%= iteratorURL %>" delta="50">
		<liferay-ui:search-container-results>
			&lt;%

						results = ListUtil.subList(scmList,
								searchContainer.getStart(),
								searchContainer.getEnd());		
						total = scmList.size();
						pageContext.setAttribute("results", results);
						pageContext.setAttribute("total", total);
			%&gt;
...

		<liferay-ui:search-iterator />

	</liferay-ui:search-container-results></liferay-ui:search-container>
</reportdao></reportdao>


Hope you can help me, I tried to use a ReentrantLock too in the action method without success.

Regards
Daniela
thumbnail
David H Nebinger, modificado 12 Anos atrás.

RE: simultaneous requests to same portlet issue

Liferay Legend Postagens: 14919 Data de Entrada: 02/09/06 Postagens Recentes
If you're going to be clearing and repopulating the list anyway, why make it a private member variable instead of just a local variable?
thumbnail
Mika Koivisto, modificado 12 Anos atrás.

RE: simultaneous requests to same portlet issue

Liferay Legend Postagens: 1519 Data de Entrada: 07/08/06 Postagens Recentes
Just like with Servlets you can't have member variables and expect them to be unique per request as one portlet class instance maybe executed by several threads at the same time. Like David suggested move the repDAOList declaration to inside your extractDailyReport method. That way it is declared for each execution of the method and the results of different threads won't get mixed.
Barbalace Daniela, modificado 12 Anos atrás.

RE: simultaneous requests to same portlet issue

New Member Postagens: 6 Data de Entrada: 12/01/12 Postagens Recentes
Thanks, I'll try!!
Barbalace Daniela, modificado 12 Anos atrás.

RE: simultaneous requests to same portlet issue

New Member Postagens: 6 Data de Entrada: 12/01/12 Postagens Recentes
Thanks, now it works and the two lists are not merged. Actually I had used private fields because the portlet class had been recycled from a previous Struts2 action class.
However I still have a problem. Since the result list is very large, I use the liferay search container in the jsp page which implements pagination. I noticed that when I go forth in the pages and click on the "next" link of the search container, the list is no longer available in request object and this causes NullPointerException to be thrown .
For this reason I store the list in PortletSession instead of the request object, as explained in this thread http://www.liferay.com/community/forums/-/message_boards/message/11596636
Portlet action method:

		PortletSession portletSession = request.getPortletSession();
		portletSession.setAttribute("scommesse", repDAOList,PortletSession.PORTLET_SCOPE);


Jsp:

		<liferay-ui:search-container-results>
			&lt;%
				List<reportdao> scmList = (List<reportdao>) session
								.getAttribute("scommesse");
....
				results = ListUtil.subList(scmList,
								searchContainer.getStart(),
								searchContainer.getEnd());
						total = scmList.size();

						pageContext.setAttribute("results", results);
						pageContext.setAttribute("total", total);
			%&gt;
		</reportdao></reportdao></liferay-ui:search-container-results>


But now if there are two pages with different lists (built using different parameters), if I click the next link on the first page loaded I don't see the first list because the session attribute has been overwritten and I see the second list extracted.
Maybe I should create an attribute for each list with different parameters and then retrieve the attribute in the jsp according to that parameters?
i.e., a list extracted with parameter date 15-03-2012 will store in the PortletSession in an attribute named "scommesse15-03-2012", and so on for the other parameter.
I think this is not a great idea, because it may cause memory overhead.

Any suggestion will be appreciated.

Regards

Daniela
thumbnail
David H Nebinger, modificado 12 Anos atrás.

RE: simultaneous requests to same portlet issue

Liferay Legend Postagens: 14919 Data de Entrada: 02/09/06 Postagens Recentes
Session can be shared when you are doing things simultaneously from, for example, two IE tabs.

If you did one search in IE and another search in Firefox you would see the expected result in each case.

Working around the two tab scenario in IE is truly a pain in the *ss, I must say...