Archived

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

Session, Replica groups and load balancing

Hi,

Can I have a replicator group within a session?
The factory object in the code below is allocated by type. There are several instances of it, and the idea of the loop below is to keep them all busy until the job is done.
the Ice runtime returns randomly (according to the manual) an instance that is not locked by the session, but is blocking when all factory objects are in use. By releasing the factory object at the end of the body, one achieves that all factory objects are in use concurrently. (Wouldn't it be natural that the object is released automatically when it is destructed?)

Now I want to add load-balancing. From the manual I read that replica-groups are meant for that purpose, but the example given does not involve a session.
I have tried several ways, but to no avail.
How can I achieve load-balancing in such a situation?

Regards,
Bertwim
====================================================

for (i=0; i<argc; i++) {

Ice::ObjectPrx obj = _session->allocateObjectByType( ::Foo::MyFactory" );
Foo::MyFactoryPrx factory = Foo::MyFactoryPrx::checkedCast( obj );

Foo::MyProdPrx prod = factory->createProd();

prod->doSomething_async(...); // Note: asynchronous!

Ice::Identity id = factory->ice_getIdentity();
_session->releaseObject( id );
}

Comments

  • benoit
    benoit Rennes, France
    Hi,
    bwvb wrote: »
    Hi,

    Can I have a replicator group within a session?
    The factory object in the code below is allocated by type. There are several instances of it, and the idea of the loop below is to keep them all busy until the job is done.
    the Ice runtime returns randomly (according to the manual) an instance that is not locked by the session, but is blocking when all factory objects are in use. By releasing the factory object at the end of the body, one achieves that all factory objects are in use concurrently. (Wouldn't it be natural that the object is released automatically when it is destructed?)

    Hmm, I'm not sure I understand your suggestion. It seems that there's a small misunderstanding of how the allocation system works in IceGrid. The session methods allocateObjectById and allocateObjectByType allows you to allocate objects from a fixed pool of objects: the objects declared as allocatable in the IceGrid deployment descriptors. In your specific case, you allocate factory objects (with the type Foo::MyFactory). Objects created by the factory (with the type Foo::MyProd) are not viewed as allocated by IceGrid -- IceGrid doesn't have any knowledge about these objects.

    So I don't really understand your question about releasing automatically the factory when it's destroyed since the factory objects are not destroyed (the product of the factory might get destroyed but again, these objects are not part of the fixed pool of allocatable objects). So as soon as you release a factory object, it's made available to other clients even if the objects created by the factory (the MyProd objects in your example) are not done doing their job or destroyed.
    Now I want to add load-balancing. From the manual I read that replica-groups are meant for that purpose, but the example given does not involve a session.
    I have tried several ways, but to no avail.
    How can I achieve load-balancing in such a situation?

    Replica groups are in general not used with the allocation system because they really provide two distinct and different functionalities:
    • The allocation system allows Ice clients to coordinate access to a shared and fixed pool of Ice objects. This provides some load balancing by allocating objects to clients out of this pool randomly (other type of load balancing for allocating objects could be possible though, round robin, adaptive, etc, but we only support random allocation at this time).
    • Replica groups are used to provide Ice clients transparent access to a set of replicated objects. A replicated object is viewed by an Ice client as a single entity. When a client invokes on a proxy which points to a replicated object (an object from a replica group), the client will transparently be directed to a specific object replica (according to the replica group load balancing policy). If this object replica goes down for some reasons, it's transparently redirected to another replica.

    Let me know if this is still not clear of if you need more information!

    Cheers,
    Benoit.
  • What I meant with my suggestion:
    Consider the piece of code is showed earlier (I discovered the quote trick):
    for (i=0; i<argc; i++) {

    Ice::ObjectPrx obj = _session->allocateObjectByType( "::Foo::MyFactory" );
    Foo::MyFactoryPrx factory = Foo::MyFactoryPrx::checkedCast( obj );

    Foo::MyProdPrx prod = factory->createProd();

    prod->doSomething_async(...); // Note: asynchronous!

    Ice::Identity id = factory->ice_getIdentity();
    _session->releaseObject( id );
    }
    Reply With Quote

    At each cycle, a proxy called "factory" is created. At the end of the body, at each cycle, this proxy goes out of scope and its destructor will run. However, the underlying MyFactory object is still being hold by the session. I have to explicitly release it from the session. My question/suggestion was: can this releasing be done on destruction of the factory proxy? Or is it just that the object is not supposed to be aware that it is being hold by a session?
    The allocation system allows Ice clients to coordinate access to a shared and fixed pool of Ice objects. This provides some load balancing by allocating objects to clients out of this pool randomly (other type of load balancing for allocating objects could be possible though, round robin, adaptive, etc, but we only support random allocation at this time).
    Understood.
    On the load-balancing in the allocation system: yes, it would be nice if some clever form of load-balancing would be supported here as well.
    The usefulness of sessions in real life situations is not fully clear to me.

    Speaking in general, if you have 1 client but multiple servers, and each server resides behind a firewall (not necessarily the same firewall!, my understanding is that one needs to use a session and work with Glacier2. (and hence live with the "random" load-balancing).

    I would appreciate your comments.
    Thanks
    Bertwim
  • benoit
    benoit Rennes, France
    bwvb wrote: »
    At each cycle, a proxy called "factory" is created. At the end of the body, at each cycle, this proxy goes out of scope and its destructor will run. However, the underlying MyFactory object is still being hold by the session. I have to explicitly release it from the session.

    Ok, I better understand your question now :). I recommend you to take a look at this FAQ. As explained by the FAQ, proxies and Ice objects are really two different things. When the proxy object is destroyed (when it goes out of scope), the Ice object pointed by the proxy isn't destroyed (hence the misunderstanding, I thought you were mentioning the Ice object destruction in your first post :)).
    My question/suggestion was: can this releasing be done on destruction of the factory proxy? Or is it just that the object is not supposed to be aware that it is being hold by a session?

    Ice proxies have really no clues about the IceGrid allocation system so no -- the releasing can't be done when the proxy object is destroyed.
    On the load-balancing in the allocation system: yes, it would be nice if some clever form of load-balancing would be supported here as well.
    The usefulness of sessions in real life situations is not fully clear to me.

    IceGrid sessions are useful to allocate objects with the IceGrid allocation mechanism and this is useful to coordinate access to some objects among multiple clients.

    One use case is the one presented in the Ice manual where you have multiple machines hosting MP3 encoder objects. Clients use the allocation mechanism to allocate MP3 encoders. You could also not use the allocation mechanism but then you could end up with many clients using the same MP3 encoder concurrently (coordinating the clients ensures that not too many clients use the same encoder).
    Speaking in general, if you have 1 client but multiple servers, and each server resides behind a firewall (not necessarily the same firewall!, my understanding is that one needs to use a session and work with Glacier2. (and hence live with the "random" load-balancing).

    Sorry, I'm not sure understand your use case here. In general, the servers are all behind one firewall and are accessed through one Glacier2 router. A client can connect to multiple Glacier2 routers but it's much more complicated and in such cases it might be more reasonable and easier to use other solutions for firewall traversal, such a VPN for example.

    Perhaps you could describe what you're trying to achieve? This would help to better understand your needs and give you better guidance.

    Cheers,
    Benoit.
  • Benoit,

    Thanks for your previous answers. They are clear.
    On your remark:
    Sorry, I'm not sure understand your use case here. In general, the servers are all behind one firewall and are accessed through one Glacier2 router. A client can connect to multiple Glacier2 routers but it's much more complicated and in such cases it might be more reasonable and easier to use other solutions for firewall traversal, such a VPN for example.

    My use case is precisely the opposite of what you may consider "general": I am considering the use case where there is only one ("1") client application, that wants to spawn jobs over (to?) a (potentially large) number of identical servers. In a truly global network, one unfortunately cannot assume that all of these servers reside behind the same firewall. Theoretically each individual server could have its own policy which ports are available, but this is not the situation I'm after.It is more realisitc to consider the case where there are a few pools of servers, each pool having its own port access policy.
    As a limit situation, I now consider the case where there is 1 client and 2 servers, all three running on different machines, and each machine has its own security policy. What do I need to do?
    If the answer is that a non-Ice solution is to be preferred, that's fine with me.


    Regards,
    Bertwim
  • matthew
    matthew NL, Canada
    There are many different solutions to this particular problem. However, without more knowledge of what exactly you are trying to do, your goals, network architecture, restrictions and other such details its impossible to give you good advice on how to architect, manage and deploy Ice in your environment. If you provide more details we'll do our best to help.