Glacier Router and different adapter ids using the same identity

grembogrembo Michael GmelinOrganization: Grem Equity GmbHProject: E-Commerce platformMember

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 [email protected], [email protected] 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("[email protected]"));
    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("[email protected]"));
    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

Sign In or Register to comment.