Search code examples
databaseoraclejsfrichfacesjsf-1.2

How to share a variable in concurrent JSF queries?


I have a JSF 1.2 / RichFaces 3.3 / Oracle 10g based application. I have a <h:inputText> which does a search query at database on pressing Return key. If multiple queries are submitted one after another, the program fires multiple queries to database (which returns a list of results). The program requires to show the result of only most recently submitted query.

This sample code is fired every time enter is pressed for <h:inputText>.

public void searchUser() {
    resultList = null;  // getters and setters are defined for resultList, resultList is directly accessed in .jsp pages.
    resultList = getUserServiceInterface().getFilteredUsers(searchString);  //results in JPA query to database.
}

Suppose, if query1 was submitted at t second, and its answer arrives at t+10 seconds.

Meanwhile, query2 is submitted at t+2 seconds, and its answer arrives at t+7 seconds.

The .jsp page using resultList shows the result of query2 at t+7 seconds, and then switches to the result of query1 at t+10 seconds. I want to avoid showing the result of query1 here.

The approach I am using for this is ignoring the result of the non-recent queries, it requires that I am able to distinguish the result of non-recent query from the recent query using some common variable. I have noticed that each query results in a new FacesContext and new instances of bean, therefore no common variable could be shared among concurrent queries. I tried managing states of recent query in phaseListener too but had no success. How could I have a variable in program, which is atomic during concurrent JSF queries.


Solution

  • It could be solved with Ajax Request Optimization. I used a separate queue for traffic flood protection.

    The following code executes fucntion searchUser(), if Return key is pressed.

    <h:inputText value="#{searchUser.searchString}">    
        <a4j:support event="onkeydown" onsubmit="if (event.keyCode == 13) {return false;} else {return true;}"/>    
        <a4j:support event="onkeyup" onsubmit="if (event.keyCode != 13) {return false;} else {searchUser(); return false;}"/>
    </h:inputText>
    

    I defined a separate queue for the function and used ignoreDupResponses="true", which avoids similar requests.

    <a4j:jsFunction name="searchUser" eventsQueue="foo" ignoreDupResponses="true" requestDelay="1000" action="#{searchUser.searchUser}" reRender="homeContent, userList2"/>
    

    More information can be found at following link: https://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html/ArchitectureOverview.html#QueueandTrafficFloodProtection