Archived
This forum has been archived. Please start a new discussion on GitHub.
Same object on many servers
Hi
First sorry for my poor english (I'm french)
I have to create an application who permits to a user listing all available fonctions available on the network (fonctions are in fact Objects extending a Slice interface named "Methode").
For the moment, I can list all "Methode" objects on a server with the method findAllObjectsByType. For example, with this application.xml, I can have objects m1 and m2 and use them :
But I would like to have a same "Methode" object on several server.
I tried that :
but it doesn't work (duplicate object error). I'm a beginner in Ice and English documentation is difficult for me
so my question is how can i have same object (same class) on several network with the same name ?
At the end, the goal for this application is to call the object on the least loaded server.
Thanks.
First sorry for my poor english (I'm french)
I have to create an application who permits to a user listing all available fonctions available on the network (fonctions are in fact Objects extending a Slice interface named "Methode").
For the moment, I can list all "Methode" objects on a server with the method findAllObjectsByType. For example, with this application.xml, I can have objects m1 and m2 and use them :
<icegrid> <application name="Simple"> <node name="localhost"> <server id="SimpleServer" exe="./GridServer" activation="on-demand"> <adapter name="Methode" endpoints="tcp" register-process="true"> <object identity="m1" type="::Demo::Methode" property="Identity"/> <object identity="m2" type="::Demo::Methode" property="Identity"/> </adapter> </server> </node> </application> </icegrid>
But I would like to have a same "Methode" object on several server.
I tried that :
<icegrid> <application name="Simple"> <node name="localhost"> <server id="SimpleServer" exe="./GridServer" activation="on-demand"> <adapter name="Methode" endpoints="tcp" register-process="true"> <object identity="m1" type="::Demo::Methode" property="Identity"/> <object identity="m2" type="::Demo::Methode" property="Identity"/> </adapter> </server> <server id="SimpleServer2" exe="./GridServer" activation="on-demand"> <adapter name="Methode" endpoints="tcp" register-process="true"> <object identity="m1" type="::Demo::Methode" property="Identity"/> </adapter> </server> </node> </application> </icegrid>
but it doesn't work (duplicate object error). I'm a beginner in Ice and English documentation is difficult for me
![:) :)](https://forums.zeroc.com/resources/emoji/smile.png)
At the end, the goal for this application is to call the object on the least loaded server.
Thanks.
0
Comments
-
Hi Antoine,
You need to create a replica group and declare the object within the replica group instead. See demo/IceGrid/simple/application_with_replication.xml included with your Ice distribution for an example.
Kenavo!
Benoit.0 -
thank you it helps me but I still have a question, server instance of a template all have the same objects. I would like my servers to have differents "Methode" objects in general and sometimes they share a same object.
I don't know if I'm very clear sorry.
Thanks0 -
You just need to declared the objects which are hosted by multiple servers with the replica group. You can still define the other objects with the object adapter.
Cheers,
Benoit.0 -
That works fine thanks !
I continue with my questionsI've noticed that if I create an adapter member of a replica-group, icegrid will consider this adapter contains all object of this replica group and won't search in other adapter members of this replica group.
For example :<replica-group id="ReplicatedMethodeAdapter"> <load-balancing type="round-robin"/> <object identity="m1" type="::Demo::Methode"/> <object identity="m2" type="::Demo::Methode"/> </replica-group> <server id="SimpleServer" exe="./GridServer" activation="on-demand"> <adapter name="Methode" endpoints="tcp" register-process="true" replica-group="ReplicatedMethodeAdapter"/> </server> <server id="SimpleServer2" exe="./GridServer2" activation="on-demand"> <adapter name="Methode" endpoints="tcp" register-process="true" replica-group="ReplicatedMethodeAdapter"/> </server>
if I only add "m1" in the adapter "Methode" of SimpleServer and only add "m2" in the adapter "Methode" of SimpleServer2, and after if I want to work on "m2", icegrid returns he can't find the object so he starts searching on SimpleServer and doesn't continue the search on SimpleServer2.
It would not be a problem if adapters could be members of many replica-group but I don't know if it's possible and how.
In fact I had the idea to create one replica-group per shared "Methode" object OR create a general replica-group where it's not necessary to declare all of objects on all servers (that would return an error only if none of the servers have the required object in the adapter).
Hope what I ask is possible
Thanks0 -
Try the following instead:
<replica-group id="ReplicatedMethodeAdapter"> <load-balancing type="round-robin"/> <object identity="m1" type="::Demo::Methode"/> </replica-group> <server id="SimpleServer" exe="./GridServer" activation="on-demand"> <adapter name="Methode" endpoints="tcp" register-process="true" replica-group="ReplicatedMethodeAdapter"/> </server> <server id="SimpleServer2" exe="./GridServer2" activation="on-demand"> <adapter name="Methode" endpoints="tcp" register-process="true" replica-group="ReplicatedMethodeAdapter"> <object identity="m2" type="::Demo::Methode"/> </adapter> </server>
Cheers,
Benoit.0 -
that is what I found thank to your last answer
But now what if I want to have "m1" duplicated for SimpleServer and SimpleServer2 like in your code and another function "m3" duplicated for SimpleServer2 and SimpleServer3 for example ? "m2" is still an additionnal function for SimpleServer2.
Can SimpleServer2 be member of two differents replica groups ? (one for m1, one for m3)
Thanks0 -
No, this is not possible. An object adapter can only be member of a single replica group.
Cheers,
Benoit.0 -
Aie too bad
And is it possible to verify if an object is added on every server of the replica group before returning an error Ice::ObjectNotExistException ?
Thanks
Antoine0 -
is my last question clear enough ?
Antoine0 -
Hi Antoine,
No, it's not possible.
It looks like you have quite an unusual configuration. Why are you registering well-known objects for each of these "Methode"? Perhaps it would be simpler if you had your own registry and return either a proxy with the replica group or with the adapter id depending on the requested "Methode"?
In any case, I recommend reading the IceGrid chapter in the Ice manual. It should give you a better idea on what is possible to do with the IceGrid deployment mechanism.
Cheers,
Benoit.0 -
I tried to find in the documentation something telling me that my problem can be resolved or not but i found nothing.
So i will explain it in other way :
here is some instructions from the client source code :Ice::ObjectPrx proxy = communicator()->stringToProxy("DemoIceGrid/Query"); IceGrid::QueryPrx query = IceGrid::QueryPrx::checkedCast(proxy); Ice::ObjectProxySeq seq; string type = Methode::ice_staticId(); Ice::ObjectProxySeq::size_type index; seq = query->findAllObjectsByType(type); index = 0; test = MethodePrx::checkedCast(communicator()->stringToProxy(communicator()->identityToString(seq[index]->ice_getIdentity())));
and my application.xml contains the following :<icegrid> <application name="Simple"> <replica-group id="ReplicatedMethodeAdapter"> <load-balancing type="random"/> <object identity="m1" type="::Demo::Methode"/> <object identity="m2" type="::Demo::Methode"/> <object identity="m3" type="::Demo::Methode"/> </replica-group> <node name="localhost"> <server id="SimpleServer" exe="./GridServer" activation="on-demand"> <adapter name="Methode" endpoints="tcp" register-process="true" replica-group="ReplicatedMethodeAdapter"> </adapter> </server> </node> <node name="host2"> <server id="SimpleServer2" exe="./GridServer2" activation="on-demand"> <adapter name="Methode" endpoints="tcp" register-process="true" replica-group="ReplicatedMethodeAdapter"/> </server> </node> <node name="host3"> <server id="SimpleServer3" exe="./GridServer3" activation="on-demand"> <adapter name="Methode" endpoints="tcp" register-process="true" replica-group="ReplicatedMethodeAdapter"/> </server> </node> </application> </icegrid>
Now the problem is here, in GridServer2 for example :int GridServer::run(int argc, char* argv[]) { Ice::PropertiesPtr properties = communicator()->getProperties(); Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("Methode"); adapter->add(new Mun(properties->getProperty("Ice.ServerId")), communicator()->stringToIdentity("m1")); adapter->add(new Mdeux(properties->getProperty("Ice.ServerId")), communicator()->stringToIdentity("m2")); adapter->activate(); communicator()->waitForShutdown(); return EXIT_SUCCESS; }
all works fine but if I delete the line :adapter->add(new Mun(properties->getProperty("Ice.ServerId")), communicator()->stringToIdentity("m1"));
then if the random point the GridServer2 to provide the Methode object "m1", an ObjectNotExistException. The fact is I would like to verify if the "m1" object is really added in the adapter or find a query that give me only adapters with expected object already added in its.
Is it possible
Thanks
Antoine0 -
Hi Antoine,
As I previously explained, if you declare an object with the replica group, IceGrid assumes this object is available with all the object adapters of the replica group. You shouldn't register an object with a replica group if it's not hosted by all the members of the replica group.
In any case, there's no easy way for the client to figure out which object is hosted by a given server other than invoking on the proxy and check if you get an Ice::ObjectNotExistException.
You should really explain what you're trying to do if you need further help with this. It sounds like replica groups and well-known objects are not a good fit for what you're trying to do here.
Cheers,
Benoit.0 -
ok sorry if I'm not very clear.
I will try to explain the objectives of my project
on many servers we have library created by searcher and we would like to create a client interface that lists all library availables (with the method findAllObjectsByType). Every library can be called with an "Methode" object defined in Slice. And after the client can call the Methode he wants in the list.
But sometime a same library is available on several servers and that's why i thought about the replica groups. And the probleme is : we can't create a replica group per library as you told me so I tried to put every Methode object in the replica group and test if they are instanciated but apparently it's impossible (checking Ice::ObjectNotExistException would be too long and even if a Methode object is not available at all, it would be listed as available.)
I hope I've enough explained my problem. I don't know if what I want to do is possible and if replica's group fit for my needs.
Thanks
Antoine0 -
Hi
Am I clear enough in my previous post or do I have to explain something more ?
Thanks
Antoine0 -
I don't think replica groups and well-known objects are really suitable for what you're trying to do. You'd have to create an object adapter and replica group per library which would be inconvenient. It's probably best if you create your own registry service where you register the proxies of the "Methode" objects. Clients would use this registry to lookup and retrieve these proxies.
Cheers,
Benoit.0