Conversation timeout seems to be a commonly misunderstood Seam
concept. I often see postings on the Seam forums claiming that the
conversation-timeout doesn’t work! Well, actually it does, you simply
have to understand the semantics.
Configuring the conversation-timeout period can be accomplished
through the following in your components.xml:
<core:manager conversation-timeout="900000" />
At first glance most developers relate conversation-timeout to
session timeout, where any conversation will simply timeout after the
configured conversation timeout period. As you will quickly notice
during testing, this is not the case. To execute a quick experiment, try
the following configuration in the components.xml of the seam-booking
example:
<core:manager conversation-timeout="60000" />
Because the conversation-timeout is set in milliseconds, the above
configuration sets the conversation-timeout to 1 minute. Now in the
web.xml set the session timeout to 5 minutes:
<session-config>
<session-timeout>5</session-timeout>
</session-config>
Now in the destroy method of the HotelBookingAction add the following
line:
...
@Destroy @Remove
public void destroy() {
log.info("Destroying HotelBookingAction...");
}
...
This will log our message when the conversation ends and the
HotelBookingAction is destroyed. Now deploy the seam-booking example to
your local JBoss instance and start up a conversation. This can be
accomplished by logging in, navigating to the hotels listing, and
selecting a hotel for booking. At this point, wait for the 1 minute
period… nothing happens. Now wait for another 4 minutes, the message
is displayed. The conversation timed out along with the session.
Foreground vs. Background Conversations
So why didn’t our conversation timeout as configured? This is
because the conversation-timeout only affects background conversations.
The foreground conversation will only timeout when the session times
out. Foreground, background, what? The foreground conversation is the
conversation that the user last interacted with. A background
conversation is any other conversation in the user’s session. Thus, in
our previous scenario the foreground conversation timed out with the
session as expected.
Now lets try another approach. Perform the same steps as before to
proceed to the booking screen. Now open a new window and perform the
same steps. We now have a foreground conversation and a background
conversation in progress. Again, wait 1 minute. Nothing happened.
If you wait an additional 4 minutes, both conversations will timeout.
So what is going on here, I thought we had a background conversation?
We did, Seam simply checks the conversation timeout on each request.
Thus, if I interact with the foreground conversation after 1 minute, the
background conversation times out. Try it, perform the same steps,
wait 1 minute and then click on the window of the foreground
conversation and you will see the log message.
This is very desirable behavior. Essentially when a user leaves his
or her desk for a period of time and comes back, if the session is still
active it would be desirable to maintain the state the user was
previously in. This is the foreground conversation state. All other
background conversation state is left to timeout after the configured
conversation-timeout period which reduces overall memory consumption.
This enables a developer to think less about memory usage and cleaning
up state and more about developing business logic. That’s why we’re
here right?
Letting the user choose
So you may be asking at this point why the conversation-timeout
doesn’t use polling. As we said, you must interact with the foreground
conversation to cause the background conversations to timeout after the
conversation-timeout period. Imagine that the user had many windows
open and leaves his or her desk. Based on which window the user clicks
on when they return, that becomes the foreground conversation timing out
any other background conversations. This gives the user a chance to
resume whichever conversation he or she chooses, not the one the
developer chooses.