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 a normal EntityManagerFactory (like provided by jpa.container) this
> should not apply as the EntityManager is under control of the client bundle.
>
> In case of jpa.container.context there probably is a problem. The service
> holds instances of EntityManager. So if this bundle is updated I would
> expect it to close
> all EntityManager instances. So the state would be lost. This is a very
> special case though and I dont think it would warant the Quiesce support
> all for itself.
> After all updating aries jpa is rather seldom for a customer compared to
> updating their own bundles. So I think it should be ok to handle this case
> manually in a special way.
>
> 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.

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.


>
> Btw. I am not yet sure what a refresh in OSGi actually does. Let us assume
> we refresh a bundle that provides a package that is imported by other
> bundles. Will these bundles also be refreshed then?
>
Yes

> If not then I think  these bundles will not see the new package. So in
> case the package contains a service interface they will not see the new
> service. As this seems to work in practice (at least in karaf) I assume
> that in karaf the
> client bundles are also refreshed. Is that correct?
>

If the interface containing the bundle is refreshed, the bundle using that
interface is refreshed too.  If the api is packaged as a separate bundle
and you update the implementation, the client bundle won't be refreshed.

>
> Btw. this reminds me of this issue https://issues.apache.org/
> jira/browse/ARIES-1270 .
> There we refresh a persistence unit bundle. After this the client bundle
> and the EntityManagerFactory saw different classes for the Entities.
> I do not think this is Quiesce related though. If you have any ideas about
> that would be great as I do not seem to find any solution.
>
>  The doc mentions "threads started by this bundle".
>>>
>>> If a bundle B calls a service from bundle A then the thread is not
>>> started
>>> by bundle A. So it should be fine that this thread keeps running
>>> even when the Activator.stop was called.
>>>
>>>  Here's what the spec says for services (section 5.7, osgi core 6):  the
>> behaviour of a a service object that becomes unregistered is undefined.
>> Such service objects may continue to work properly or throw an exception
>> at
>> their discretion.  Imho, in a production environment, you don't really
>> want
>> to rely on an undefined behavior.  And if the service throws an exception,
>> it's not a clean shutdown anymore.
>>
> I would interpret this part of the spec ("at their discretion") that the
> service implementor is free to either continue working or throw an
> exception.
> So if he does not do anything special it should be fine.
>
>
> Christian
>
>
> --
> Christian Schneider
> http://www.liquid-reality.de
>
> Open Source Architect
> http://www.talend.com
>
>

Reply via email to