[
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.