2015-02-13 11:17 GMT+01:00 Christian Schneider <ch...@die-schneider.net>:
> On 13.02.2015 10:43, Guillaume Nodet wrote: > >> >> >> I think you did not understand the concept of *clean* shutdown which I'm >> trying to explain. >> I think there's a big difference between reacting to the fact that the >> database connection has been lost, which is out of your control and the >> only thing you can do is stop your own services asap, and cleanly shut >> down >> your application. >> >> Let's tale again my example where we have bundle B which is a service >> exposed to the outside world and bundle A, a JPA layer. If I want to >> update bundle A and I simply call bundleA.update(), this will cause users >> of bundleB to have their calls fail. What we really need is the >> following: >> * stop any new users to use bundle B >> * wait until all calls from bundle B to finish >> * stop bundles A and B (which are not actively used anymore) >> * update bundle A >> >> I think an update of bundleA should simply work without issues. > > From what I understood the following would happen. > - bundleA stops which should not affect inflight processing inside bundle A > - If bundle B uses blueprint then new calls to bundle A will block > - bundleA is replaced and started > - Calls from bundle B continue again > > So I think we do not have a problem in this case. 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). > > > > >>> This means that in order to stop A, I think you want to quiesce A and >>> B. >>> >>>> One problem with blueprint, and it may be an implementation problem, is >>>> the >>>> following. I just made a test with the blueprint-testquiescebundle which >>>> exposes a simple bean with a sleep method through blueprint. If I call >>>> it >>>> with a long sleep, and I concurrently stop the bundle, the bean will >>>> continue executing while the bundle is already stopped. That's quite bad >>>> actually. >>>> >>>> I think it is absolutely fine that threads of a bundle that stops or is >>> even uninstalled continue to run. We might want to interrupt them so a >>> sleep returns earlier but even if the sleep continues I do not see an >>> immediate problem. It would just prevent the classloader from cleaning up >>> the bundle classses for some time. Btw. I think having such a long sleep >>> is >>> an implementation problem that OSGi does not need to fix. >>> >> >> Uh, no that's clearly not fine. BundleActivator#stop() says the following: >> >> /** >> * Called when this bundle is stopped so the Framework can perform the >> * bundle-specific activities necessary to stop the bundle. In general, >> this >> * method should undo the work that the {@code BundleActivator.start} >> * method started. There should be no active threads that were started by >> * this bundle when this bundle returns. A stopped bundle must not call >> any >> * Framework objects. >> * >> * <p> >> * This method must complete and return to its caller in a timely manner. >> */ >> >> So, we can infer the following things: >> * you're not allowed to wait for quite a long time to cleanly wait for >> things to be ready to be stopped >> * you're not allowed to leave threads running >> >> This leads to the conclusion that the OSGi api is not sufficient to cover >> clean shutdown of bundles. I think the quiesce api aims to solve this >> problem. I'm not saying it can't be improved or implemented differently, >> I'm just trying to expose what I think is the purpose of this api. >> > 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. > > So I think the OSGi API is fine and I still see no need for Quiesce. > ... and honestly if the OSGi was not able to cover this quite typical case > then it would be really bad and we should not use OSGi. > If we are not sure then I propose we forward this question to the OSGi dev > list and ask for some advice there. Before doing that, we need to understand each other, and that's not the case yet. > > > >> >> >> I agree, I'm not sure to fully understand it. That does not mean we >> should >> get rid of it just because we don't understand it ;-) >> > I agree. The problem is though if we have no one who understands it then > we have a big problem when moving on. > > So my point of view is that we either have someone who understands it or > at least have the use cases documented. If both is not the case then > I indeed would rather like to get rid of Quiesce. Of course not in a bug > fix or minor version. It should be ok for a major version though. > > > Christian > > -- > Christian Schneider > http://www.liquid-reality.de > > Open Source Architect > http://www.talend.com > >