Which lifecycle annotation for when all associations have been injected?

1 view
Skip to first unread message

Dawid Loubser

unread,
Feb 22, 2012, 9:59:54 AM2/22/12
to Rio Users Group
Hello fellow Rio/JavaSpaces users,

Imagine I deploy a service bean that starts a loop to read entries
from a JavaSpace:

At the time my service bean method annotated with @Started gets
called, the association proxies have not yet been injected (i.e. I
have to write complex code to wait until I have an association proxy,
on top of the different code I have to write to deal with the fact
that the association proxy is in a broken state because the service
has disappeared, etc). There isn't a single paradigm to deal with here
at a code level, to deal with the different options:

- The association has not yet been injected, because it's never been
discovered
- The association is injected, but when you call a service on it, it
throws RemoteException because
- The association is injected, but the service has subsequently
disappeared, and all calls will fail until it is re-discovered

I have historically been using @PreAdvertise for my start method,
because this seems to be called only after all the association proxies
have been injected. However, I do unit/integration testing using a
StaticSybernode, and it seems that, for a given runtime session (Java
VM?) it only ever calls the @PreAdvertise annotated method once - even
if I create a new StaticCybernode and re-deploy the opstring before
running the next test. Is this some sort of a bug where a handle is
kept in a class variable in StaticCybernode or something?

Anyway, I am just looking for a bit of advice. I'd like it if the
members on my team wouldn't have to use Locks and Conditions to delay
processing until the association proxies have been injected, and then
on top of it, deal with the usual potential problems of remote method
calls.

Does Rio provide any infrastructure to help, for example, to wait
until we have association proxies to ServiceX and ServiceY injected,
before we perform work that requires both?

I understand that the question I pose in the title might be a fallacy
- there might never be a lifecycle event when "all required
associations are satisfied" because that condition might change a
moment later in anyway. It's still an interesting problem, and one
which one wants to make as easy as possible for developers to work
with.

regards,
Dawid

Dennis Reedy

unread,
Feb 22, 2012, 10:11:58 AM2/22/12
to rio-...@googlegroups.com
Are your associations uses or requires?

Dawid Loubser

unread,
Feb 22, 2012, 10:40:07 AM2/22/12
to Rio Users Group
Requires - but I am thinking now of switching to uses (because the
only sense that "requires" would really make in Jini is if Rio also
actually stopped your component when all required associations are not
available, and restarted it later). Otherwise, one has to in anyway
cater for the fact that they could come and go. So I am seeing the
value in "requires" only in terms of startup (i.e. the waiting to call
@PreAdvertise) - but there is definitely a bug in StaticCybernode in
this regard, I can only run one test (ever) per VM invocation.

I am about to proof this, but will "uses" cause Associations them to
be injected earlier (before @Started) ?

I have also made the decision to switch from injecting the bare
services (public void setFoo( Foo foo)) to using your
AssociationProxy<Foo> - one can then write nice code to, for example,
halt a loop processing items off the space based on the state of the
proxy (pending/discovered/changed/broken). if I do this, I am hoping
that those proxies (in a state of, say, PENDING) will be injected by
the time @Started is called?

regards,
Dawid

Dennis Reedy

unread,
Feb 22, 2012, 11:47:39 AM2/22/12
to rio-...@googlegroups.com

On Feb 22, 2012, at 1040AM, Dawid Loubser wrote:

> Requires - but I am thinking now of switching to uses (because the
> only sense that "requires" would really make in Jini is if Rio also
> actually stopped your component when all required associations are not
> available, and restarted it later).

It will not stop your service, but if you use requires it will unadvertise it.

> Otherwise, one has to in anyway
> cater for the fact that they could come and go.

Such is the nature of distributed systems.

> So I am seeing the
> value in "requires" only in terms of startup (i.e. the waiting to call
> @PreAdvertise) - but there is definitely a bug in StaticCybernode in
> this regard, I can only run one test (ever) per VM invocation.

StaticCybernode is not meant to be used in a dynamic setting (hence it's static nature). I even state the following in StaticCybernode's doc:

If associations have been declared (with setter properties) the injection of associated services is undefined at this time.

So I'm not sure what you're getting at here.

>
> I am about to proof this, but will "uses" cause Associations them to
> be injected earlier (before @Started) ?
>
> I have also made the decision to switch from injecting the bare
> services (public void setFoo( Foo foo)) to using your
> AssociationProxy<Foo> -

You should rather use Association<Foo> instead

> one can then write nice code to, for example,
> halt a loop processing items off the space based on the state of the
> proxy (pending/discovered/changed/broken).

It seems you want specific handling for associations. What I have done in cases like this is to write a custom association management proxy. The AMP can be used to manage the discovered services, as needed iterating over a collection of services. Rio comes with a couple of these (called service selection strategies): FailOver (default), RoundRobin and Utilization. With this approach you could make a set of services appear as one (although thats what the association proxies try to do for you by default), and even eagerly inject it so you dont have to wait for the 'real' services to appear [1]. If you haven't already, take a look at the writeup here http://www.rio-project.org/associations.html#Service_Selection_Strategies

> if I do this, I am hoping
> that those proxies (in a state of, say, PENDING) will be injected by
> the time @Started is called?

Nope, they are still associations, and still are waiting to be discovered. Rio will only inject them early if you tell it to.

Dennis

1. You can declare any association to be injected eagerly by using the inject property of the association management:

association(name: 'Foo', type: 'requires', property: 'foo') {
management inject: 'eager'
}

Dawid Loubser

unread,
Feb 23, 2012, 1:33:16 AM2/23/12
to Rio Users Group
Dennis, day by day my understanding improves because of your
thoughtful help - thank you. Eager injection together with service
discovery timeout (that blocks calls until the association is in a non-
broken state) is precisely what I need right now. I can remove this
code from my application logic then (where it does not belong).

I have read so much over the past few weeks, but i think I need to pay
even closer attention to your minimalist, but to-the-point,
documentation :-)

kind regards,
Dawid
> It seems you want specific handling for associations. What I have done in cases like this is to write a custom association management proxy. The AMP can be used to manage the discovered services, as needed iterating over a collection of services. Rio comes with a couple of these (called service selection strategies): FailOver (default), RoundRobin and Utilization. With this approach you could make a set of services appear as one (although thats what the association proxies try to do for you by default), and even eagerly inject it so you dont have to wait for the 'real' services to appear [1]. If you haven't already, take a look at the writeup herehttp://www.rio-project.org/associations.html#Service_Selection_Strate...
Reply all
Reply to author
Forward
0 new messages