[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[ecf-dev] Customizing the consumption of remote services
|
Hi Folks,
On the ecf newsgroup there was a question about the client discovery and
handling of multiple remote services...i.e. where the remote services
comes from more than one target framework. I've included the original
posting and my response below, as there are some design issues here.
Also, it gave me a chance to provide some more documentation about an
aspect of ECF remote services that is kind of cool...the ability to
easily extend and customize the behavior.
The discussion began with reference to the r-osgi provider specifically,
but in fact most of the issues are not with the r-osgi provider...but
rather with the remote services consumer/client behavior in the face of
multiple remote services on a network (and multiple frameworks hosting
those services).
See below for discussion. Feel free to jump in with questions and/or
observations.
Scott
-------
Hi Rado,
First, with your permission (Rado), I would like to move this discussion
over to ecf-dev at eclipse.org mailing list. Is this OK with you? Here
is the page for joining that mailing list:
https://dev.eclipse.org/mailman/listinfo/ecf-dev
The reason that I would like to move this discussion over to the ECF dev
mailing list is that the handling of this use case (multiple remote
services) has a number implications...and I would like to get input from
you and others in the ECF mailing list.
So in this particular case, on the client you have created *one*
instance of the r-osgi container/client. When the first service
endpoint is discovered, that client is used to connect, get the remote
service reference for, and create the local proxy for the remote service
endpoint (in your xml file, this is likely the r-osgi://localhost:9279
endpoint).
When the *second* endpoint is 'discovered' (I put quotes around this
because you are using the local/file-based discovery, so it's just being
discovered because of the reading of the xml file), there is only *one*
r-osgi client, and since it's already connected to the first endpoint,
the no remote service container is found to handle the second remote
service endpoint, and so it can't handle it without either:
1) disconnecting from the first one...and reconnecting to the second one
2) creating a new remote service container/client to handle this second
remote service
Note that the selection between 1 and 2 is an important client-side
policy choice, because it will determine how/whether both remote
services can be used simultaneously. Further, selection of these
strategies has other effects if there are > 2 services that are
discovered (using file-based discovery and/or other discovery providers).
There are other upsides and downsides to both approaches (1 or 2). So,
for example, 2 requires more resources on the client (since there are >
1 client container instances).
So the strategy selection in these use cases (on the client side) are
sort of important...and the current OSGi 4.2 specification does not say
anything about how these situations are to be handled...at least
partially because this is kind of a policy-level choice (i.e. some
applications/clients will want to do things one way, others will want to
do things different ways).
Now, ECF has built in some flexibility into our implementation, so that
either/both approaches can be implemented fairly easily. This API is
new, and I would consider it still provisional (it's marked internal in
ECF 3.2, precisely because it likely will undergo some changes once
we/others get some more experience with it).
Specifically, we have something called the IProxyContainerFinder
service, which is responsible for *selecting* IContainer instances...on
the client...when they are discovered. There is some documentation (not
enough yet, I know), on this mechanism for extending/customizing the ECF
remote service impl in the wiki here:
http://wiki.eclipse.org/Customizing_and_Extending_ECF_Remote_Services
What happens is this:
discovery provider
--> discovers remote service
--> IProxyContainerFinder is selected (the service instance with
highest priority is selected)
--> IProxyContainerFinder.findProxyContainers is called and
returns an array of IRemoteServiceContainers. The given discovered
remote service is then registered with *all* of the
IRemoteServiceContainers returned.
The implementation of the findProxyContainers determines which container
instance is used to handle the discovered remote service.
If *no* custom/user-defined IProxyContainerFinder instances are present,
then a default one is created...and this is an instance of class
DefaultProxyContainerFinder. (Note that the DefaultProxyContainerFinder
is API also, so it can be easily subclassed to create your own
IProxyContainerFinder instance).
Now...the DefaultProxyContainerFinder already has the ability to do
strategy 2 as described above (i.e. create a new container instance of
compatible type), when a second/nth remote service is discovered. As
described briefly on the wiki page, the DefaultProxyContainerFinder has
a flag (which can be set in the constructor) that indicates whether an
appropriate IContainer instance should be created dynamically (i.e.
strategy 2). This flag is set to *false* by default...for security
reasons (if it was on by default, clients would be subject to possibly
severe denial of service attacks). There's some discussion of this
design choice on this bug:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=303979
So I *believe* that if you were to use the the System property for
DefaultProxyContainerFinder (see the wiki page), your use case described
below would/could work, because with auto create container flag set to
'true' a new/second container instance would be created when your second
remote service was discovered.
If you want to do 1 (or variations thereof), it would be necessary to
create your own IProxyContainerFinder (e.g. by extending
DefaultProxyContainerFinder class and registering the service as shown
on the wiki), and in your impl of findProxyContainers you would/could
explicitly disconnect the client container (i.e.
IContainer.disconnect()), before returning from findProxyContainers.
This IProxyContainerFinder (and IHostContainerFinder for that matter)
are ECF-specific mechanisms...which aren't specified at all by the OSGi
4.2 spec...but I put them in place to support more complex use cases
(i.e. with many remote services). If we need to adjust them/add to them
or simplify them then we are open to doing this, as like I said above
they are provisional at this point, and I am interested in making them
as easy to use for as many use cases as possible (for example, perhaps
we could consider implementing strategy 1 in DefaultProxyContainerFinder
as well as 2).
One more thing. There was a bug filed recently describing a race
condition in the ECF 3.2 implementation with multiple remote services
discovered via file-based discovery (as yours is doing). That bug is here:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=304427
This race condition has since been fixed/addressed, but note that the
fix is *not* in ECF 3.2 released version, as we only learned about it
since the 3.2 release. Currently our plan is to next have an ECF 3.3
release for Helios in June, but if we get enough support and desire we
could consider a 3.2.1 release before June to make this fix available.
Also, the fix is in the CVS repo (HEAD), so you can get the appropriate
bundle and try it out if you wish.
Does this make sense? Rado please let me know if it will be ok to move
this discussion to ecf-dev at eclipse.org mailing list and we will
continue this discussion further.
Thanks,
Scott
a340859@xxxxxxxxxx wrote:
Hello,
I am trying to run a file-based discovery with the r-OSGI provider.
I am utilizing the org.eclipse.ecf.examples.remoteservices.hello.consumer
and org.eclipse.ecf.examples.remoteservices.hello.host
examples.
Everything is running just fine with one host and one consumer.
However when I start an additional host (on a separate machine) the
consumer discovers only one of them. My
OSGI-INF/remote-service/hello-service-description-generic.xm l file is:
<?xml version="1.0" encoding="UTF-8"?>
<service-descriptions xmlns="http://www.osgi.org/xmlns/sd/v1.0.0">
<service-description>
<provide
interface="org.eclipse.ecf.examples.remoteservices.hello.IHello"/>
<property name="ecf.sp.cid">r-osgi://localhost:9279</property>
<property name="ecf.sp.cns">ecf.namespace.r_osgi</property>
<property name="ecf.sp.ect">ecf.r_osgi.peer</property>
</service-description>
<service-description>
<provide
interface="org.eclipse.ecf.examples.remoteservices.hello.IHello"/>
<property name="ecf.sp.cid">r-osgi://192.168.1.242:9279</property>
<property name="ecf.sp.cns">ecf.namespace.r_osgi</property>
<property name="ecf.sp.ect">ecf.r_osgi.peer</property>
</service-description>
</service-descriptions>
In fact, only the first <service-description> entry is discovered.
Is this the right way to have more than one provider for a given service?
Thanks in advance.
Regards,
Rado