[ic] Update to update: Re: AddAttr only UserTags sometimes work, sometimes fail

Chris Keane chris.keane at zzgi.com
Wed Jun 30 15:36:40 UTC 2010

> Scratch that, it doesn't make any difference which order the arguments 
> are in. About half the time it works perfectly as expected right after 
> the server restarts for some period of time and then consistently 
> fails until the next time the server is restarted.

I've turned on full debugging and uncommented quite a few of the 
logDebug statements in Parse.pm. I'm still tracing through but is this a 
possible scenario?
Two catalogs, running in the same server.

Each has a private catalog-specific UserTag called, say "thing". But 
they're coded differently in how they take their similar arguments. For 
example in catalog #1:

UserTag thing Order arg
UserTag thing AddAttr
UserTag thing Routine << EOR
sub {
     ($arg, $opt) = @_;
     ::logDebug("arg is $arg");

And in catalog #2:
UserTag thing AddAttr
UserTag thing Routine << EOR
sub {
     ($opt) = @_;
     ::logDebug("arg is $opt->{arg}");

Both catalogs call the tag using [thing arg=arg_value]

It looks like catalog #2's version works right up until sometime after 
someone uses catalog #1's version. After that, Parse attempts to always 
send a positional parameter for arg whether or not the application is 
expecting it. In this case, the catalog #2's calls to the 'thing' tag 
will fail with a server error. The unevaled arguments to catalog #1's 
version should be
["arg_value",{'arg' => "arg_value"}]
whereas catalog #2 should be getting
[{'arg' => "arg_value"}]

Unfortunately it seems that the per-catalog arg list is getting mixed 
because, for example, catalog #2's version is getting the same argument 
list as would be sent to catalog #1's version.
Therefore, because $_[0] is a scalar rather than a hashref, any 
subsequent calls to $opt->{arg} gives a server error since at that point 
$opt is a scalar.

Specifically, in Parse::resolve_args:
         @list = @{$ref}{@{$Order{$tag}}};
         push @list, $ref if defined $addAttr{$tag};
         push @list, (shift || $ref->{body} || '') if $hasEndTag{$tag};
         return @list;

@{$Order{$tag}} has a value of ["arg"] whether called from catalog #1 or 
catalog #2. Note that when the server first starts, catalog #2 calls to 
UserTag thing show (correctly) that @{$Order{$tag}} has a value of [], 
and it's only after calls to "thing" from catalog #1 that 
@{$Order{$tag}} acquires the value of ["arg"] for all catalogs.

Still digging but if anyone has any suggestions I'd love to hear them.


More information about the interchange-users mailing list