You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "Steven E. Harris" <se...@panix.com> on 2007/02/09 00:28:39 UTC

OBR Resolver.deploy() and framework start level

I've discovered behavior in Felix and its OBR implementation that
seems wrong to me, and I'd like to figure out whether it's a bug or
working as intended.

First, the scenario: Say that an application wishes to deploy a bundle
using the OBR, and it knows the bundle's symbolic name. It uses a
filter like

  (symbolicname=my.bundle)

fed to RepositoryAdmin.discoverResources(), then feeds the returned
Resources to Resolver.resolve() and, upon a successful return, calls
on Resolver.deploy(true). The boolean parameter passed to
Resolver.deploy() indicates whether to start all the bundles deployed.

This all works fine the first time. The bundle "my.bundle" gets
installed and marked to be started (as the current start level may be
lower than the initial bundle start level), as well as any other
bundles it depends on.

Now, say that I stop the "my.bundle" bundle and shut down the
framework, but I leave the cache in place. The next time I start the
framework, if we try to deploy the same "my.bundle" bundle, OBR
correctly figures out that it's already present locally, and checks to
see if it can be updated. If so, it compares the OBR-provided Resource
to the locally-installed bundle. If they match, the deploy() method
moves on, doing nothing further with this bundle.¹ That is, deploy()
does not mark the already-installed bundle to be started.

If we then raise the framework start level high enough to include this
(re-)deployed bundle, it doesn't start, apparently because it had been
stopped in some prior run. But reading the OSGi R4 Start Level Service
Specification, it sounds like even a previously-stopped bundle should
be started:

,----[ OSGi Start Level Service Specification, Section 8.2.2 ]
| If the requested start level is higher than the active start level,
| the Framework must increase the start level by one and then start all
| bundles that meet the following criteria:
| 
| . Bundles that are persistently marked started, and
| . Bundles that have a bundle start level equal to the new active start
|   level.
| 
| The Framework continues increasing the active start level and starting
| the appropriate bundles until it has started all bundles with a bundle
| start level that equals the requested start level.
`----

This is really two problems I'm noting at once:

o First, I think that Resolver.deploy() should mark an
  already-installed bundle to be started if called with a true "start"
  parameter.

  Move lines 431-436 in ResolverImpl.java down to line 446 so that a
  local bundle gets started regardless of its eligibility for
  updating. Felix._startBundle() already accommodates restarting an
  already started bundle.

o Second, increasing the start level should start bundles that have
  been previously stopped.

Consider the framework sitting at start level 3, with a bundle with a
start level of 4. The bundle cannot be active. Try to start that
bundle and it gets marked to be started, but the framework start level
is still too low to actually start the bundle. Now raise the framework
start level to 4. The bundle should start.

Now stop the bundle, then lower the start level back down to 3. If we
then raise the framework start level back up to 4, should the bundle
start again? By my reading of the specification, it should, but
by my testing Felix does not start the bundle.

In the specification quote above, the "and" conjunction between the
two bullets is vague. Does this mean that a bundle not persistently
marked started need not be started here, or does such a bundle merely
fail the first condition but satisfy the second? Does "meet the
following criteria" mean that a bundle must meet both conditions or
either condition?

If the behavior of Resolver.deploy() were changed per my suggestion, I
wouldn't care as much how the start level specification is
interpreted, as the bundle wolud be "persistently marked started" as
intended.

I do have a use case in mind that gets foiled by the current behavior,
if we need to add some justification to the inquiry.


Footnotes: 
¹ Look around line 424 in ResolverImpl.java.

-- 
Steven E. Harris

Re: OBR Resolver.deploy() and framework start level

Posted by "Richard S. Hall" <he...@ungoverned.org>.
Steven E. Harris wrote:
> "Richard S. Hall" <he...@ungoverned.org> writes:
>
>   
>> And, in general, it is not a good idea to make expedient decisions
>> because then it is hard to back away from them later.
>>     
>
> I understand.
>
>   
>> The resource gives you the symbolic name and version, which uniquely
>> identifies the bundle.
>>     
>
> Yes, though unfortunately it's still an O(n) search to find the bundle
> this way.
>
> [...]
>   

True, but I would assume that n is reasonably small since we are talking 
about installed bundles...even a 1000 or so shouldn't be an issue. If it 
is, you can easily construct your own map of installed bundles to search 
faster, since it isn't optimized under the covers either for quick 
lookup by symbolic name and version.

>> There is no association between a resource and an installed bundle
>> under the covers as you imply other than this.
>>     
>
> By "association", I was referring to the body of the Resolver.deploy()
> function which, while building its "start list" in the present
> incarnation, is able to get an actual Bundle instance in hand for each
> Resource it's operating on. It could return this "start list" to the
> caller as a Set<Bundle> or Bundle[], but we'd still be arguing over
> whether already-installed Bundles should be included in the returned
> list.
>
>   
>> A thought, I could imagine another possibility, where the deploy()
>> method could return some sort of mapping between its resources and
>> the bundles it deployed or there could be another method that
>> returned this mapping after deploy() was invoked, since the resolver
>> would be able to construct this mapping while deploying the
>> resources.
>>     
>
> Yes, that's what I'm alluding to above. It could be the return value
> from deploy(), which at the moment only returns void, or it could be
> fetched by a subsequent method call if constructing the mapping is too
> expensive to do by default (even though it is best built during the
> deploy() method).
>
> As for whether it's a mapping from Resource->Bundle or just the
> Bundles themselves, I don't see much of a difference for my use
> case. I just want the Bundles.

Well, I am not against such an extension. We could always sub-class the 
resolver interface so we don't break from the "official" interface and 
add a method to get this mapping post-deploy().

I also think the resolver interface needs to be extended pre-deploy() to 
give a better indication of what will be installed and what will be 
updated (and possibly in the future, removed)...that is another 
different, but related issue.

-> richard

Re: OBR Resolver.deploy() and framework start level

Posted by "Steven E. Harris" <se...@panix.com>.
"Richard S. Hall" <he...@ungoverned.org> writes:

> And, in general, it is not a good idea to make expedient decisions
> because then it is hard to back away from them later.

I understand.

> The resource gives you the symbolic name and version, which uniquely
> identifies the bundle.

Yes, though unfortunately it's still an O(n) search to find the bundle
this way.

[...]

> There is no association between a resource and an installed bundle
> under the covers as you imply other than this.

By "association", I was referring to the body of the Resolver.deploy()
function which, while building its "start list" in the present
incarnation, is able to get an actual Bundle instance in hand for each
Resource it's operating on. It could return this "start list" to the
caller as a Set<Bundle> or Bundle[], but we'd still be arguing over
whether already-installed Bundles should be included in the returned
list.

> A thought, I could imagine another possibility, where the deploy()
> method could return some sort of mapping between its resources and
> the bundles it deployed or there could be another method that
> returned this mapping after deploy() was invoked, since the resolver
> would be able to construct this mapping while deploying the
> resources.

Yes, that's what I'm alluding to above. It could be the return value
from deploy(), which at the moment only returns void, or it could be
fetched by a subsequent method call if constructing the mapping is too
expensive to do by default (even though it is best built during the
deploy() method).

As for whether it's a mapping from Resource->Bundle or just the
Bundles themselves, I don't see much of a difference for my use
case. I just want the Bundles.

-- 
Steven E. Harris

Re: OBR Resolver.deploy() and framework start level

Posted by "Richard S. Hall" <he...@ungoverned.org>.
Steven E. Harris wrote:
> "Richard S. Hall" <he...@ungoverned.org> writes:
>
>   
>> In truth, I wasn't much of a fan of the whole "start" flag in the
>> first place. I think OBR should be a deployment tool only.
>>     
>
> That would be fine, but at present there's no connection in the OBR
> interface between the Resources consumed and exposed and what actually
> gets deployed -- the actual Bundle instances. OBR talks in Resources,
> which are obviously related to Bundles, but, as I've made much noise
> about here, jumping back and forth between the two is not well
> supported.
>
> Are you suggesting removing the "start" flag from the OBR Resolver?
>   

Well, I wouldn't be against it. The main reason it is there is to have 
some capability with OBR1, which had the capability. In fact, when I 
first did OBR1, it didn't have the capability either and I believe 
someone requested it.

> That's exactly what I need: Some way to identify the transitive
> closure of the bundles involved in a deployment. I don't care whether
> the bundle was already installed or if it just got downloaded; I want
> to start them all, or stated alternately, make sure they are all
> marked to be started.
>
> But now we're talking again about hypothetical future facilities. I
> arrived at the problem in this thread by more or less giving up on the
> other deployment approach I've described, trying to stick to the
> facilities available today. And now we're considering removing another
> facility, pushing success even further away.
>   

Sorry, that's certainly not the goal. We have limited resources, so it 
is hard to get everything done at once. And, in general, it is not a 
good idea to make expedient decisions because then it is hard to back 
away from them later.

> Here's the problem with removing the "start" flag: How does the user
> know which Bundles got deployed? The Resolver.getAddedResources(),
> Resolver.getRequiredResources(), and Resolver.getOptionalResources()
> methods give the set of which /Resources/ were deployed, but we can't
> get from a Resource to a Bundle. (Just as I've been pining for a way
> to get from a Bundle to a Resource.)
>   

The resource gives you the symbolic name and version, which uniquely 
identifies the bundle.

> The only way I see to map a Resource to a Bundle is to call
> BundleContext.getBundles(), the walk the array, looking for one that
> "matches" the Resource, I guess by way of symbolic name and
> version. Again, that seems like too much work for the /user/, trying
> to make these vague associations between the "world of the OSGi
> framework" and the "world of OBR", when under the covers these
> associations are already established.
>
> I'm not complaining about having to call Bundle.start() myself. I'm
> complaining about how I'm supposed to get the Bundle in hand.
>   

I believe there is a PackageAdmin method to get a bundle by symbolic 
name and version, but all it does is loop through the installed bundles 
like you describe. There is no association between a resource and an 
installed bundle under the covers as you imply other than this. At some 
point, someone needs to write the low-level mechanism and then someone 
else needs to write the next layer on top of that and so on. Right now, 
we are at the lower layers, that's all.

A thought, I could imagine another possibility, where the deploy() 
method could return some sort of mapping between its resources and the 
bundles it deployed or there could be another method that returned this 
mapping after deploy() was invoked, since the resolver would be able to 
construct this mapping while deploying the resources.

-> richard

Re: OBR Resolver.deploy() and framework start level

Posted by "Steven E. Harris" <se...@panix.com>.
"Richard S. Hall" <he...@ungoverned.org> writes:

> In truth, I wasn't much of a fan of the whole "start" flag in the
> first place. I think OBR should be a deployment tool only.

That would be fine, but at present there's no connection in the OBR
interface between the Resources consumed and exposed and what actually
gets deployed -- the actual Bundle instances. OBR talks in Resources,
which are obviously related to Bundles, but, as I've made much noise
about here, jumping back and forth between the two is not well
supported.

Are you suggesting removing the "start" flag from the OBR Resolver?

> Imagine some tool that allowed you to use OBR to deploy a resolved
> set of bundles and assign a name to that resolved set of
> bundles. Then you could use this tool to start/stop/uninstall that
> named set of bundles, for example.

That's exactly what I need: Some way to identify the transitive
closure of the bundles involved in a deployment. I don't care whether
the bundle was already installed or if it just got downloaded; I want
to start them all, or stated alternately, make sure they are all
marked to be started.

But now we're talking again about hypothetical future facilities. I
arrived at the problem in this thread by more or less giving up on the
other deployment approach I've described, trying to stick to the
facilities available today. And now we're considering removing another
facility, pushing success even further away.


Here's the problem with removing the "start" flag: How does the user
know which Bundles got deployed? The Resolver.getAddedResources(),
Resolver.getRequiredResources(), and Resolver.getOptionalResources()
methods give the set of which /Resources/ were deployed, but we can't
get from a Resource to a Bundle. (Just as I've been pining for a way
to get from a Bundle to a Resource.)

The only way I see to map a Resource to a Bundle is to call
BundleContext.getBundles(), the walk the array, looking for one that
"matches" the Resource, I guess by way of symbolic name and
version. Again, that seems like too much work for the /user/, trying
to make these vague associations between the "world of the OSGi
framework" and the "world of OBR", when under the covers these
associations are already established.

I'm not complaining about having to call Bundle.start() myself. I'm
complaining about how I'm supposed to get the Bundle in hand.

-- 
Steven E. Harris

Re: OBR Resolver.deploy() and framework start level

Posted by Felix Meschberger <Fe...@day.com>.
On 2/12/07, Steven E. Harris <se...@panix.com> wrote:
>
> Felix Meschberger <Fe...@day.com> writes:
>
> > Actually, the bundle set descriptor is a bundle itself, which has a
> > special manifest header naming other bundles (or resources in OBR
> > speak) to be managed. The reference is by bundle symbolic name and a
> > version range.
>
> This is interesting. The "set bundle" refers to the other bundles not
> in the abstract (by exported packages), but as concrete references to
> symbolic name and version. It sounds kind of like the Require-Bundle
> header. Is there a reason why you don't use Require-Bundle, other than
> it not having been implemented in Felix until recently?


The "Set Bundle" is - conceptually - not the same as the Require-Bundle
thing. Require-Bundle to me is more like another way of expressing real code
dependency (which IMHO is better done through Import-Package...). The bundle
list of a "Set Bundle" is more like installation instructions targeted at a
management agent (bundle).

Unlike Require-Bundle not only the symbolic names and versions of the bundle
to install but also the start level and whether the installed bundles are to
be started/stopped when the "Set Bundle" is started/stopped may be specified
and whether the bundles to install are contained as entries in the "Set
Bundle" itself is declared in the "Set Bundle". This goes beyond the
functionality of Require-Bundle.

Does the "set bundle" start all its related bundles when it itself is
> told to start, and stop all the others when it stops?


Yes, and  the bundles contained in the "Set Bundle" are uninstalled when the
"Set Bundle" is uninstalled. This, however, may be controlled with a flag in
the "Set Bundle" to prevent this "locking into the Set Bundle lifecycle".

Do you deploy this "set bundle" through OBR? If so, it sounds like the
> "set bundle's" bundle associations aren't known to OSGi (being
> specified by this special header you mention above), so how do the
> associated bundles get discovered through OBR? Or does the "set
> bundle" itself use OBR to deploy all its associated bundles?


Yes, as the "Set Bundle" is a normal bundle. And yes, the depdencies are not
known to OBR, as these are not declared in the "Set Bundle". Instead, the
management agent recognizes the installation of the "Set Bundle" and handles
the next steps accordingly, including getting the bundles referred to by the
"Set Bundle" and their dependencies from the OBR. It is more like a two-step
process.

BTW: We call these "Set Bundles" "Assembly Bundles" or "Assembly" for short
- lacking a better name :-) [ On the other hand "Bundle Set" does not sound
too bad ]

Regards
Felix

Re: OBR Resolver.deploy() and framework start level

Posted by "Steven E. Harris" <se...@panix.com>.
Felix Meschberger <Fe...@day.com> writes:

> Actually, the bundle set descriptor is a bundle itself, which has a
> special manifest header naming other bundles (or resources in OBR
> speak) to be managed. The reference is by bundle symbolic name and a
> version range.

This is interesting. The "set bundle" refers to the other bundles not
in the abstract (by exported packages), but as concrete references to
symbolic name and version. It sounds kind of like the Require-Bundle
header. Is there a reason why you don't use Require-Bundle, other than
it not having been implemented in Felix until recently?

Does the "set bundle" start all its related bundles when it itself is
told to start, and stop all the others when it stops?

Do you deploy this "set bundle" through OBR? If so, it sounds like the
"set bundle's" bundle associations aren't known to OSGi (being
specified by this special header you mention above), so how do the
associated bundles get discovered through OBR? Or does the "set
bundle" itself use OBR to deploy all its associated bundles?

> For each of the resources I take its symbolic name and version to
> find the matching bundle - through PackageAdmin as Richard notes in
> another mail or simply looping through the bundles.

I see. Thanks for clarifying.

-- 
Steven E. Harris

Re: OBR Resolver.deploy() and framework start level

Posted by Felix Meschberger <Fe...@day.com>.
Hi,

On 2/10/07, Steven E. Harris <se...@panix.com> wrote:
>
> Felix Meschberger <Fe...@day.com> writes:
>
> > In fact we do exactly this at our place: Define bundle sets and have
> > a management agent control the lifecycle
>
> What defines a set of bundles? Is it their symbolic names?


Actually, the bundle set descriptor is a bundle itself, which has a special
manifest header naming other bundles (or resources in OBR speak) to be
managed. The reference is by bundle symbolic name and a version range.

> and just use OBR to get the bundles in the first place and make sure
> > any required bundles are also retrieved.
>
> How do you know which bundles were retrieved? Are you using
> Resolver.getRequiredResources()? If so, how do you get from a Resource
> to a Bundle?


I check the Resolver.getAddedResources(), Resolver.getRequiredResources()
and Resovler.getOptionalResources(). For each of the resources I take its
symbolic name and version to find the matching bundle - through PackageAdmin
as Richard notes in another mail or simply looping through the bundles.

Also, do you worry about controlling the life-cycle of the required
> bundles that weren't part of your original set? That is, if your
> bundle set A contains bundles "foo" and "bar", but "bar" turns out to
> require "baz", do you add "baz" to set A's life-cycle operations?


No, "baz" is just started and assigned a startlevel which is equal to the
lowest startlevel of any of the bundles contained in the set.

Regards
Felix

Re: OBR Resolver.deploy() and framework start level

Posted by "Steven E. Harris" <se...@panix.com>.
Felix Meschberger <Fe...@day.com> writes:

> In fact we do exactly this at our place: Define bundle sets and have
> a management agent control the lifecycle

What defines a set of bundles? Is it their symbolic names?

> and just use OBR to get the bundles in the first place and make sure
> any required bundles are also retrieved.

How do you know which bundles were retrieved? Are you using
Resolver.getRequiredResources()? If so, how do you get from a Resource
to a Bundle?

Also, do you worry about controlling the life-cycle of the required
bundles that weren't part of your original set? That is, if your
bundle set A contains bundles "foo" and "bar", but "bar" turns out to
require "baz", do you add "baz" to set A's life-cycle operations?

-- 
Steven E. Harris

Re: OBR Resolver.deploy() and framework start level

Posted by Felix Meschberger <Fe...@day.com>.
Hi,

On 2/10/07, Richard S. Hall <he...@ungoverned.org> wrote:
>
> [....] I think OBR should be a deployment tool only. I think it should
> be kept as simple as possible, but no simpler to its job. We can create
> another tool to manage the run-time life cycles of bundles...


This is exactly, what I was going to say. Hence I completely agree.

Imagine some tool that allowed you to use OBR to deploy a resolved set
> of bundles and assign a name to that resolved set of bundles. Then you
> could use this tool to start/stop/uninstall that named set of bundles,
> for example.


In fact we do exactly this at our place: Define bundle sets and have a
management agent control the lifecycle and just use OBR to get the bundles
in the first place and make sure any required bundles are also retrieved.

Regards
Felix

Re: OBR Resolver.deploy() and framework start level

Posted by "Richard S. Hall" <he...@ungoverned.org>.
Niclas Hedhman wrote:
> On Friday 09 February 2007 07:28, Steven E. Harris wrote:
>   
>> o First, I think that Resolver.deploy() should mark an
>>   already-installed bundle to be started if called with a true "start"
>>   parameter.
>>     
>
> Doesn't the whole issue get resolved if you call a start() method explicitly 
> after a deploy??
>
>
> I have not worked with OBR yet, so not sure if such exist; If not, perhaps 
> there should be.
>   

In truth, I wasn't much of a fan of the whole "start" flag in the first 
place. I think OBR should be a deployment tool only. I think it should 
be kept as simple as possible, but no simpler to its job. We can create 
another tool to manage the run-time life cycles of bundles...

Imagine some tool that allowed you to use OBR to deploy a resolved set 
of bundles and assign a name to that resolved set of bundles. Then you 
could use this tool to start/stop/uninstall that named set of bundles, 
for example.

-> richard

Re: OBR Resolver.deploy() and framework start level

Posted by Niclas Hedhman <ni...@hedhman.org>.
On Friday 09 February 2007 07:28, Steven E. Harris wrote:
> o First, I think that Resolver.deploy() should mark an
>   already-installed bundle to be started if called with a true "start"
>   parameter.

Doesn't the whole issue get resolved if you call a start() method explicitly 
after a deploy??


I have not worked with OBR yet, so not sure if such exist; If not, perhaps 
there should be.


Cheers
Niclas

Re: OBR Resolver.deploy() and framework start level

Posted by "Richard S. Hall" <he...@ungoverned.org>.
Steven E. Harris wrote:
> "Richard S. Hall" <he...@ungoverned.org> writes:
>
>   
>> At worst, I think that it should be possible for you to create your
>> own shell command (or direct functionality in your management agent)
>> that does the deploy like the current command then add an additional
>> step to loop through and start all resources referenced by the
>> resolver object.
>>     
>
> Possible, yes, but per my parallel reply to Mr. Meschberger, doesn't
> this redo the work implied by the Resolver.deploy() "start" parameter?
> If there was no such parameter, and no implementation that /almost/
> achieves what I'm after, I'd take this responsibility in stride. That
> the current implementation doesn't go this far looks like a small bug
> and shouldn't warrant each user redoing this work.

I guess this is what is up for debate... :-)

I will listen to you guys argue (and anyone else who wants to jump in) 
before I formulate my opinion.

-> richard

Re: OBR Resolver.deploy() and framework start level

Posted by "Steven E. Harris" <se...@panix.com>.
"Richard S. Hall" <he...@ungoverned.org> writes:

> At worst, I think that it should be possible for you to create your
> own shell command (or direct functionality in your management agent)
> that does the deploy like the current command then add an additional
> step to loop through and start all resources referenced by the
> resolver object.

Possible, yes, but per my parallel reply to Mr. Meschberger, doesn't
this redo the work implied by the Resolver.deploy() "start" parameter?
If there was no such parameter, and no implementation that /almost/
achieves what I'm after, I'd take this responsibility in stride. That
the current implementation doesn't go this far looks like a small bug
and shouldn't warrant each user redoing this work.

-- 
Steven E. Harris

Re: OBR Resolver.deploy() and framework start level

Posted by "Richard S. Hall" <he...@ungoverned.org>.
Felix Meschberger wrote:
> Hi Steven,
>
> Let me comment your second question first:
>
> There is a tiny little adjective in the spec: "permanently marked". 
> So, when
> you start a bundle, regardless of it actually startes or not due to start
> level restrictions, the bundle is permanently marked started. If you stop
> the bundle, the bundle is stopped (if not started) and permanently marked
> stopped.
>
> If stop and restart the framework, the bundle is still permanently makred
> stopped and will not be started even though it could be started as per 
> the
> start level.
>
> Consequently, the system works as specified.

Agreed.

> Regarding, whether Resolver.deploy(boolean) should start resources 
> added to
> the resolver but not selected for deployment: I am more happy with the
> situation of the Resolver not touching the state existing bundles. That
> said, I am in favor of not having the resolver start bundles not 
> elected for
> deployment.

I don't have a strong feeling on this. Part of my thinks you should 
honor the state that is there, but I can also see why you might want 
them restarted. I will let you guys argue this out. :-)

At worst, I think that it should be possible for you to create your own 
shell command (or direct functionality in your management agent) that 
does the deploy like the current command then add an additional step to 
loop through and start all resources referenced by the resolver object.

-> richard

>
> Regards
> Felix
>
> On 2/9/07, Steven E. Harris <se...@panix.com> wrote:
>>
>> I've discovered behavior in Felix and its OBR implementation that
>> seems wrong to me, and I'd like to figure out whether it's a bug or
>> working as intended.
>>
>> First, the scenario: Say that an application wishes to deploy a bundle
>> using the OBR, and it knows the bundle's symbolic name. It uses a
>> filter like
>>
>>   (symbolicname=my.bundle)
>>
>> fed to RepositoryAdmin.discoverResources(), then feeds the returned
>> Resources to Resolver.resolve() and, upon a successful return, calls
>> on Resolver.deploy(true). The boolean parameter passed to
>> Resolver.deploy() indicates whether to start all the bundles deployed.
>>
>> This all works fine the first time. The bundle "my.bundle" gets
>> installed and marked to be started (as the current start level may be
>> lower than the initial bundle start level), as well as any other
>> bundles it depends on.
>>
>> Now, say that I stop the "my.bundle" bundle and shut down the
>> framework, but I leave the cache in place. The next time I start the
>> framework, if we try to deploy the same "my.bundle" bundle, OBR
>> correctly figures out that it's already present locally, and checks to
>> see if it can be updated. If so, it compares the OBR-provided Resource
>> to the locally-installed bundle. If they match, the deploy() method
>> moves on, doing nothing further with this bundle.¹ That is, deploy()
>> does not mark the already-installed bundle to be started.
>>
>> If we then raise the framework start level high enough to include this
>> (re-)deployed bundle, it doesn't start, apparently because it had been
>> stopped in some prior run. But reading the OSGi R4 Start Level Service
>> Specification, it sounds like even a previously-stopped bundle should
>> be started:
>>
>> ,----[ OSGi Start Level Service Specification, Section 8.2.2 ]
>> | If the requested start level is higher than the active start level,
>> | the Framework must increase the start level by one and then start all
>> | bundles that meet the following criteria:
>> |
>> | . Bundles that are persistently marked started, and
>> | . Bundles that have a bundle start level equal to the new active start
>> |   level.
>> |
>> | The Framework continues increasing the active start level and starting
>> | the appropriate bundles until it has started all bundles with a bundle
>> | start level that equals the requested start level.
>> `----
>>
>> This is really two problems I'm noting at once:
>>
>> o First, I think that Resolver.deploy() should mark an
>>   already-installed bundle to be started if called with a true "start"
>>   parameter.
>>
>>   Move lines 431-436 in ResolverImpl.java down to line 446 so that a
>>   local bundle gets started regardless of its eligibility for
>>   updating. Felix._startBundle() already accommodates restarting an
>>   already started bundle.
>>
>> o Second, increasing the start level should start bundles that have
>>   been previously stopped.
>>
>> Consider the framework sitting at start level 3, with a bundle with a
>> start level of 4. The bundle cannot be active. Try to start that
>> bundle and it gets marked to be started, but the framework start level
>> is still too low to actually start the bundle. Now raise the framework
>> start level to 4. The bundle should start.
>>
>> Now stop the bundle, then lower the start level back down to 3. If we
>> then raise the framework start level back up to 4, should the bundle
>> start again? By my reading of the specification, it should, but
>> by my testing Felix does not start the bundle.
>>
>> In the specification quote above, the "and" conjunction between the
>> two bullets is vague. Does this mean that a bundle not persistently
>> marked started need not be started here, or does such a bundle merely
>> fail the first condition but satisfy the second? Does "meet the
>> following criteria" mean that a bundle must meet both conditions or
>> either condition?
>>
>> If the behavior of Resolver.deploy() were changed per my suggestion, I
>> wouldn't care as much how the start level specification is
>> interpreted, as the bundle wolud be "persistently marked started" as
>> intended.
>>
>> I do have a use case in mind that gets foiled by the current behavior,
>> if we need to add some justification to the inquiry.
>>
>>
>> Footnotes:
>> ¹ Look around line 424 in ResolverImpl.java.
>>
>> -- 
>> Steven E. Harris
>>
>

Re: OBR Resolver.deploy() and framework start level

Posted by "Steven E. Harris" <se...@panix.com>.
Felix Meschberger <Fe...@day.com> writes:

> If you stop the bundle, the bundle is stopped (if not started) and
> permanently marked stopped.

That started to dawn on me as I was finishing writing my message: the
absence of being permanently marked as started is the same as being
permanently marked as stopped. I never found this asserted in the
specification, but it's the behavior exhibited by Felix as of now.

> If stop and restart the framework, the bundle is still permanently
> makred stopped and will not be started even though it could be
> started as per the start level.
>
> Consequently, the system works as specified.

I follow your logic, per the assertion about permanent marking above.

> Regarding, whether Resolver.deploy(boolean) should start resources
> added to the resolver but not selected for deployment: I am more
> happy with the situation of the Resolver not touching the state
> existing bundles. That said, I am in favor of not having the
> resolver start bundles not elected for deployment.

Where we differ here is in the "not elected for deployment"
qualifier. I'll describe my anticipated use case and see if my
preference still holds up through the description.

In my system, the application running the OSGi framework is a client
to a server that provides bundles for download, and directs the client
to "make use of" certain bundles. The server will tell the client to
use bundles "foo" and "bar" today, where these bundles should be
installed (if not already), started, and certain advertised services
provided by the bundles and detected by the application should be
used. Once these services have been used once, the bundles can be
stopped and even uninstalled, but for now I'm assuming the bundles are
just stopped.

The next time the application runs, it may be directed by the server
to "make use of" bundles "foo" and "quux". The second one would need
to be downloaded, but the first one is still installed from a previous
run. If the application operates by constructing filters to discover
resources with OBR, it doesn't need to know that "foo" is already
installed and "quux" isn't; the OBR discover-resolve-deploy interface
accommodates ensuring both "foo" and "quux" will be present and
resolvable at the end.

But when the application tries to deploy "foo" and "quux", passing the
true "start" parameter to Resolver.deploy(), "quux" will be started
but "foo" will not be, as "foo" had been stopped on a previous run.

In order to make sure that each of the bundles targeted for deployment
get started, the application would have to inspect the set returned by
Resolver.getRequiredResources(), looking for a symbolic name match to
see if each of its targets are mentioned. Those not mentioned would
then need to be started explicitly. This seems needlessly complex,
especially given the contract implied by the "start" parameter
accepted by Resolver.deploy().

Doesn't supplying a true "start" parameter mean, "Start all of these
up"? The present behavior is more like, "Start up the ones I don't
have, even though I'm not sure which ones those are."

-- 
Steven E. Harris

Re: OBR Resolver.deploy() and framework start level

Posted by Felix Meschberger <Fe...@day.com>.
Hi Steven,

Let me comment your second question first:

There is a tiny little adjective in the spec: "permanently marked". So, when
you start a bundle, regardless of it actually startes or not due to start
level restrictions, the bundle is permanently marked started. If you stop
the bundle, the bundle is stopped (if not started) and permanently marked
stopped.

If stop and restart the framework, the bundle is still permanently makred
stopped and will not be started even though it could be started as per the
start level.

Consequently, the system works as specified.

Regarding, whether Resolver.deploy(boolean) should start resources added to
the resolver but not selected for deployment: I am more happy with the
situation of the Resolver not touching the state existing bundles. That
said, I am in favor of not having the resolver start bundles not elected for
deployment.

Regards
Felix

On 2/9/07, Steven E. Harris <se...@panix.com> wrote:
>
> I've discovered behavior in Felix and its OBR implementation that
> seems wrong to me, and I'd like to figure out whether it's a bug or
> working as intended.
>
> First, the scenario: Say that an application wishes to deploy a bundle
> using the OBR, and it knows the bundle's symbolic name. It uses a
> filter like
>
>   (symbolicname=my.bundle)
>
> fed to RepositoryAdmin.discoverResources(), then feeds the returned
> Resources to Resolver.resolve() and, upon a successful return, calls
> on Resolver.deploy(true). The boolean parameter passed to
> Resolver.deploy() indicates whether to start all the bundles deployed.
>
> This all works fine the first time. The bundle "my.bundle" gets
> installed and marked to be started (as the current start level may be
> lower than the initial bundle start level), as well as any other
> bundles it depends on.
>
> Now, say that I stop the "my.bundle" bundle and shut down the
> framework, but I leave the cache in place. The next time I start the
> framework, if we try to deploy the same "my.bundle" bundle, OBR
> correctly figures out that it's already present locally, and checks to
> see if it can be updated. If so, it compares the OBR-provided Resource
> to the locally-installed bundle. If they match, the deploy() method
> moves on, doing nothing further with this bundle.¹ That is, deploy()
> does not mark the already-installed bundle to be started.
>
> If we then raise the framework start level high enough to include this
> (re-)deployed bundle, it doesn't start, apparently because it had been
> stopped in some prior run. But reading the OSGi R4 Start Level Service
> Specification, it sounds like even a previously-stopped bundle should
> be started:
>
> ,----[ OSGi Start Level Service Specification, Section 8.2.2 ]
> | If the requested start level is higher than the active start level,
> | the Framework must increase the start level by one and then start all
> | bundles that meet the following criteria:
> |
> | . Bundles that are persistently marked started, and
> | . Bundles that have a bundle start level equal to the new active start
> |   level.
> |
> | The Framework continues increasing the active start level and starting
> | the appropriate bundles until it has started all bundles with a bundle
> | start level that equals the requested start level.
> `----
>
> This is really two problems I'm noting at once:
>
> o First, I think that Resolver.deploy() should mark an
>   already-installed bundle to be started if called with a true "start"
>   parameter.
>
>   Move lines 431-436 in ResolverImpl.java down to line 446 so that a
>   local bundle gets started regardless of its eligibility for
>   updating. Felix._startBundle() already accommodates restarting an
>   already started bundle.
>
> o Second, increasing the start level should start bundles that have
>   been previously stopped.
>
> Consider the framework sitting at start level 3, with a bundle with a
> start level of 4. The bundle cannot be active. Try to start that
> bundle and it gets marked to be started, but the framework start level
> is still too low to actually start the bundle. Now raise the framework
> start level to 4. The bundle should start.
>
> Now stop the bundle, then lower the start level back down to 3. If we
> then raise the framework start level back up to 4, should the bundle
> start again? By my reading of the specification, it should, but
> by my testing Felix does not start the bundle.
>
> In the specification quote above, the "and" conjunction between the
> two bullets is vague. Does this mean that a bundle not persistently
> marked started need not be started here, or does such a bundle merely
> fail the first condition but satisfy the second? Does "meet the
> following criteria" mean that a bundle must meet both conditions or
> either condition?
>
> If the behavior of Resolver.deploy() were changed per my suggestion, I
> wouldn't care as much how the start level specification is
> interpreted, as the bundle wolud be "persistently marked started" as
> intended.
>
> I do have a use case in mind that gets foiled by the current behavior,
> if we need to add some justification to the inquiry.
>
>
> Footnotes:
> ¹ Look around line 424 in ResolverImpl.java.
>
> --
> Steven E. Harris
>