On 13.02.2015 12:43, Guillaume Nodet wrote:
2015-02-13 12:23 GMT+01:00 Christian Schneider <ch...@die-schneider.net>:
On 13.02.2015 11:58, Guillaume Nodet wrote:
Your example expects a simple restart of the service, I'm talking about an
update/refresh of the bundle.
But even restarting the service, if the service is an EntityManager, that
does not work afaik : you can't just switch it in the middle of your
processing (what you've already done with the JDBC connection in the
context of your transaction can't be propagated to a new connection).
You are right about a service that provides EntityManger instances. The
problem here is that the service is not really stateless which makes it
much harder to manage.
You could also think about a camel component you want to update. In such a
case, you want the routes to cleanly shutdown before actually updating the
component.
For camel I am not sure. The components are looked up as services but
camel does not really cope
with OSGi dynamics afaik. So indeed updating a component might very well
lead to problems.
Still this would be no clear reason for using Quiesce for me. The camel
extender would see that the component is gone and could
stop/restart all bundles that need the component.
I would be careful to put too much logic into this though. As the
problem is probably not to common.
For updates of user bundles there should be no issue I think.
This problem is a general problem, think about CXF services, camel routes,
etc...
It may be possible to partially get rid of the quiesce api if all bundles
would always perform a clean shutdown when being stopped. That's actually
what camel does afaik.
If shutting down a blueprint bundle or an jpa container would wait for all
calls to be finished before actually shutting down, it may help a lot.
Though even doing that would not really be sufficient, as you can't track
inside an individual bundle, the fact that a service is "still" in use,
even without being currently called.
I.e. if you have a service which performs several operations on the entity
manager, you could delay the stop of the entity manager until one call is
finished, but what you really want is coordination so that the entity
manager it stopped until the bundle using the entity manager is completely
done. For that, you need cooperation of bundles, and the OSGi api does not
really provide anything afaik.
If we are talking about an update of the user jpa client bundle then I
dont think the EntityManager is
an issue. The user jpa client bundle does not control the EntityManager.
So updating the user bundle should even
keep the EntityManager intact.
If the persistence unit bundle is updated then the whole
EntityManagerFactory has to be taken down of course.
All instances of EntityManager created by the old EMF should then also
be cleaned up.
This is indeed a bit tricky but I think even this case should work
without Quiesce. The critical part is that we may not close and
EntityManager instance
while a bundle is still using it inside a method.
So we need to know when a method that can use an EntityManager is
entered and when it is left. As we have an interceptor for these methods
we at least have the chance to do this.
So in the preCall we could count +1 for the EM of this thread and in
postCall we can count -1. An EntityManager then can only be closed when
the count is at 0.
I think this should provide us with enough information to cleanly shut
down EMs.
I am not sure about all the details but I think it should be doable.
I will try to implement this in the new design I experiment with.
There may be alternatives though, as the service dependencies can be
introspected from the outside.
In karaf 4, when we need to refresh bundles, we do an orderly shut down of
bundles according to service dependencies. In the case above, we would
first shut down the client bundle, then the JPA entity manager. If each
bundle performs a clean shut down, it may be sufficient and we could get
rid of the quiesce api, but not of the code which tracks calls, that's
needed to perform the clean shut down.
I am not sure about the general case but what you describe about karaf 4
already sounds quite solid.
Christian
--
Christian Schneider
http://www.liquid-reality.de
Open Source Architect
http://www.talend.com