Archived

This forum has been archived. Please start a new discussion on GitHub.

Glacier Router and different adapter ids using the same identity

Looking at the code, it seems like the glacier2 routing table is built on identity only (Glacier2::RoutingTable::add). In our system, we use many well known identities that live on different icegridnodes, using different adapter ids (like myfactory@adapter1, myfactory@adapter2 etc.).

Is there any way to make Glacier2 include the adapter id/endpoint of a servant when making routing decisions?

Example code (this is stripped down from a real world application):

#include <Ice/Ice.h>
#include <Glacier2/Glacier2.h>
#include <My.h>

int main(int argc, char** argv)
{
  auto communicator = Ice::initialize(argc, argv);
  Ice::RouterPrx r = communicator->getDefaultRouter();
  auto neoRouter = Glacier2::RouterPrx::checkedCast(r);
  neoRouter->createSession("", "");

  { // Block A
    auto factory = My::MyFactoryPrx::checkedCast(
        communicator->stringToProxy("MyFactory@MyService0"));
    std::cout << factory->ice_toString() << std::endl;
    auto o = factory->getObjectById(1234);
    std::cout << o->ice_toString() << std::endl;
  }

  { // Block B
    auto factory = My::MyFactoryPrx::checkedCast(
        communicator->stringToProxy("MyFactory@MyService1"));
    std::cout << factory->ice_toString() << std::endl;
    auto o = factory->getObjectById(1234);
    std::cout << o->ice_toString() << std::endl;
  }

  neoRouter->destroySession();
  communicator->destroy();
}

My.ice contains a very basic factory that returns a factored object, something like this:

module My
{
    interface MyObject
    {
       //...
    };

    interface MyFactory
    {
        MyObject* getObjectById(long id);
    }
}

The server implements getObjectById in a straightforward way:

MyObjectPrx MyFactory::getObjectById(Ice::Long id, const Ice::Current& current)
{
    return current.adapter->createProxy({std::to_string(id), "MyObject"});
}

MyService0 and MyService1 are adapters that run on two separate icegridnodes in iceboxes, on two separate servers.

Now, when running the example code from above, I would expect to see the following output:

MyFactory -t -e 1.1 @ MyService0
MyObject/1234 -t -e 1.1 @ MyService0
MyFactory -t -e 1.1 @ MyService1
MyObject/1234 -t -e 1.1 @ MyService1

Instead I see:

MyFactory -t -e 1.1 @ MyService0
MyObject/1234 -t -e 1.1 @ MyService0
MyFactory -t -e 1.1 @ MyService1
MyObject/1234 -t -e 1.1 @ MyService0 <-- wait, what?

When reversing Block A and Block B, the output is:

MyFactory -t -e 1.1 @ MyService1
MyObject/1234 -t -e 1.1 @ MyService1
MyFactory -t -e 1.1 @ MyService0
MyObject/1234 -t -e 1.1 @ MyService1 <-- wait, what?

So Glacier2 always talks to the first factory resolved, due to the identity that was cached in the routing table.

Tagged:

Comments