[ 
https://issues.jboss.org/browse/JBSEAM-4861?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

ahus1 updated JBSEAM-4861:
--------------------------

    Forum Reference: 
http://www.seamframework.org/Community/GlobalFactoryLockInComponentjavaPerformanceIssue

    
> Component.java uses application wide factoryLock too often 
> -----------------------------------------------------------
>
>                 Key: JBSEAM-4861
>                 URL: https://issues.jboss.org/browse/JBSEAM-4861
>             Project: Seam 2
>          Issue Type: Patch
>          Components: Core
>    Affects Versions: 2.2.2.Final, 2.3.0.ALPHA
>            Reporter: ahus1
>         Attachments: Component.patch, Component.patch, Component.patch
>
>
> Whenever getInstanceFromFactory() is called and a factory is used, a 
> (application wide) lock is used: factoryLock.
> In my environments the Factory uses expensive calls to the backend to create 
> an object, and during this time no other Factory method is allowed to be 
> called. This is a severe bottleneck in a multiuser environment. 
> This lock is important for APPLICATION scoped components, but other 
> components that are i.e. CONVERSATION scoped, Seam already ensures that only 
> one Thread has access to the current conversation. The same should be true 
> for PAGE and EVENT. In this cases no lock should be acquired. UPDATE: 
> Factories that use injection should not be called multithreaded, therefore an 
> updated condition.
> See the follwing code snippet. I also attach a patch. 
> I tested the patch for Seam 2.2.2.Final - I would be most happy to have this 
> included in 2.2 and 2.3 branch.
> Br Alexander.
> {code:title=Component.java}
>         ScopeType scopeResult = getOutScope(factoryMethod.getScope(),
>             factoryMethod.getComponent());
>         ScopeType scopeFactory = factoryMethod.getComponent().getScope();
>         boolean lockingNeeded = false;
>         /*
>          * we need this lock in the following cases: (1) the target scope is
>          * accessed by more than one thread (as we don't want to create the 
> same
>          * object by two threads at the same time for the same scope) OR (2) 
> the
>          * factory is accessed by more than one thread and is using 
> interceptors
>          * (as accessing a factory multiple times might mess up interceptors).
>          * This assumes that (1) the scopes CONVERSATION, EVENT and PAGE can't
>          * be accessed by more than one thread anyway due to CONVERSATION 
> being
>          * locked for the current thread anyway, and EVENT and PAGE being only
>          * short-lived anyway. (2) a factory that doesn't use injection can be
>          * accessed multi threaded. See JBSEAM-4669/JBSEAM-2419 for the 
> original
>          * discussion.
>          */
>         if ((scopeResult != ScopeType.CONVERSATION
>             && scopeResult != ScopeType.EVENT && scopeResult != 
> ScopeType.PAGE)
>             || (scopeFactory != ScopeType.CONVERSATION
>                 && scopeFactory != ScopeType.EVENT
>                 && scopeFactory != ScopeType.PAGE && factoryMethod
>                 .getComponent().interceptionEnabled)) {
>           lockingNeeded = true;
>         }
>         if (lockingNeeded) {
>           /*
>            * synchronize only on the factory instance, let the rest of the 
> world
>            * continue.
>            */
>           synchronized (factory) {
>             return createInstanceFromFactory(name, scope, factoryMethod,
>                 factory);
>           }
>         } else {
>           return createInstanceFromFactory(name, scope, factoryMethod, 
> factory);
>         }
> [...]
>   private static Object createInstanceFromFactory(String name, ScopeType 
> scope,
>       Init.FactoryMethod factoryMethod, Object factory) {
>     // check whether there has been created an instance by another thread
>     // while waiting for this function's lock
>     if (scope != STATELESS) {
>       Object value = (scope == null) ? Contexts.lookupInStatefulContexts(name)
>           : scope.getContext().get(name);
>       if (value != null) {
>         return value;
>       }
>     }
>     
>     if (factory == null) {
>       return null;
>     } else {
>       Object result = 
> factoryMethod.getComponent().callComponentMethod(factory,
>           factoryMethod.getMethod());
>       return handleFactoryMethodResult(name, factoryMethod.getComponent(),
>           result, factoryMethod.getScope());
>     }
>   }
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.jboss.org/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        
_______________________________________________
seam-issues mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/seam-issues

Reply via email to