Archived

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

Unable to get simple Replica Group to work

Hi,

I apologise in advance for this post as I must be missing something obvious.

I have set up a very simple Ice Grid with two ice box Services on different nodes which expose a simple Service via a Service template.

I can Access the Services directly using the Well-Known Name I have defined.

However, when I try to Access them via a replica Group it doesn't work. I can see from the grid admin that the replica Group is set up correctly, and when Debugging from a Client I am able to obtain a Proxy however a checked cast leads to an Ice.ObjectNotExistException.

Here is my grid XML:

<icegrid>
<application name="grid">
<replica-group id="ReplicatorAddService">
<load-balancing type="adaptive" n-replicas="2"/>
<object identity="AddServiceGateway" type="::ProView::Grid::Slice::Test::AddService"/>
</replica-group>

<service-template id="AddService">
<parameter name="instanceId"/>
<service name="AddService-${instanceId}" entry="C:/GridProView/lib/AddService/ProView.Grid.Add.dll:ProView.Grid.Add.Service">
<properties>
<property name="instanceId" value="${instanceId}"/>
</properties>
<description>AddService ${instanceId}</description>
<adapter name="AddServiceAdapter-${instanceId}" id="AddServiceAdapter-${instanceId}" endpoints="tcp" replica-group="ReplicatorAddService">
<object identity="AddService-${instanceId}" type="::ProView::Grid::Slice::Test::AddService"/>
</adapter>
</service>
</service-template>

<node name="Node1">
<icebox id="IceBox1" activation="always" exe="iceboxnet.exe">
<description>IceBox server node 1</description>
<service-instance template="AddService" instanceId="1"/>
</icebox>
</node>

<node name="Node2">
<icebox id="IceBox2" activation="always" exe="iceboxnet.exe">
<description>IceBox server node 2</description>
<service-instance template="AddService" instanceId="2"/>
</icebox>
</node>
</application>
</icegrid>

And here is my Client code (in F#):

let proxy = communicator.stringToProxy("AddServiceGateway")
let addService = AddServicePrxHelper.checkedCast(proxy)

Could this have something to do with the fact that the Services are not in the same ice box ?

Many thanks for your help, and again, apologies if this is a schoolboy error on my part...

Comments

  • benoit
    benoit Rennes, France
    Hi,

    An Ice.ObjectNotExistException indicates that the Ice object doesn't exist. In your IceBox service, did you add a servant for the "AddServiceGateway" identity or only for the "AddService-1" or "AddService-2" identity?

    You have 2 choices:
    • Register the servant twice, once with the AddServiceGateway identity and once with the AddService-1 or AddService-2 identity.
    • Only register the servant with the AddServiceGateway and remove the well-known object declaration from the service template descriptor.

    I recommend to only register the servant once with the AddServiceGateway identity. It is fine to register an Ice object with the same identity in 2 different services as long as conceptually the Ice object is replicated.

    Cheers,
    Benoit.
  • Hi Benoit,

    Many thanks for the quick Response, indeed that was the Problem, and I agree it is best to have just one servant registered with the AddServiceGateway identity.

    Apologies, it is hard for me to figure out from the IceGird documentation what the corresponding Server code should look like, I promise I downloaded the examples and tried to figure it out before posting the question.

    Unfortunately now the load-balancing doesn't appear to work as I imagined, here is my replica Group entry:

    <replica-group id="ReplicatorAddService">
    <load-balancing type="round-robin" n-replicas="2"/>
    <object identity="AddServiceGateway" type="::ProView::Grid::Slice::Test::AddService"/>
    </replica-group>

    And here is the sample Client code I'm using:

    let communicator = Ice.Application.communicator()
    let x = 2
    let y = 3
    let proxy = communicator.stringToProxy("AddServiceGateway")
    let addService = AddServicePrxHelper.checkedCast(proxy)
    [0..5]
    |> List.iter (fun _ ->
    try
    //let proxy = communicator.stringToProxy("AddService-1")
    //let addService = AddServicePrxHelper.checkedCast(proxy)
    let z = addService.Add(x, y)
    printfn "x: %i y: %i z: %i" x y z
    with ex ->
    printfn "Error: %s" ex.Message
    raise ex
    )

    I was expecting it to use each Service in order, however it just seems to pick one Service and stay with it. I have tried with the other load balancing types and all give the same (non load-balancing :-) ) behaviour.

    I tried moving Proxy creation into the Loop, but still got the same result.

    Are my expectations of how this should work wrong ?

    My expectations are largely driven from this excerpt from the documentation:

    The client no longer needs to use the IceGrid::Query interface, but simply creates a proxy for a well-known object and lets the Ice run time transparently interact with the location service. In response to a locate request for EncoderFactory, the registry returns a proxy containing the endpoints of both object adapters. The Ice run time in the client selects one of the endpoints at random...

    As an aside I am also encountering an intermitten delay in obtaining the Proxy even though everything at the Moment is running on my local machine.
  • benoit
    benoit Rennes, France
    We indeed don't document this very well. We'll look into improving this.

    The replication and load balancing most likely works for your client but you don't see it because the load balancing only occurs once: when the client establishes the connection to the server. If you restart your client, it should eventually pick up another replica.

    To perform per-request load balancing in your client, you need to configure the proxy appropriately: you should disable connection caching and eventually the locator cache timeout. The client from the C++ IceGrid/replication demo demonstrate this:
        //
        // Get the hello proxy. We configure the proxy to not cache the
        // server connection with the proxy and to disable the locator
        // cache. With this configuration, the IceGrid locator will be
        // queried for each invocation on the proxy and the invocation
        // will be sent over the server connection matching the returned
        // endpoints.
        //
        Ice::ObjectPrx obj = communicator()->stringToProxy("hello");
        obj = obj->ice_connectionCached(false);
        obj = obj->ice_locatorCacheTimeout(0);
    

    For information on connection caching see the Connection Establishment section in the manual. For information on locator cache see Locator Cache Timeout.

    Cheers,
    Benoit.
  • MANY thanks, that indeed means the load-balancing works as I expected, from a functional Point of view.

    I now just have to resolve the delay issue.... :-)

    I have a very simple set-up whereby a registry and two nodes are running on my local machine, however there is a heavy delay of almost a Minute between each successive call.

    I am Aware this could be due to any number of issues on my local Computer, however I wasn't seeing the issue when I located the Services directly instead of via a replica Group.

    Please let me know if some obvious configuration or set-up issue could be causing this. I assume a multi-second delay isn't an in-build Feature of the load-balancing :-)

    Again, many thanks for your Support.
  • benoit
    benoit Rennes, France
    One possible reason is that your client tries to establish a connection to an inaccessible IP address.

    You can set Ice.Trace.Network=2 in your client configuration to see if that's the case. See this FAQ for the reason.

    If this is the problem, you'll need to provide a -h <hostname> option in the endpoints attribute of the <adapter> XML element of your service descriptor.

    Cheers,
    Benoit.
  • That was exactly the Problem !

    Again, many, many, many thanks for your help, it has really speeded up the Setting up of a demo grid for us.

    Have a good Weekend.

    Daniel