Thread safety bug when creating pages with @Asset annotations
-------------------------------------------------------------

                 Key: TAPESTRY-1422
                 URL: https://issues.apache.org/jira/browse/TAPESTRY-1422
             Project: Tapestry
          Issue Type: Bug
          Components: Annotations
    Affects Versions: 4.1.1
         Environment: Windows, JDK 1.5, Tomcat 6.0.x
            Reporter: Jon McCarty


I have a thread safety bug in Tapestry when using the Annotations.

PageSpecificationResolverImpl is a threaded service, but its Namespace objects 
are not; they're provided by the singleton tapestry.parse.SpecificationSource.

A problem arises when two threads are building the same page at the same time.  
They create two ComponentSpecification objects for the page, but only ONE Of 
those is changed (due to processing the annotations) when the 
ComponentConstructor is being created by ComponentConstructorFactoryImpl.  The 
two PageSpecificationResolverImpl's attempt to install() both of them, and 
sometimes, the wrong one pushes the good one out of the Namespace's page map.

I have a sleazy partial fix that works for our application for now, but it's 
not a true fix.  I currently let the two PageSpecificationResolvers build up 
two parallel copies of the Page's specification, but down in the install() 
method, make a thread-safe decision not to add one if there's one already in 
there, and moreso, to grab that first one back out of the Namespace.

It's a poor solution, but it gets me past my jMeter tests.  In reality, The 
second thread should just wait for the first thread to finish constructing the 
page, or Tapestry needs a different way of managing the side-effects of 
processing annotations that have to add stuff to ComponentSpecifications.


Here's what I did in PageSpecificationResolverImpl.install(), but it's not a 
real fix (order of thread execution could still cause the broken behavior, 
though this is currently working for me):

    private void install()
    {
        INamespace namespace = getNamespace();
        IComponentSpecification specification = getSpecification();
        
        if (_log.isDebugEnabled())
            _log.debug(ResolverMessages.installingPage(_simpleName, namespace,
                    specification));
        
        synchronized(namespace)
        {
            if( !namespace.containsPage(_simpleName) )
            {
                namespace.installPageSpecification(_simpleName, specification);
            }
            else
            {
                setSpecification(namespace.getPageSpecification(_simpleName));
            }
        }
    }


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to