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 + -
显示快捷键?