I am not sure I agree with your conclusion. :-)
Since it is theoretically impossible to protect against hard failure (power,
kernel panic, kill -9, distributed call when the cable is plugged, etc) any
valuable application must have protection against an unexpected exit at any
moment in time. Idempotency, consensus, and transactionality are your friends
in these cases. So if you are protected against these bad failures, how bad can
an in-flight shutdown be? Best case you can shorten the recovery time at
restart but this often requires additional complexity that can then also fail.
Since the chance that things go wrong in-flight is quite small I would take the
recovery cost in the unlikely event you got caught.
Related is my very old opposition to an update or uninstall callback to the
bundle. Though it is an awfully attractive idea with lots of good stuff the
party is spoiled because you cannot guarantee such a call circumstances.
Billy Joy (Sun Founder) once told us a story about the development of the
Internet, of which he took part. Initially they tried to make every router
perfect but this turned the routers incredibly expensive and there were still
failure scenarios that even a perfect router could not handle (power, cable
cuts). Then someone proposed to assume the routers were very imperfect and that
the end points should correct the problems in the net. This changed a very
large number of very hard to handle failure scenario into one problem: how to
handle a missing package. If a router panicked, lost power, a cable was cost,
too busy, out of memory, had no clue: discard the package.
It is a pervasive problem in Enterprise software world that we want to ignore
failure because it is so hard. For example, Blueprint has this awful service
damping that looks so attractive for the developer (Look Ma, no dynamics!) but
by hiding the reality you get caught in lots of unexpected places.
Bad software expects an unchanging perfect world, good software is more
realistic. Embrace failure! :-)
Kind regards,
Peter Kriens
> On 15 feb. 2015, at 11:09, Christian Schneider <[email protected]>
> wrote:
>
> Thanks to all of you for the insights.
>
> From the responses I take that clean shutdown is not in scope of OSGi itself.
> I agree that it is best solved on the application level. On the other hand I
> see that the Quiesce API can at least cover some
> cases and so it has its values.
>
> Christian
>
> Am 13.02.2015 um 17:55 schrieb Raymond Auge:
>> To my knowledge what you are speaking of is not intentionally supported by
>> the dynamics of osgi. This topic comes up all the time, it's funny.
>>
>> If you must support "in flight" changes, then you have to implement this
>> support in your code using concurrency constructs.
>>
>> Note that unregistering a service is a synchronous operation during
>> "shutdown" of a bundle, and so with proper concurrency measures in place, a
>> bundle could both be shutting down (meaning it's not reachable by other
>> bundles) and also finishing any ongoing work.
>>
>> Anyone feel free to correct me but this is what I've learned in my short
>> experience.
>>
>> - Ray
>>
>> On Fri, Feb 13, 2015 at 11:37 AM, Christian Schneider
>> <[email protected] <mailto:[email protected]>> wrote:
>> I had a longer discussion with Guillaume Nodet about how to shut down
>> bundles cleanly. The main question was if you can cleanly shut down bundles
>> with just the OSGi APIs or if we are missing something.
>>
>> So the thing to define is: what does clean shutdown mean? Clean would refer
>> to the fact that none of the inflight calls the bundle processes are
>> disturbed.
>>
>> Case A
>> So what could happen. In the simplest case a bundle might simply process a
>> long running service call.
>>
>> 1. The call started before the bundle was stopped
>> 2. Then the bundle is stopped
>> 3. The bundle is refreshed or uninstalled
>> 4. At some later point the call finishes
>>
>> So what happens with the inflight call after 3?
>> Can the running thread still work normally?
>>
>> One issue that might arise is that during stop the bundle might have shut
>> down some needed resources. This is in control of the developer, so I think
>> it should be no big issue.
>> The question though is what happens to the Classloader of the bundle?
>> The stop operation should be no problem here but what about refresh, update
>> or uninstall? Does this old classloader still work then?
>> If the classloader does not work anymore how should this case be handled?
>> Does the bundle have to make sure all inflight processing is done before
>> stop is finished?
>>
>>
>> Case B
>> This could be even more complex when you have chained service calls.
>> Service A1 in bundle A calls service B1 in bundle B
>>
>> 1. Service call in A1 starts processing
>> 2 Bundle B is stopped
>> 3. bundle B is uninstalled
>> 3. Service A1 tries to call service B
>>
>> For blueprint I know that the call to service B will block because of the
>> service damping.
>> What happens in DS here? Normally DS would stop Service A1 when the Service
>> B1 disappears but the call to service A1 already started.
>> I think that in this case Service A1 will still have an instance of B1
>> injected. So the call to B1 will probably happen, even if B1 was uninstalled
>> in the mean time.
>> So I think we might have the same classloader issue as in the first case.
>> The problem is though that bundle B cannot defer stopping because it does
>> not see an inflight call at the point where it stops.
>>
>> I think one solution to avoid Case B could be to stop bundles according to
>> their service dependencies. So you would first stop bundle B then bundle A.
>> Is this the recommended solution? Is this already automated in OSGi in some
>> way?
>>
>>
>> Case C
>> An even more complicated case is when one or more extenders are involved
>> that create services on behalf of the bundles. Are there any best practices
>> around this?
>>
>> I have seen that there is the Quiesce API in aries that seems to cover
>> shutting down bundles when extenders are involved.
>> See
>> https://github.com/apache/aries/blob/trunk/quiesce/quiesce-api/src/main/java/org/apache/aries/quiesce/participant/QuiesceParticipant.java
>>
>> <https://github.com/apache/aries/blob/trunk/quiesce/quiesce-api/src/main/java/org/apache/aries/quiesce/participant/QuiesceParticipant.java>
>>
>> The API seems to be aries specific though. Is something like that necessary
>> or should plain OSGi APIs offer enough flexibility for this case too?
>>
>> Christian
>>
>> --
>> Christian Schneider
>> http://www.liquid-reality.de <http://www.liquid-reality.de/>
>>
>> Open Source Architect
>> http://www.talend.com <http://www.talend.com/>
>>
>> _______________________________________________
>> OSGi Developer Mail List
>> [email protected] <mailto:[email protected]>
>> https://mail.osgi.org/mailman/listinfo/osgi-dev
>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>>
>>
>>
>> --
>> Raymond Augé <http://www.liferay.com/web/raymond.auge/profile> (@rotty3000)
>> Senior Software Architect Liferay, Inc. <http://www.liferay.com/> (@Liferay)
>> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org/> (@OSGiAlliance)
>>
>>
>> _______________________________________________
>> OSGi Developer Mail List
>> [email protected] <mailto:[email protected]>
>> https://mail.osgi.org/mailman/listinfo/osgi-dev
>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>
> --
>
> Christian Schneider
> http://www.liquid-reality.de <http://www.liquid-reality.de/>
>
> Open Source Architect
> Talend Application Integration Division http://www.talend.com
> <http://www.talend.com/>
> _______________________________________________
> OSGi Developer Mail List
> [email protected]
> https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev