Configure timeout for CDI conversations
This can be achieved by conversation scoped bean with timeout. We will deal with MyFaces CODI (CDI Extensions) and see how to set a custom timeout for beans annotated with @ConversationScoped. The default timeout is 30 min. what is too long for our example. We will configure it for 1 min. The first step is to extend CODI’s ConversationConfig and overwrite the method getConversationTimeoutInMinutes(). Let’s write a class AlternativeConversationConfig.
package controller.cdi;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.Specializes;
import org.apache.myfaces.extensions.cdi.core.api.config.ConfigEntry;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.config.ConversationConfig;
@ApplicationScoped
@Alternative
@Specializes
public class AlternativeConversationConfig extends ConversationConfig {
@ConfigEntry
public int getConversationTimeoutInMinutes() {
return 1;
}
}
The important thing is the annotation @Specializes which allows to inject AlternativeConversationConfig instead of ConversationConfig at every existing places. The second step is a proper entry in beans.xml to use (activate) our class on all injection points for ConversationConfig.
<alternatives>
<class>controller.cdi.AlternativeConversationConfig</class>
</alternatives>
Server’s log output during startup contains these lines now
config implementation: controller.cdi.AlternativeConversationConfig$Proxy$_$$_WeldClientProxy config implementation: controller.cdi.AlternativeConversationConfig method: getConversationTimeoutInMinutes value: 1
To check if everything is ok, we can write a conversation scoped bean and use it in facelets.
import java.io.Serializable;
import javax.faces.event.ActionEvent;
import javax.inject.Named;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ConversationScoped;
@Named
@ConversationScoped
public class CdiBeanConversationScoped implements Serializable {
private int counter;
public int getCounter() {
return counter;
}
public void increment(ActionEvent e) {
counter++;
}
}
<h:outputText id='counter' value='Conversation scoped counter: #{cdiBeanConversationScoped.counter}'/>
<p:commandButton value='Increment counter' process='@this' update='counter'
actionListener='#{cdiBeanConversationScoped.increment}'/>
The counter will expire after 1 min. if no access to the bean happens within this time interval. Simple push the button to increment the counter, wait longer than 1 min. and increment it again. You will see that counter was reseted.
Reference: Configure timeout for CDI conversations from our JCG partner Oleg Varaksin at the Thoughts on software development blog.




