[ 
https://issues.apache.org/jira/browse/ARIES-137?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12828567#action_12828567
 ] 

Timothy Ward commented on ARIES-137:
------------------------------------

The lifecycle issues in this area are somewhat complicated, and as you suggest, 
I'm sure there are improvements on the current design.

There are two main issues associated with the Persistence bundle manager:

1) Persistence bundle lifecycle
  Any call into the EntityManagerFactoryManager may be re-entrant, as it is 
possible that the side effects of the persistence bundle state change will 
cause it to change state again. However, we should not be synchronizing when 
using the PersistenceProvider service or when registering the 
EntityManagerFactory in the service registry. To add further complexity, each 
EntityManagerFactory should only be created once (until it is closed).

2) Persistence provider lifecyle
 Any update to the list of accessible persistence providers needs to be thread 
safe, and ensure that any EntityManagerFactory services are unregsistered 
synchronously by that thread. We also need to eliminate the race condition 
where a new persistence bundle becomes available simultaneously with the 
persistence provider being added or removed. As only one of these calls comes 
through the bundle tracker, and the bundle tracker holds no locks, we cannot 
guarantee any call to getObject() will return the correct value.

To answer the points raised by this JIRA

a) The PersistenceBundleManager#addingProvider method should check for 
persistence bundles that are not matched with a provider and attempt to 
resolve. 

     Yes, it should. I had plans to do this when I started, but not the time to 
implement them. I could start on this once I've finished some of the logging 
tidy up and itests.

b) MultiBundleTracker does not expose the bundles tracked, but by exposing 
getBundles() for above and also using getObject() where the 
EntityManagerFactoryManager is being returned there probably wouldn't be any 
need for bundleToManagerMap and associated synchronization

     I did not write the MultiBundleTracker, but I imagine that it is somewhat 
difficult to get an atomic snapshot of the bundles and objects tracked without 
completely re-writing BundleTracker. In any event, the real problem here is a 
race condition between a thread removing a provider and a thread creating an 
EntityManagerFactoryManager. Until some point after the addingBundle call has 
completed there will be no object returned by getObject(), this means that when 
the provider is removed we can't get an atomic view of the bundles that might 
be using that provider unless we keep that view ourselves. It would be nice if 
the Tracker could be used, but I can't see any way to make the threading work.


c) Also I think an ExecutorService should be used for the setUpManager calls 
rather than this work being done on a framework event thread. 

  Is it possible to do this safely when the provider may disappear at any time? 
It may make more sense if we create the manager first, then assign a provider. 
Another big issue here is really that we need to make calls out to the 
ManagedPersistenceUnitInfoFactory, allowing plug-ins to customize the bundle in 
some way (for example by adding a fragment). This could be worth looking at in 
the future if we can avoid breaking anything.

> Lifecycle issues with PersistenceBundleManager
> ----------------------------------------------
>
>                 Key: ARIES-137
>                 URL: https://issues.apache.org/jira/browse/ARIES-137
>             Project: Aries
>          Issue Type: Bug
>          Components: JPA
>            Reporter: Alan Keane
>
> EntityManagerFactory only gets registered for a unit if a matching 
> PersistenceProvider service
> is bound before the persistence bundle is added to the tracker.
> The PersistenceBundleManager will only attempt to setup an 
> EntityManagerFactoryManager 
> for the PersistenceProvider services available at the point when a 
> persistence bundle 
> is first detected and subsequently only tracks the persistence bundles that 
> get matched with a Provider.
> Any Persistence bundle added to the tracker before a (suitable) 
> PersistenceProvider is
> available will never get matched with a provider.
> The PersistenceBundleManager#addingProvider method should check for 
> persistence bundles 
> that are not matched with a provider and attempt to resolve.
> One possible solution would be that the addingBundle and setUpManager methods 
> use a 
> null object style pattern (or similar) for the EntityManagerFactoryManager so 
> that 
> detected persistence bundles without a matching provider are still tracked. 
> When a provider service is then bound to the PersistenceBundleManager via 
> addingProvider, 
> iterate through all tracked persistence bundles and attempt to match those 
> that do 
> not have a valid EntityManagerFactoryManager associated.
> (Note: MultiBundleTracker does not expose the bundles tracked, but by 
> exposing getBundles()
> for above and also using getObject() where the EntityManagerFactoryManager is 
> being returned
> there probably wouldn't be any need for bundleToManagerMap and associated 
> synchronization)
> Also I think an ExecutorService should be used for the setUpManager calls 
> rather 
> than this work being done on a framework event thread.
> (I don't have time right now to look at this properly, so somebody might want 
> to have a 
> look/take this in the meantime)

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

Reply via email to