river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dennis Reedy <dennis.re...@gmail.com>
Subject Re: Dynamic Behavior wrt IOC in services.
Date Mon, 27 May 2013 18:41:22 GMT


On May 27, 2013, at 204PM, Greg Trasuk wrote:

> (New subject for an interesting point)
> 
> Good point, Dennis...
> 
> On Mon, 2013-05-27 at 13:30, Dennis Reedy wrote:
>> On May 27, 2013, at 103PM, Greg Trasuk wrote:
>> 
> 
>> Sure, no problem. One big thing to consider wrt container IoC, is that
>> the lifecycle of a River service is different then an EJB. With River,
>> a service can join and leave the network (advertised and
>> unadvertised). Making sure that you consider that has been important
>> in my experience. This when tied with how a service deals with other
>> services (what I call associations
>> http://www.rio-project.org/associations.html), can change the
>> lifecycle of a service. So food for thought
>> 
> 
> I think you're on the right track in Rio, with injecting a dynamic proxy
> for associations.  Curiously, this approach is similar to the dynamic
> proxies injected under JEE6 CDI for contextual objects.

An important distinction perhaps is the service selection strategy that is coupled with the
dynamic proxy produced for an associated service declaration. The service selection strategy
provides a way to determine how services in the collection of discovered services are invoked.
Perhaps a strategy (or chained strategies) could be produced to implement behaviors outlined
below.

> 
> Truth is, I've always been hesitant about injecting service
> dependencies, because it seems to me that resolving the services needs
> to be a part of the logic of the service invocation, so that various
> failures can be handled appropriately.
> 
> Couple of scenarios:
> 
> Context - We're talking about a service that depends on one or more
> other services.  When you call service A's 'doSomething()' method, it
> needs to call methods on services B, C, etc.
> 
> Scenario 1- You have a (not very efficient!) policy of looking up every
> service dependency every time A.doSomething() is called.  In this case
> it might just be reasonable to throw an exception (ServiceNotAvailable
> or something similar) and let the client deal with it.  Straight
> injection works in that case.  Or you might want to save the data
> locally and do some alternate handling.  In that case, perhaps it might
> be best to leave the unresolved service references null, so the
> A.doSomething() code can handle it.
> 
> Scenario 2- You have some service references cached.  When you go to do
> A.doSomething(), you find that service B has failed (of course, you find
> this out by means of an IOException when calling service B).  What to
> do?  In the past, I've handled this by dumping all the caches and
> rediscovering the services.  Which means that A.doSomething() has to
> take some control of the dependency resolution, which doesn't fit with
> dependency injection very well.  In Harvester, I had a resolver object
> (I could be wrong, but I think I saw something similar in Rio), so
> A.doSomething() would execute the resolution before attempting to use
> service dependencies.  Then in case of failure, it could call fail() on
> the resolver, which would dump the caches, and attempt resolution again,
> then complete the calls.
> 
> Another issue I've been pondering is how Jini interacts with dynamic IP
> address assignments (i.e. network cards on DHCP).  If the IP address of
> a node changes, it's kind of catastrophic, since the IP addresses of any
> services it exports are probably baked in to both the serialized
> endpoints,

Yes, this could be an issue, but I wonder how probable this is? I had always thought it would
be nice to make the network 'observable' so that if the interface changed you could unadvertise,
unexport, export then advertise. 


> and the codebase urls (assuming that we pessimistically
> assumed that name-based resolution won't work - arguably the truth in
> most networks).  It seems like in that case, the services' states need
> to roll back to before the endpoints were exported, then re-export and
> re-publish to the registrar.
> 
>> From a client point of view, a client would simply see that as a set of
> services failing, and then go and rediscover the services.  That's no
> problem.  But I wonder how to handle that on the service side.  It's
> almost easiest to just shutdown the services and restart.

Yep. 

> 
> And what happens if a host has more than one IP address (multi-homed)? 

Yeah, multi-homed machines are always fun:) I generally key off the java.rmi.server.hostname
system property to use when creating exporters (or other utilities tied to the network). 
If not found, I get the first non-loopback address. 

> Again, the services codebases will likely have the IP address baked-in. 
> So a client on one interface needs to use the serialized proxy that
> corresponds to the correct interface.  Here's a case where using Maven
> artifact ids could help handle the codebase issue.  

Indeed it would. You get rid of the lost codebase issue, and also add in performance gains
by loading classes locally instead of loading over http (and you load them every time). This
is a fundamental problem with the way we have traditionally set up RMI based systems. We can
still have the dynamic classloading, but I never create a ClassLoader that loads classes remotely
any more. Thats just crazy :)

Dennis
Mime
View raw message