http://lists.scsys.co.uk/pipermail/catalyst/2008-December/020427.html
When Catalyst::Session fetches an existing session it records its
"signature" which it then compares with the session data at the end
of the request to decide if the session should be written.
_load_session() does:
$c->_session_data_sig( Object::Signature::signature($session_data) )
if $session_data;
And then _save_session does this:
no warnings 'uninitialized';
if ( Object::Signature::signature($session_data) ne
$c->_session_data_sig )
{
$session_data->{__updated} = time();
my $sid = $c->sessionid;
$c->store_session_data( "session:$sid" => $session_data );
}
Now, if you call $c->session and no session data is found (no session
id, or no session data in store), then a fresh session hash is created.
sub initialize_session_data {
my $c = shift;
my $now = time;
return $c->_session(
{
__created => $now,
__updated => $now,
(
$c->config->{session}{verify_address}
? ( __address => $c->request->address )
: ()
),
}
);
}
Note that it is not saving the signature of this new hash.
So, if you look at the session every request, for example:
# See if user has selected a language preference
my $language = $c->session->{language} || 'en';
Then if a session doesn't exist it will generate a new session id and
at the end of the request, since there's no signature of the newly
created session data, it will store the empty session.
Anyone see a reason why not to create a signature of the new session?
sub initialize_session_data {
my $c = shift;
my $now = time;
my $session_data = {
__created => $now,
__updated => $now,
(
$c->config->{session}{verify_address}
? ( __address => $c->request->address )
: ()
),
};
# Only save this session if data is added by the application
$c->_session_data_sig( Object::Signature::signature($session_data) );
return $c->_session($session_data);
}