You are viewing a plain text version of this content. The canonical link for it is here.
Posted to embperl@perl.apache.org by "Steven D. Arnold" <st...@neosynapse.net> on 2001/04/07 22:35:16 UTC
apparent bug in udat handling
We have been extensively using udat with great success in our software here. However, we have discovered what seems like a bug in the way udat handles persistence.
To summarize the bug, we believe that udat does not properly store state information unless a scalar is stored as a value for a top-level key in udat. We are using perl 5.6, Embperl 1.3b3, mod_perl 1.24 and Apache::Session 1.03. We are using FileStore for persistence. Documentation so that you may reproduce the bug is given below.
This message contains two embperl files and a function which is contained in the utility.pm module. The function, set_app_state, is used to allow authors of different applications to stay entirely under a single key in udat; this allows each application author to avoid polluting udat's top-level namespace.
persist1.shtml:
---------------
[-
use utility;
$foo = set_app_state('foo', \%udat);
$bar = set_app_state('bar', $foo);
-]
<HTML><HEAD><TITLE>Page 1</TITLE></HEAD>
<BODY>
<H1>Now on page 1</H1>
join(", ", keys(%{$bar})) = [+ join(", ", keys(%{$bar})) +]<BR>
<FORM METHOD="post" ACTION="/embperl/tests/persist2.shtml">
<INPUT TYPE="submit" VALUE="Page 2">
</FORM>
</BODY>
</HTML>
If you load the above page, $bar should be equivalent to $udat{'foo'}->{'bar'}. This value will have no keys, so the "join" expression will show an empty result.
persist2.shtml:
---------------
[-
use utility;
$state = set_app_state('foo', \%udat);
$bar = set_app_state('bar', $state);
$bar->{'foo'} = "whee";
$udat{'foo'}->{'bar'}{'foo'} = "whee";
#$udat{'bar'} = "lalala";
-]
<HTML><HEAD><TITLE>Page 2</TITLE></HEAD>
<BODY>
<H1>Now on page 2</H1>
join(", ", keys(%{$bar})) = [+ join(", ", keys(%{$bar})) +]<BR>
$udat{'foo'}->{'bar'}{'foo'} = [+ $udat{'foo'}->{'bar'}{'foo'} +]<BR>
$udat{'bar'} = [+ $udat{'bar'} +]<BR>
<FORM METHOD="post" ACTION="/embperl/tests/persist1.shtml">
<INPUT TYPE="submit" VALUE="Page 1">
</FORM>
</BODY>
</HTML>
In the above code, $state is the same as $udat{'foo'} and $bar is the same as $udat{'foo'}->{'bar'}. So when we say $bar->{'foo'} = "whee", that is equivalent to saying $udat{'foo'}->{'bar'}{'foo'} = "whee".
The problem is that if we click the button to take us back to page 1, the key ("foo") for $udat{'foo'}->{'bar'} is not displayed. In other words, %udat is not storing the data structure we're creating. However, if we uncomment the $udat{'bar'} = "lalala" line above, everything works as expected. Said another way, if we assign a scalar to a key at the top level of udat, the remainder of our data structures are saved/remembered, but if we don't have any scalars associated with top-level keys, it doesn't work.
The set_app_state function is given below:
set_app_state from utility.pm:
------------------------------
sub set_app_state {
my($app, $udat_ref) = @_;
confess "function must be passed the name of the application"
unless ($app);
confess "function must be passed a reference to udat"
unless (ref($udat_ref) eq "HASH");
if (!defined($udat_ref->{$app})) {
$udat_ref->{$app} = {};
}
return $udat_ref->{$app};
}
We have worked around this problem by simply assigning a value to a top-level key in the set_app_state function, so this does not represent a current problem for us. However, it took a couple hours of debugging to isolate the problem, so IMHO this is still worth documenting/fixing.
steve
---------------------------------------------------------------------
To unsubscribe, e-mail: embperl-unsubscribe@perl.apache.org
For additional commands, e-mail: embperl-help@perl.apache.org
RE: apparent bug in udat handling
Posted by Gerald Richter <ri...@ecos.de>.
>
> We have been extensively using udat with great success in our software
> here. However, we have discovered what seems like a bug in the way udat
> handles persistence. To summarize the bug, we believe that udat does not
> properly store state information unless a scalar is stored as a
> value for a
> top-level key in udat.
That's not a bug, but the well defined behaviour of Apache::Session. There
is no way for Apache::Session to see that a non top level key has changed.
To workaround this problem, simply do a $udat{xxx}++ in each page that
updates only non top level keys.
Gerald