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.