river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dan Creswell <dan.cresw...@gmail.com>
Subject Re: MarshalledServiceItem
Date Wed, 02 Feb 2011 09:26:05 GMT
Inline and leaving context for now.....

On 1 February 2011 19:12, Gregg Wonderly <gergg@cox.net> wrote:

> On 2/1/2011 3:17 AM, Dan Creswell wrote:
>
>> So...
>>
>> On 1 February 2011 01:29, Gregg Wonderly<gregg@wonderly.org>  wrote:
>>
>>  One of the important things for my use of my changes to the
>>> ServiceRegistrar interface was separating deserialization of the Entrys
>>> from
>>> the service object.
>>>
>>
> Note "separating" used here.  I was trying to say that I need to be able to
> "pick" which Entry objects to deserialize, and deserialize them independent
> of deserializing the service proxy/object.
>
>
>  Being able to defer downloading was also controlled by the changes to
>>> ClassLoading to include the "neverPrefer" settings on a class name.  I
>>> can
>>> do that now through the recent RMIClassLoaderSPI override capabilities.
>>>  But
>>> I still need to be able to control which Entry is deserialized.  I need
>>> to
>>> be able to ask what classes, by name, are in the namespace of each Entry
>>> object as my implementation allowed. I had made changes to Reggie
>>> marshalling to use reflection to get the class hierarchy, and then
>>> provided
>>> access to the list of classnames as part of the returned, marshalled
>>> value
>>> in my API.
>>>
>>>
>>>  Digging through classes belonging to a service implementation that is
>> designed to be encapsulated/not your concern? Does that sound right? I
>> gotta
>> say, it sounds horribly invasive, very hacky and speaks of an overly
>> complex
>> solution as the result of treating symptoms, not problems.
>>
>
> Okay, I want to go through the problems that I was dealing with, the
> attributes of the current mechanisms, and how I inserted points of control
> to manage these issues.
>
> First, let's look at the simple client mechanisms I wanted to have.  I have
> a desktop environment, which does lookup, and then shows treeviews of
> services based on "machine"->"group"->Service Instance structure.  The
> deployed services contain Entry objects that provide values for these three
> name spaces.  Since I need to look at these, they can not be preferred by
> the service or I can't read them.  There may be a subclass that the client
> has used, and that can be preferred no problem.  There are some other items
> in the Entrys that I need too, such as icons.  Any of the Entry objects that
> I need access to, and any classes which they are dependent on, and which are
> publicly visible classes/interfaces, because of that attribute (public) can
> not be realistically preferred.
>
>
These Entry types are part of the basic infrastructure of your system aren't
they? Why download them at all? I guess because you have to "teach" it to
the LUS via code-download? Or you could just put them on all classpaths
including LUS? S'far as I can see you've got an extended LUS infrastructure
that everyone shares thus codebase seems like the wrong choice for these.

Sure user's can subclass Entry types but do they? Do you even want them to?
Why? Thus far I've seen many subclass Entry's for JavaSpaces and, I think,
zero for LUS type annotations.

See my other thread with Peter but it seems to me that you have some core
additions to LUS infrastructure and a need to be able to filter what you
don't want to see/is outside of a client's knowledge base. Because it's that
inability to filter that then leads to lots of additional downloading.



> So my first assertion is that Entry objects will hardly ever be preferred,
> and thus downloading of the PREFERRED.LIST is not a necessary step to
> correctly resolve them for my use.
>
> The next issues is this PREFERRED.LIST file.  The implementation of that
> technology is that the file is retrieved from the first jar file listed in
> the codebase.  So, in order to resolve any class in the proxy or Entry
> values, there must be a download from the associated codebase server.
>
> Now, one of the first things that I think about with distributed computing
> is the business of partial failure and limiting that impact to the overall
> performance of the system.  My deployments at my customers' sites consist of
> copies of the same service platform with the same services on it.  There are
> copies for both redundancy and for capacity.
>
> Each instance of my platform has as a starting point 20 some services each
> with a separate codebase, but with many common jars such as jsk-dk.jar.  If
> a lookup service responds with a list of services but the codebase server
> doesn't respond with jars, then any attempt to download limits the
> performance of the display of available services, and I considered an
> "incorrect list of available services" less important than non-display or
> slow-display of available services.
>

As Michal says elsewhere, are you sure the solution is to try and leverage
LUS to handle display challenges like this?

What you seem to be doing is constructing a navigation structure for a GUI
direct from the LUS per client. Why wouldn't you have some separate "service
summary service" that builds up this navigation structure by tracking
service arrivals and such and creating the necessary descriptive text for
clients to pull down in one big bang?

You get caching for staters, no need to download a bunch of services until
later and thus far fewer downloads especially as things like Entry's can be
rendered into text reps as part of this process of building navigation
information. (heck you could even insist all Entry's provide a toString for
use on your platform). No reason too why the summary service couldn't build
on demand trees for some specified set of Entry types. It could cache those
and update them too such that if another client requests the same tree it
gets it straight back.

I guess my summary would be, I feel like you've gone for a "deep" solution
that builds into existing infrastructure instead of building extensions atop
that specifically tackle your problems in a more "meta" fashion. Please
don't take offence at that, I'm not for a moment saying it's a mistake, just
one path to solution and given what I've heard so far I think there's
another path that hasn't been ruled out yet.


>
> The technicians in my customers' business have a lot of windshield time and
> use their cellular connectivity or satellite based WAN networking for many
> tasks. This means that there is a lot of latency, cost for bandwidth in term
> of time and bandwidth both.  So, for me to make a distributed network based
> services environment work, I have to limit network to only what is
> absolutely necessary.
>
> So, back to the two different changes that I made to service lookup and
> class resolution.  The activities in ClassLoading to provide a
> "neverPreferred" functionality was instituted by having my client tell
> ClassLoading via public static API, which Entry classes and dependent
> classes should never be preferred.  Recall, that in the beginning, the class
> loading mechanisms did have a "neverPreferred" policy for java.lang.* and
> for native types and arrays.
>
> This was removed in an update later on in 2.1 if I remember right.  This
> kept classloading from being triggered in those cases.  That functionality,
> when removed, was declared as nonessential/unused because normal class
> loading would keep that from happening.  However, because
> PreferredClassLoading will never ask the parent class loader (especially
> without my patch to allow RMIClassLoaderSPI to not be used) to resolve a
> class until the PREFERRED.LIST is on hand, the codebase will always be
> accessed, requiring a download of at least the first jar.
>
> In my case, a customer with 100 codebases (5 machines) trying to use my
> desktop client, would experience 100 http connections and downloads of the
> first jar before they could see all the available services.  And, because of
> the fact that not ever single codebase would be requested in parallel, any
> stuck codebase could potentially delay the display of available services for
> 3-5 minutes per problem codebase while TCP connect requests timeout.
>
> For me, this was just not an acceptable outcome.  It was simply not
> possible to manage my product environment with these issues at hand.  No
> matter how much the first jar required to be transferred, it would simply
> take way too long for them to see a useful client display.
>
> My changes in River-336 for RMIClassLoaderSPI override, use methods such as
> CodebaseAccessClassLoader.loadClass(...) which can be used to provide the
> "neverPreferred" functionality.  So, I have a pluggable mechanism that
> allows me to manage this issue.  So if no one else has such requirements,
> there is no need to discuss this as a point of argument for inclusion in
> River.  I think it is a valid point of control because the client can
> declare the platform that they are compatible with by using this facility to
> never prefer certain classes which will then cause services overrides to not
> appear and the client could even provide some feedback when this happens by
> allow the CodebaseAccessClassLoader implementation to provide some data
> points about when it finds it is ignoring something declared as preferred.
>
> The other business at hand is the deferred unmarshalling.  And in that
> case, I don't think that there is too much of an argument to be had.  If we
> focus on just allowing the client to access the entries selectively, and
> defer unmarshalling of the service proxy/object separately, that's the
> basics of what I need for my environment.
>
> The API that I implemented allowed access to the list of classes and
> interfaces referred to by the Entry so that the client could discover that
> it can't unmarshall the Entry because it requires network access to download
> something that it doesn't have locally.  If that usage pattern doesn't seem
> valuable, then something more along the lines of providing a Class object as
> Peter's API shows might work well enough.  But we need to figure out how to
> deal with Entry values which are subclasses.  If I pass in Name.class, and
> there are several subclasses of Name visible in the Entry values, then which
> one would you return?  All of them?  What if one of those contained a rather
> large object graph which was not what I wanted.  Would I get it unmarshalled
> so that I could still inspect it to decide if it was the one I wanted to
> unmarshall and look at?
>
> Sorry for going on and on about this, but I wanted to try and put out all
> the details that I had dealt with and the thoughts around my path of
> solution.
>
> Gregg Wonderly
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message