I'm looking for guidance on how to deliver on OSGi's promise of
enabling incremental deployment in non-trivial runtimes. This email is
long because I want to provide enough detail for some edge case
discussions.
We have our own (arguably idiosyncratic) approach to provisioning an
OSGi runtime. We have an external runtime model that holds the
normative list of bundles, and when it changes we reconcile the OSGi
runtime to this list of normative bundles. Note that our provisioning
can mix together multiple logical applications that can pull in and
wire multiple versions of the same plugin and packages.
This is very straightforward the first time the framework starts:
there is no cached state, we install all our bundles from the model
and start them all. If the model hasn't changed since we stopped the
framework and then restart it, the framework restores its running
state from the last time it ran and we synchronize to our unchanged
model (a no-op).
If there *are* changes to the model, things get more interesting. My
underlying question is: how we can best synchronize the runtime to our
model with the fewest disruptions?
Edge cases appear to involve:
- start levels
- singletons
- fragments
- extensions (fragments of the system bundle)
- optional dependencies
My first cut installs and starts bundles in the model that are not in
the runtime, uninstalls bundles in the framework that are not in the
runtime, then does a PackageAdmin.refreshPackages(null). My thinking
here is that I want the new bundles to be available when the refresh
"cuts over" to the new content so there is as little disruption as
possible.
Start levels can be messy. If I were king I would declare by fiat that
all our code needs to properly handle starting in any order, and not
use the start level service at all. Alas, I am not king. When I'm
processing the new bundles I actually install and start them in
ascending start level order so that, given the current framework start
level, even new bundles get installed "in the right order."
This basic approach fails for singletons. Imagine singleton v1 in the
runtime. The model changes to replace it with singleton v2. I can
install v2 with v1 still there, but it won't resolve, and I can't
start it until after v1 is uninstalled. [Side question: do I need to
refresh packages after v1 uninstall before I can start v2?] This
implies that I should uninstall old bundles before I install the new
ones. What does this imply about how long dependent bundles will be
"down"?
Fragments are also problematic. Whether a fragment will attach to a
resolved host bundle depends on many factors, including the host's
fragment-attachment directive, the fragment dependencies, and what the
fragment exports. If the synchronization doesn't want to crawl the
implications of all this, would I need to unresolve all candidate host
bundles first? Furthermore, unresolving a host bundle that is resolved
doesn't appear possible without first uninstalling it (because
stopping it will just move it to the resolved state).
Extension bundles typically cause the entire framework to need
restart. This gets really tricky because when you do a refresh
packages and there's a new extension bundle, the framework will
actually stop, preventing you from doing further operations.
Optional dependencies are also a killer. Consider package a in bundle
A with an optional dependency on package b in bundle B. Assume we
install bundle A without bundle B. Bundle A resolves, we run, and
there is much rejoicing. Later we update the model to include bundle A
but also bundle B and bundle C, which wants to use the optional
functionality through A. Well, A is already resolved, so it won't
automatically rewire just because we install B, so C can't use the
optional dependency. How do we go about even detecting this?
Are there other edge cases to think about?
Given these edge cases, how do we actually deliver "incremental
update" without some very nasty wiring and dependency grunging? Is
there an easy approach that "just works"?
/djk
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev