load_balancer_i.cpp

来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 545 行 · 第 1/2 页

CPP
545
字号
// Load_Balancer_i.cpp,v 1.16 2003/11/01 11:15:08 dhinton Exp
// ============================================================================
//
// = FILENAME
//   Load_Balancer_i.cpp
//
// = AUTHOR
//    Marina Spivak <marina@cs.wustl.edu>
//
// ============================================================================

#include "Load_Balancer_i.h"
#include "ace/Auto_Ptr.h"
#include "ace/OS_NS_time.h"

Object_Group_Factory_i::Object_Group_Factory_i (void)
{
}

Object_Group_Factory_i::~Object_Group_Factory_i (void)
{
}

void
Object_Group_Factory_i::remove_group (const ACE_CString &id,
                                      int random)
{
  // Remove the entry from the appropriate map of groups.
  if (random)
    random_groups_.unbind (id);
  else
    rr_groups_.unbind (id);
}

Load_Balancer::Object_Group_ptr
Object_Group_Factory_i::make_round_robin (const char * id
                                          ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException,
                     Load_Balancer::duplicate_group))
{
  return make_group (0,
                     id
                     ACE_ENV_ARG_PARAMETER);
}

Load_Balancer::Object_Group_ptr
Object_Group_Factory_i::make_random (const char * id
                                     ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException,
                     Load_Balancer::duplicate_group))
{
  return make_group (1,
                     id
                     ACE_ENV_ARG_PARAMETER);
}

Load_Balancer::Object_Group_ptr
Object_Group_Factory_i::make_group (int random,
                                    const char * id
                                    ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException,
                     Load_Balancer::duplicate_group))
{
  ACE_CString group_id (id);

  // Check to make sure we don't already have a group with the same
  // <id>.
  if (rr_groups_.find (group_id) == 0
      || random_groups_.find (group_id) == 0)
    ACE_THROW_RETURN (Load_Balancer::duplicate_group (),
                      Load_Balancer::Object_Group::_nil ());
  else
    {
      // Store our result here for return.
      Load_Balancer::Object_Group_var group;

      // Create an appropriate servant.
      Object_Group_i * group_servant;
      if (random)
        ACE_NEW_THROW_EX (group_servant,
                          Random_Object_Group (id, this),
                          CORBA::NO_MEMORY ());
      else
        ACE_NEW_THROW_EX (group_servant,
                          RR_Object_Group (id, this),
                          CORBA::NO_MEMORY ());
      ACE_CHECK_RETURN (group._retn ());

      // Temporarily put the servant into the auto_ptr.
      ACE_Auto_Basic_Ptr<Object_Group_i> temp (group_servant);

      // Register with the poa, begin using ref. counting.
      group = group_servant->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
      ACE_CHECK_RETURN (group._retn ());

      group_servant->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
      ACE_CHECK_RETURN (Load_Balancer::Object_Group::_nil ());
      temp.release ();

      // Make an entry in appropriate map of groups.
      if (random)
        {
          if (random_groups_.bind (group_id, group) == -1)
            ACE_THROW_RETURN (CORBA::INTERNAL (),
                              Load_Balancer::Object_Group::_nil ());

          ACE_DEBUG ((LM_DEBUG,
                      "Load_Balancer: Created new Random Group"
                      " with id <%s>\n", id));
        }
      else
        {
          if (rr_groups_.bind (group_id, group) == -1)
            ACE_THROW_RETURN (CORBA::INTERNAL (),
                              Load_Balancer::Object_Group::_nil ());
          ACE_DEBUG ((LM_DEBUG,
                      "Load_Balancer: Created new Round Robin Group"
                      " with id <%s>\n", id));
        }
      // Return.
      return group._retn ();
    }
}

Load_Balancer::Object_Group_ptr
Object_Group_Factory_i::resolve (const char * id
                                 ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException,
                     Load_Balancer::no_such_group))
{
  ACE_CString group_id (id);
  Load_Balancer::Object_Group_var group;

  if (rr_groups_.find (group_id, group) == -1
      && random_groups_.find (group_id, group) == -1)
    ACE_THROW_RETURN (Load_Balancer::no_such_group (),
                      Load_Balancer::Object_Group::_nil ());
  else
    return group._retn ();
}

Load_Balancer::Group_List *
Object_Group_Factory_i::list_groups (int random
                                     ACE_ENV_ARG_DECL)
{
  Load_Balancer::Group_List * list;

  // Figure out the length of the list.
  CORBA::ULong len;
  if (random)
    len = random_groups_.current_size ();
  else
    len = rr_groups_.current_size ();

  // Allocate the list of <len> length.
  ACE_NEW_THROW_EX (list,
                    Load_Balancer::Group_List (len),
                    CORBA::NO_MEMORY ());
  ACE_CHECK_RETURN (list);
  list->length (len);

  // Create an iterator for group structure to populate the list.
  Object_Group_Factory_i::HASH_MAP::ITERATOR *group_iter;
  Object_Group_Factory_i::HASH_MAP::ITERATOR random_iter (random_groups_);
  Object_Group_Factory_i::HASH_MAP::ITERATOR rr_iter (rr_groups_);
  if (random)
    group_iter = &random_iter;
  else
    group_iter = &rr_iter;

  // Iterate over groups and populate the list.
  Object_Group_Factory_i::HASH_MAP::ENTRY *hash_entry;
  for (CORBA::ULong i = 0; i < len; i++)
    {
      group_iter->next (hash_entry);
      group_iter->advance ();

      (*list)[i] = hash_entry->ext_id_.c_str ();
    }

  return list;
}

Load_Balancer::Group_List *
Object_Group_Factory_i::round_robin_groups (ACE_ENV_SINGLE_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException))
{
  return list_groups (0 ACE_ENV_ARG_PARAMETER);
}

Load_Balancer::Group_List *
Object_Group_Factory_i::random_groups (ACE_ENV_SINGLE_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException))
{
  return list_groups (1 ACE_ENV_ARG_PARAMETER);
}

Object_Group_i::Object_Group_i (const char * id,
                                Object_Group_Factory_i *my_factory)
  : id_ (id),
    my_factory_ (my_factory)
{
}

Object_Group_i::~Object_Group_i (void)
{
  // Need to delete all the items from the member_id_list, to avoid
  // memory leaks.
  Object_Group_i::ITERATOR iter (member_id_list_);

  do
    {
      delete (iter.next ());
    } while (iter.advance ());
}

char *
Object_Group_i::id (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  return CORBA::string_dup (id_.c_str ());
}

void
Object_Group_i::bind (const Load_Balancer::Member & member
                      ACE_ENV_ARG_DECL)
  ACE_THROW_SPEC ((CORBA::SystemException,
                   Load_Balancer::duplicate_member))
{
  ACE_CString member_id (member.id);
  CORBA::Object_var obj = CORBA::Object::_duplicate (member.obj.in ());

  // Insert new member into <members_> and check for duplicates/failures.
  int result = members_.trybind (member_id, obj);
  if (result == 1)
    ACE_THROW (Load_Balancer::duplicate_member ());
  else if (result == -1)
    ACE_THROW (CORBA::INTERNAL ());

  // Insert new member's id into <member_id_list_>.
  ACE_CString *new_id;
  ACE_NEW_THROW_EX (new_id,
                    ACE_CString (member.id),
                    CORBA::NO_MEMORY ());
  ACE_CHECK;
  if (member_id_list_.insert_tail (new_id) == 0)
    ACE_THROW (CORBA::NO_MEMORY ());

  // Theoretically, we should deal with memory failures more
  // thoroughly.  But, practically, the whole system is going to be
  // hosed anyways ...

  ACE_DEBUG ((LM_DEBUG,
              "Load_Balancer: Added member <%s> to <%s> Group\n",
              member_id.c_str (),
              id_.c_str ()));
}

void
Object_Group_i::unbind (const char * id
                        ACE_ENV_ARG_DECL)
  ACE_THROW_SPEC ((CORBA::SystemException,
                   Load_Balancer::no_such_member))
{
  ACE_CString member_id (id);

  // Code below works iff list and hash map states are consistent,
  // which is the case unless the system experienced major problems,
  // e.g., ran out of memory ...

  // Check to make sure we have it.
  if (members_.find (member_id) == -1)
    ACE_THROW (Load_Balancer::no_such_member ());

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?