Archived
This forum has been archived. Please start a new discussion on GitHub.
Problem with replication in IceGrid
Hello!
I am testing the Ripper application to prove and learn all the functionality of IceGrid (see 36.4 section of the ICE documentation). I use ICE 3.1.1, Debian Sid, and Python 2.4.4.
I have the registry and a node running in a same host: the host Node1. However, I have a problem when I add another node: Node2, which runs in the same host but has another name and, therefore, another configuration file and another data directory.
This is the configuration file related to the configuration of the first node:
This is the configuration file related to the configuration of the second node:
I am currently using Round Robin as my load balancing type.
My descriptors are specified in the following configuration file:
And this is the relevant code of the Server:
As you see, I am only testing the IceGrid functionality.
I start the registry and the Node1 node, I start the Node2 node and, finally, I deploy the Ripper application. If a start a client, the server related to the Node1 node shows the textual message but, when I start a second client I obtain the following error:
As I use a round-robin based load balancing type, I know this fail is related to the Node2 node.
This is my simple client:
I suppose I do not take into account some question, but studying the documentation I have not found the answer to my problem.
I hope you could help me.
Thank you,
David.
I am testing the Ripper application to prove and learn all the functionality of IceGrid (see 36.4 section of the ICE documentation). I use ICE 3.1.1, Debian Sid, and Python 2.4.4.
I have the registry and a node running in a same host: the host Node1. However, I have a problem when I add another node: Node2, which runs in the same host but has another name and, therefore, another configuration file and another data directory.
This is the configuration file related to the configuration of the first node:
#Registry properties IceGrid.Registry.Client.Endpoints=default -p 10000 IceGrid.Registry.Server.Endpoints=default IceGrid.Registry.Admin.Endpoints=default IceGrid.Registry.Internal.Endpoints=default IceGrid.Registry.Data=registry #Node properties IceGrid.Node.Name=Node1 IceGrid.Node.Endpoints=default IceGrid.Node.Data=node IceGrid.Node.CollocateRegistry=1 IceGrid.Node.Trace.Activator=3 Ice.Default.Locator=IceGrid/Locator:tcp -h 127.0.0.1 -p 10000
This is the configuration file related to the configuration of the second node:
#Node properties IceGrid.Node.Endpoints=tcp IceGrid.Node.Name=Node2 IceGrid.Node.Data=node2 IceGrid.Node.Trace.Activator=3 Ice.Default.Locator=IceGrid/Locator:tcp -h 127.0.0.1 -p 10000
I am currently using Round Robin as my load balancing type.
My descriptors are specified in the following configuration file:
<icegrid> <application name="Ripper"> <replica-group id="EncoderAdapters"> <load-balancing type="round-robin"/> <object identity="EncoderFactory" type="::Ripper::MP3EncoderFactory"/> </replica-group> <server-template id="EncoderServerTemplate"> <parameter name="index"/> <parameter name="exepath" default="./Server.py"/> <server id="EncoderServer${index}" exe="${exepath}" activation="on-demand"> <adapter name="EncoderAdapter" replica-group="EncoderAdapters" register-process="true" endpoints="tcp"/> </server> </server-template> <node name="Node1"> <server-instance template="EncoderServerTemplate" index="1"/> </node> <node name="Node2"> <server-instance template="EncoderServerTemplate" index="2"/> </node> </application> </icegrid>
And this is the relevant code of the Server:
class Mp3EncoderI (Ripper.Mp3Encoder): def encode (self, leftSamples, rightSamples, current): print 'Encoding...' return None def flush (self, current): print 'Flushing...' return None class Mp3EncoderFactoryI (Ripper.Mp3EncoderFactory): def createEncoder (self, current): return Ripper.Mp3EncoderPrx.uncheckedCast( current.adapter.addWithUUID(Mp3EncoderI())) class Server (Ice.Application): def run (self, argv): self.shutdownOnInterrupt() adapter = self.communicator().createObjectAdapter('EncoderAdapter') adapter.add(Mp3EncoderFactoryI(), Ice.stringToIdentity('EncoderFactory')) adapter.activate() self.communicator().waitForShutdown() return 0 Server().main(sys.argv)
As you see, I am only testing the IceGrid functionality.
I start the registry and the Node1 node, I start the Node2 node and, finally, I deploy the Ripper application. If a start a client, the server related to the Node1 node shows the textual message but, when I start a second client I obtain the following error:
Traceback (most recent call last): File "/var/lib/python-support/python2.4/Ice.py", line 524, in main status = self.run(args) File "Client.py", line 14, in run encoder.encode(None, None) File "Ripper.ice", line 62, in encode ObjectNotExistException: exception ::Ice::ObjectNotExistException { id = { name = 60CF5A6C-CB41-468E-B7DA-7599ADE72A4C category = } facet = operation = encode }
As I use a round-robin based load balancing type, I know this fail is related to the Node2 node.
This is my simple client:
class Client (Ice.Application): def run (self, argv): self.shutdownOnInterrupt() obj = self.communicator().stringToProxy('EncoderFactory') ripper = Ripper.Mp3EncoderFactoryPrx.checkedCast(obj) encoder = ripper.createEncoder() encoder.encode(None, None) self.communicator().waitForShutdown() return 0 Client().main(sys.argv, 'client.cfg')
I suppose I do not take into account some question, but studying the documentation I have not found the answer to my problem.
I hope you could help me.
Thank you,
David.
0
Comments
-
Hi,
You're registering the Encoder servant with an object adapter from a replica group (the `EncoderAdapter' adapter). By default, the object adapter creates proxies containing the replica group ID not the adapter ID.
As a result, the proxy returned by the createEncoder method is "<uuid> @ EncoderAdapters" and when you invoke on the proxy, your client sends the request to the next replica (because of the round-robin load balancing).
You should change the code that creates the encoder to:class Mp3EncoderFactoryI (Ripper.Mp3EncoderFactory): def createEncoder (self, current): Ice.ObjectPrx prx = current.adapter.addWithUUID(Mp3EncoderI()); return Ripper.Mp3EncoderPrx.uncheckedCast(current.adapter.createIndirectProxy(prx.ice_getIdentity())
See the Ice manual for more information on the Ice::ObjectAdapter::createIndirectProxy method.
Cheers,
Benoit.0 -
Hello again!
When I try to invoke the createIndirectProxy I obtain the following error:Traceback (most recent call last): File "./Server.py", line 20, in createEncoder return Ripper.Mp3EncoderPrx.uncheckedCast(current.adapter.createIndirectProxy(prx.ice_getIdentity())) AttributeError: 'ObjectAdapterI' object has no attribute 'createIndirectProxy' identity: EncoderFactory facet: operation: createEncoder
I have review the ICE documentation and the name of the method is the same you specified.
Any idea?0 -
You found a bug in IcePy! The implementation of this method is unfortunately missing. We'll fix this for the next release.
In the meantime, you should be able to use the following code as a workaround:class Mp3EncoderFactoryI (Ripper.Mp3EncoderFactory): def createEncoder (self, current): Ice.ObjectPrx prx = current.adapter.addWithUUID(Mp3EncoderI()); string adapterId = current.adapter.getCommunicator().getProperties().getProperty(current.adapter.getName() + ".AdapterId") return Ripper.Mp3EncoderPrx.uncheckedCast(prx.ice_adapterId(adapterId))
Cheers,
Benoit.0