2015-02-13 11:17 GMT+01:00 Christian Schneider <[email protected]>:
> 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
>
>