/* -*- C++ -*- */ //============================================================================= /** * @file Load_Balancer_i.h * * Defines classes that implement interfaces in Load_Balancer.idl * * @author Marina Spivak */ //============================================================================= #ifndef LOAD_BALANCER_I_H_ #define LOAD_BALANCER_I_H_ #include "Load_BalancerS.h" #include "ace/Hash_Map_Manager.h" #include "ace/SString.h" #include "ace/Synch.h" #include "ace/Containers.h" #include "ace/Null_Mutex.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) #pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ class Object_Group_Factory_i : public virtual POA_Load_Balancer::Object_Group_Factory { // = TITLE // This class implements Load_Balancer::Object_Group_Factory idl // interface. // // = DESCRIPTION // This implementation uses two s // to store to associations for all // load balancing groups created by this factory (one map keeps // track of all random groups, and the other keeps track of all // round robin groups). // public: /// Constructor. Object_Group_Factory_i (); /// Destructor. ~Object_Group_Factory_i (); // = Load_Balancer::Object_Group_Factory idl methods. /** * Creates an that resolves requests for arbitrary * members in round robin order. If an , of any * type, with Group_ID has already been created by this * factory, and hasn't been destroyed, a * exception is thrown. */ Load_Balancer::Object_Group_ptr make_round_robin (const char * id); /** * Creates an that resolves requests for arbitrary * members in random order. If an , of any * type, with Group_ID has already been created by this * factory, and hasn't been destroyed, a * exception is thrown. */ Load_Balancer::Object_Group_ptr make_random (const char * id); /** * Locates and returns an by its . If * no has of , throw a * exception. */ Load_Balancer::Object_Group_ptr resolve (const char * id); /** * Lists all the round robin s which were created * by this factory, and haven't been destroyed yet, i.e., return * a sequence of s of all existing round robin * s created by this factory. */ Load_Balancer::Group_List * round_robin_groups (); /** * Lists all the random s which were created * by this factory, and haven't been destroyed yet, i.e., return * a sequence of s of all existing random * s created by this factory. */ Load_Balancer::Group_List * random_groups (); // = Implementation detail methods. /** * This method is invoked by an with group id when it * is being destroyed. The method removes entry corresponding to * group from if is 1 or from * if is 0. This recycles , allowing it * to be used for new , and prevents the destroyed * group from being included in lists returned from * and methods. */ void remove_group (const ACE_CString &id, int random); private: // = Helper methods. /** * This function factors out common code in and * . Creates a random if parameter is * set to 1 and round robin if it is 0. */ Load_Balancer::Object_Group_ptr make_group (int random, const char * id); /** * This function factors out common code in and * . Returns a sequence of its random * groups if parameter is set to 1 and a sequence of its * round robin groups if it is 0. */ Load_Balancer::Group_List * list_groups (int random); /// Typedef for ease of use: hash map associating group ids to /// references. typedef ACE_Hash_Map_Manager HASH_MAP; /// Map containing all random s created by this factory. HASH_MAP random_groups_; /// Map containing all round robin s created by this factory. HASH_MAP rr_groups_; }; class Object_Group_i : public virtual POA_Load_Balancer::Object_Group { // = TITLE // This abstract class partially implements // Load_Balancer::Object_Group idl interface. // // = DESCRIPTION // is the only abstract method - subclasses should // define it in order to implement an appropriate load balancing // policy. Other methods can be overridden as needed. This class // factors out code common to implementations with // different load balancing policies. // public: /// Constructor. Object_Group_i (const char * id, Object_Group_Factory_i * my_factory); /// Destructor. ~Object_Group_i (); // = Load_Balancer::Object_Group idl methods. /// Get group's id. char * id (); /** * Adds a new to the . Note that each * in an must be unique. If the * group already contains a member with the same , a * exceptions is thrown. */ void bind (const Load_Balancer::Member & member); /** * Removes a member with the specified from the * . If none of the group's members have a * Member_ID of , exception is thrown. */ void unbind (const char * id); /** * Returns a member object from this in accordance with * load balancing policy it implements, i.e., ``random'' or * ``round robin.'' If the group contains no members, * exception is thrown. */ CORBA::Object_ptr resolve () = 0; /** * Returns an object with the specified . If this * contains no members with the specified * , exception is thrown. */ CORBA::Object_ptr resolve_with_id (const char * id); /// Return a sequence of s of all of its members. Load_Balancer::Member_ID_List * members (); /** * Cleanup the resources associated with this . * Subsequent calls to this should fail, and its * should become available. * should no longer list this . */ void destroy (); protected: /// Typedefs for ease of use. typedef ACE_DLList LIST; typedef ACE_DLList_Iterator ITERATOR; typedef ACE_Hash_Map_Manager HASH_MAP; /// List of ids of all the members of this group. LIST member_id_list_; /// Mapping of member_id to obj for all the members of this group. HASH_MAP members_; // Note, we store information redundantly in this implementation, // i.e., both and store member ids. // However, this redundancy eases/speeds up the implementation of // certain operations. is useful for implementing // variations of method to implement different policies. // is useful for doing id-based look-up. /// This group's id. ACE_CString id_; /** * Pointer to the servant, which created this * servant. We need this pointer to be able to * notify the factory when this is destroyed. Upon * notification, the factory can update its records and release * resources as necessary. */ Object_Group_Factory_i *my_factory_; }; /** * @class Random_Object_Group * * @brief This class implements idl interface with the * random policy for . */ class Random_Object_Group : public Object_Group_i { public: /// Constructor. Random_Object_Group (const char *id, Object_Group_Factory_i *my_factory); /// Destructor. ~Random_Object_Group (); /// Returns a member object from this in accordance with /// the "random" load balancing policy. CORBA::Object_ptr resolve (); /** * Cleanup the resources associated with this . * Subsequent calls to this should fail, and its * should become available. * should no longer list this . */ void destroy (); }; /** * @class RR_Object_Group: * * @brief This class implements idl interface with the * round robin policy for . */ class RR_Object_Group: public Object_Group_i { public: /// Constructor. RR_Object_Group (const char *id, Object_Group_Factory_i *my_factory); /// Destructor. ~RR_Object_Group (); /** * We need to override the implementation of from * Object_Group_i to make sure * works correctly. */ void unbind (const char * id); /// Returns a member object from this in accordance with /// the "round robin" load balancing policy. CORBA::Object_ptr resolve (); /** * Cleanup the resources associated with this . * Subsequent calls to this should fail, and its * should become available. * should no longer list this . */ void destroy (); private: /// Index into the Object_Group_i::member_id_list_: keeps track of /// the member_id to return on the next invocation of . size_t next_; }; #endif /* LOAD_BALANCER_I_H_ */