
//=============================================================================
/**
 *  @file    Load_Balancer.idl
 *
 *  Interfaces for a simple CORBA Load Balancing service, which can
 *  be used in conjunction with the Naming Service or alone to
 *  improve distributed load balancing.  See README file for a short
 *  discussion of other solution approaches for load balancing as
 *  well as use cases for this approach.
 *
 *
 *  @author Interfaces in this file came from OrbixNames Load Balancing features with modifications by: Doug Schmidt (schmidt@cs.wustl.edu) Marina Spivak (marina@cs.wustl.edu)
 */
//=============================================================================


module Load_Balancer
{
  // = TITLE
  //   Define a module that allows clients to treat a group
  //   of <Object>s, i.e., an <Object_Group>, as an equivalence class
  //   to improve distributed load balancing.
  //
  // = DESCRIPTION
  //   <Object_Group_Factory> is used to create <Object_Group>s.
  //   There are two logical types of <Object_Group>s :
  //
  //   1. Round Robin <Object_Group> -- This <Object_Group> resolves
  //      requests for arbitrary members in round robin order.
  //
  //   2. Random <Object_Group> -- This <Object_Group> resolves
  //      requests for arbitrary members in random order.
  //
  //   Both types of <Object_Group>s have the same interface (i.e.,
  //   <Object_Group>) but different behaviour should be provided
  //   in interface implementations appropriately.

  // = Module-defined exceptions.
  exception no_such_member {};
  exception duplicate_member {};
  exception duplicate_group {};
  exception no_such_group {};

  // = Module-defined types.

  typedef string Member_ID;
  typedef sequence<Member_ID> Member_ID_List;

  struct Member
  {
    Object obj;
    // IOR of an <Object_Group> member.

    Member_ID id;
    // Each member in an <Object_Group> is identified by a unique ID.
  };

  typedef string Group_ID;
  typedef sequence<Group_ID> Group_List;

  // = Forward interface decls.
  interface Object_Group;

  interface Object_Group_Factory
    {
      // = TITLE
      //   A factory that creates different types of
      //   <Object_Group>s and keeps track of them.
      //
      // = DESCRIPTION
      //   Currently, operations for two types of <Object_Group>s are
      //   defined: random and round robin.

      Object_Group make_round_robin (in Group_ID id)
        raises (duplicate_group);
      // Creates an <Object_Group> that resolves requests for arbitrary
      // members in round robin order.  If an <Object_Group>, of any
      // type, with Group_ID <id> has already been created by this
      // factory, and hasn't been destroyed, a <duplicate_group>
      // exception is thrown.

      Object_Group make_random (in Group_ID id)
        raises (duplicate_group);
      // Creates an <Object_Group> that resolves requests for arbitrary
      // members in random order.  If an <Object_Group>, of any
      // type, with Group_ID <id> has already been created by this
      // factory, and hasn't been destroyed, a <duplicate_group>
      // exception is thrown.

      Object_Group resolve (in Group_ID id) raises (no_such_group);
      // Locates and returns an <Object_Group> by its <Group_ID>.   If
      // no <Object_Group> has <Group_ID> of <id>, throw a
      // <no_such_group> exception.

      Group_List round_robin_groups ();
      // Lists all the round robin <Object_Group>s which were created
      // by this factory, and haven't been destroyed yet, i.e., return
      // a sequence of <Group_ID>s of all existing round robin
      // <Object_Group>s created by this factory.

      Group_List random_groups ();
      // Lists all the random <Object_Group>s which were created
      // by this factory, and haven't been destroyed yet, i.e., return
      // a sequence of <Group_ID>s of all existing random
      // <Object_Group>s created by this factory.
    };

  interface Object_Group
    {
      // = TITLE
      //   Holds references for 0 or more objects that form an
      //   equivalence class, and provides load balancing for those
      //   objects.
      //
      // = DESCRIPTION
      //   Whenever a client needs to find an object of a certain type
      //   or functionality, it makes a request to the appropriate
      //   <Object_Group>.  The <Object_Group> selects one of its
      //   members in accordance with the implemented policy (i.e.,
      //   random or round robin), and returnd it to the client, thus
      //   providing a form of load balancing for its members.
      //
      readonly attribute string id;
      // Each Object Group has its own distinct ID.

      void bind (in Member member_) raises (duplicate_member);
      // Adds a new <member> to the <Object_Group>.  Note that each
      // <Member_ID> in an <Object_Group> must be unique.  If the
      // group already contains a member with the same <Member_ID>, a
      // <duplicate_member> exceptions is thrown.

      void unbind (in Member_ID id) raises (no_such_member);
      // Removes a member with the specified <Member_ID> from the
      // <Object_Group>.  If none of the group's members have a
      // Member_ID of <id>, <no_such_member> exception is thrown.

      Object resolve () raises (no_such_member);
      // Returns a member object from this <Object_Group> in accordance with
      // load balancing policy it implements, i.e., ``random'' or
      // ``round robin.''  If the group contains no members, <no_such_member>
      // exception is thrown.

      Object resolve_with_id (in Member_ID id) raises (no_such_member);
      // Returns an object with the specified <Member_ID>.  If this
      // <Object_Group> contains no members with the specified
      // <Member_ID>, <no_such_member> exception is thrown.

      Member_ID_List members ();
      // Return a sequence of <Member_ID>s of all of its members.

      void destroy ();
      // Cleanup the resources associated with this <Object_Group>.
      // Subsequent calls to this <Object_Group> should fail, and its
      // <id> should become available.  <Object_Group_Factory>
      // should no longer list this <Object_Group>.
    };
};
