diff options
Diffstat (limited to 'TAO/orbsvcs')
35 files changed, 3144 insertions, 36 deletions
diff --git a/TAO/orbsvcs/orbsvcs/CosLoadBalancing.dsp b/TAO/orbsvcs/orbsvcs/CosLoadBalancing.dsp new file mode 100644 index 00000000000..5c4ae49b3b4 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/CosLoadBalancing.dsp @@ -0,0 +1,390 @@ +# Microsoft Developer Studio Project File - Name="CosLoadBalancing" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=CosLoadBalancing - Win32 MFC Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "CosLoadBalancing.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "CosLoadBalancing.mak" CFG="CosLoadBalancing - Win32 MFC Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "CosLoadBalancing - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "CosLoadBalancing - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "CosLoadBalancing - Win32 MFC Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "CosLoadBalancing - Win32 MFC Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "CosLoadBalancing - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "DLL\Release\CosLoadBalancing"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CosLoadBalancing_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../" /I "../../" /I "../../../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "TAO_LOADBALANCING_BUILD_DLL" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 ace.lib TAO.lib TAO_PortableServer.lib TAO_CosNaming.lib TAO_PortableGroup.lib /nologo /dll /machine:I386 /out:"..\..\..\bin\TAO_CosLoadBalancing.dll" /libpath:"..\..\tao\PortableServer" /libpath:"..\..\tao" /libpath:"..\..\..\ace"
+
+!ELSEIF "$(CFG)" == "CosLoadBalancing - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "DLL\Debug\CosLoadBalancing"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CosLoadBalancing_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "../" /I "../../" /I "../../../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAO_LOADBALANCING_BUILD_DLL" /D "TAO_ORBSVCS_HAS_LOADBALANCING" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 TAOd.lib aced.lib TAO_PortableServerd.lib TAO_CosNamingd.lib TAO_PortableGroupd.lib /nologo /dll /debug /machine:I386 /out:"..\..\..\bin\TAO_CosLoadBalancingd.dll" /pdbtype:sept /libpath:"..\..\tao\PortableServer" /libpath:"..\..\tao" /libpath:"..\..\..\ace"
+# SUBTRACT LINK32 /profile
+
+!ELSEIF "$(CFG)" == "CosLoadBalancing - Win32 MFC Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "CosLoadBalancing___Win32_MFC_Debug"
+# PROP BASE Intermediate_Dir "CosLoadBalancing___Win32_MFC_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "DLL\Debug\CosLoadBalancing"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "../" /I "../../" /I "../../../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAO_LOADBALANCING_BUILD_DLL" /D "TAO_ORBSVCS_HAS_LOADBALANCING" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "../" /I "../../" /I "../../../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAO_LOADBALANCING_BUILD_DLL" /D "TAO_ORBSVCS_HAS_LOADBALANCING" /D ACE_HAS_MFC=1 /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 TAOd.lib aced.lib /nologo /dll /debug /machine:I386 /out:"..\..\..\bin\TAO_CosLoadBalancingd.dll" /pdbtype:sept /libpath:"..\..\tao" /libpath:"..\..\..\ace"
+# SUBTRACT BASE LINK32 /profile
+# ADD LINK32 TAOd.lib aced.lib TAO_PortableServermfcd.lib TAO_CosNamingmfcd.lib /nologo /dll /debug /machine:I386 /out:"..\..\..\bin\TAO_CosLoadBalancingmfcd.dll" /pdbtype:sept /libpath:"..\..\tao\PortableServer" /libpath:"..\..\tao" /libpath:"..\..\..\ace"
+# SUBTRACT LINK32 /profile
+
+!ELSEIF "$(CFG)" == "CosLoadBalancing - Win32 MFC Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "CosLoadBalancing___Win32_MFC_Release"
+# PROP BASE Intermediate_Dir "CosLoadBalancing___Win32_MFC_Release"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "DLL\Release\CosLoadBalancingMFC"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "../" /I "../../" /I "../../../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "TAO_LOADBALANCING_BUILD_DLL" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../" /I "../../" /I "../../../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "TAO_LOADBALANCING_BUILD_DLL" /D ACE_HAS_MFC=1 /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ace.lib TAO.lib /nologo /dll /machine:I386 /out:"..\..\..\bin\TAO_CosLoadBalancing.dll" /libpath:"..\..\tao" /libpath:"..\..\..\ace"
+# ADD LINK32 ace.lib TAO.lib TAO_PortableServermfc.lib TAO_CosNamingmfc.lib /nologo /dll /machine:I386 /out:"..\..\..\bin\TAO_CosLoadBalancingmfc.dll" /libpath:"..\..\tao\PortableServer" /libpath:"..\..\tao" /libpath:"..\..\..\ace"
+
+!ENDIF
+
+# Begin Target
+
+# Name "CosLoadBalancing - Win32 Release"
+# Name "CosLoadBalancing - Win32 Debug"
+# Name "CosLoadBalancing - Win32 MFC Debug"
+# Name "CosLoadBalancing - Win32 MFC Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\CosLoadBalancingC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CosLoadBalancingS.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_LoadManager.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_MemberLocator.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_MonitorMap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_Pull_Handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_Random.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm"
+# Begin Source File
+
+SOURCE=.\CosLoadBalancingC.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CosLoadBalancingS.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CosLoadBalancingS_T.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_conf.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_LeastLoaded.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_LoadManager.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_MemberLocator.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_MonitorMap.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_Pull_Handler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_Random.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CosLoadBalancing\LoadBalancing_export.h
+# End Source File
+# End Group
+# Begin Group "IDL Files"
+
+# PROP Default_Filter ".idl"
+# Begin Source File
+
+SOURCE=.\CosLoadBalancing.idl
+
+!IF "$(CFG)" == "CosLoadBalancing - Win32 Release"
+
+# PROP Ignore_Default_Tool 1
+USERDEP__COSLO="..\..\..\bin\Release\tao_idl.exe"
+# Begin Custom Build - Invoking TAO_IDL Compiler on $(InputName)
+InputPath=.\CosLoadBalancing.idl
+InputName=CosLoadBalancing
+
+BuildCmds= \
+ ..\..\..\bin\Release\tao_idl -Ge 1 -I../../ -I../../tao -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -Wb,export_macro=TAO_LoadBalancing_Export -Wb,export_include=LoadBalancing/Loadbalancing_export.h $(InputName).idl
+
+"$(InputName)C.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)C.i" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)C.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S.i" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S_T.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S_T.i" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S_T.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "CosLoadBalancing - Win32 Debug"
+
+# PROP Ignore_Default_Tool 1
+USERDEP__COSLO="..\..\..\bin\tao_idl.exe"
+# Begin Custom Build - Invoking TAO_IDL Compiler on $(InputName)
+InputPath=.\CosLoadBalancing.idl
+InputName=CosLoadBalancing
+
+BuildCmds= \
+ ..\..\..\bin\tao_idl -Ge 1 -I../../ -I../../tao -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -Wb,export_macro=TAO_LoadBalancing_Export -Wb,export_include=LoadBalancing/LoadBalancing_export.h $(InputName).idl
+
+"$(InputName)C.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)C.i" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)C.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S.i" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S_T.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S_T.i" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(InputName)S_T.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "CosLoadBalancing - Win32 MFC Debug"
+
+# PROP BASE Ignore_Default_Tool 1
+# PROP Ignore_Default_Tool 1
+
+!ELSEIF "$(CFG)" == "CosLoadBalancing - Win32 MFC Release"
+
+# PROP BASE Ignore_Default_Tool 1
+# PROP Ignore_Default_Tool 1
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Group "Inline Files"
+
+# PROP Default_Filter "i;inl"
+# Begin Source File
+
+SOURCE=.\CosLoadBalancingC.i
+# End Source File
+# Begin Source File
+
+SOURCE=.\CosLoadBalancingS.i
+# End Source File
+# Begin Source File
+
+SOURCE=.\CosLoadBalancingS_T.i
+# End Source File
+# Begin Source File
+
+SOURCE=.\LoadBalancing\LB_LeastLoaded.inl
+# End Source File
+# End Group
+# Begin Group "Template Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\CosLoadBalancingS_T.cpp
+
+!IF "$(CFG)" == "CosLoadBalancing - Win32 Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "CosLoadBalancing - Win32 Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "CosLoadBalancing - Win32 MFC Debug"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "CosLoadBalancing - Win32 MFC Release"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\CosLoadBalancing.rc
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/TAO/orbsvcs/orbsvcs/CosLoadBalancing.idl b/TAO/orbsvcs/orbsvcs/CosLoadBalancing.idl index 030eee89443..238dfcbf75f 100644 --- a/TAO/orbsvcs/orbsvcs/CosLoadBalancing.idl +++ b/TAO/orbsvcs/orbsvcs/CosLoadBalancing.idl @@ -44,7 +44,7 @@ module CosLoadBalancing /// Types used for obtaining and/or reporting loads typedef unsigned long LoadId; struct Load { - LoadId identifier; + LoadId id; float value; }; typedef sequence<Load> LoadList; @@ -81,21 +81,40 @@ module CosLoadBalancing Properties get_properties (); + // Report loads at given location to the Strategy. void push_loads (in PortableGroup::Location the_location, in LoadList loads) raises (LocationNotFound, StrategyNotAdaptive); + // Return the next member from the given object group which will + // requests will be forward to. Object next_member (in PortableGroup::ObjectGroup object_group, in LoadManager load_manager) raises (PortableGroup::ObjectGroupNotFound, PortableGroup::MemberNotFound); + + // Ask the Strategy to analyze loads, and enable or disable alerts + // at object group members residing at appropriate locations. + oneway void analyze_loads (in LoadManager load_manager); + + // The given loads at the given location should no longer be + // considered when performing load analysis. + void location_removed (in PortableGroup::Location the_location) + raises (LocationNotFound); + }; + + struct StrategyInfo + { + + Properties props; }; - interface Alertable + interface LoadAlert { - // Forward requests back to the load manager. - void alert (in Object load_manager); + // Forward requests back to the load manager via the object group + // reference. + void alert (in Object object_group); // Stop forwarding requests, and begin accepting them again. void disable_alert (); @@ -125,8 +144,7 @@ module CosLoadBalancing // For the PUSH load monitoring style. void push_loads (in PortableGroup::Location the_location, in LoadList loads) - raises (LocationNotFound, - StrategyNotAdaptive); + raises (StrategyNotAdaptive); // The following load monitor methods are only used for the PULL // load monitoring style. @@ -140,8 +158,9 @@ module CosLoadBalancing void remove_load_monitor (in PortableGroup::Location the_location) raises (LocationNotFound); - void register_redirector (in PortableGroup::ObjectGroup object_group, - in PortableGroup::Location the_location) + void register_alerter (in PortableGroup::ObjectGroup object_group, + in PortableGroup::Location the_location, + in Object alert) raises (LocationNotFound); }; diff --git a/TAO/orbsvcs/orbsvcs/CosLoadBalancing.rc b/TAO/orbsvcs/orbsvcs/CosLoadBalancing.rc new file mode 100644 index 00000000000..95b44fda7f1 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/CosLoadBalancing.rc @@ -0,0 +1,30 @@ +#include "..\..\tao\Version.h" + +1 VERSIONINFO + FILEVERSION TAO_MAJOR_VERSION,TAO_MINOR_VERSION,TAO_BETA_VERSION,0 + PRODUCTVERSION TAO_MAJOR_VERSION,TAO_MINOR_VERSION,TAO_BETA_VERSION,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "FileDescription", "CosLoadBalancing\0" + VALUE "FileVersion", TAO_VERSION "\0" + VALUE "InternalName", "TAO_CosLoadBalancingDLL\0" + VALUE "LegalCopyright", "\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "TAO_CosLoadBalancing.DLL\0" + VALUE "ProductName", "ORBSVCS\0" + VALUE "ProductVersion", TAO_VERSION "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/TAO/orbsvcs/orbsvcs/LB_LeastLoaded.inl b/TAO/orbsvcs/orbsvcs/LB_LeastLoaded.inl new file mode 100644 index 00000000000..d2d3dc420cd --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_LeastLoaded.inl @@ -0,0 +1,36 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE CORBA::Float +TAO_LB_LeastLoaded::raw_load (CORBA::Float load) +{ + return this->dampened_load (load + this->per_balance_load_); +} + + +ACE_INLINE CORBA::Float +TAO_LB_LeastLoaded::raw_load (CORBA::Float load) +{ + return this->dampened_load (load + this->per_balance_load_); +} + + +ACE_INLINE CORBA::Float +TAO_LB_LeastLoaded::effective_load (CORBA::Float previous_load, + CORBA::Float new_load) +{ + // Apply per-balance load. (Recompute raw load) + previous_load += this->per_balance_load_; + + // Apply dampening. (Recompute new raw load) + CORBA::Float result = + this->dampening_ * previous_load + (1 - this->dampening_) * new_load; + + ACE_ASSERT (this->tolerance_ != 0); + + // Compute th effective load. + result = raw_load / this->tolerance_; + + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp new file mode 100644 index 00000000000..50bf88300d1 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp @@ -0,0 +1,414 @@ +// -*- C++ -*- + +#include "LB_LeastLoaded.h" +#include "orbsvcs/PortableGroup/PG_conf.h" +#include "tao/debug.h" + +ACE_RCSID (LoadBalancing, + LB_LeastLoaded, + "$Id$") + + +#if !defined (__ACE_INLINE__) +#include "LB_LeastLoaded.inl" +#endif /* defined INLINE */ + + +TAO_LB_LeastLoaded::TAO_LB_LeastLoaded (void) + : load_map_ (TAO_PG_MAX_LOCATIONS), + lock_ (), + critical_threshold_ (0), + reject_threshold_ (0), + tolerance_ (1), + dampening_ (0), + per_balance_load_ (0) +{ +} + +TAO_LB_LeastLoaded::~TAO_LB_LeastLoaded (void) +{ +} + +char * +TAO_LB_LeastLoaded::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::string_dup ("TAO_LB_LeastLoaded"); +} + +CosLoadBalancing::Properties * +TAO_LB_LeastLoaded::get_properties (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CosLoadBalancing::Properties * props = 0; + ACE_NEW_THROW_EX (props, + CosLoadBalancing::Properties, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (props); + + return props; +} + +void +TAO_LB_LeastLoaded::push_loads ( + const PortableGroup::Location & the_location, + const CosLoadBalancing::LoadList & loads + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::StrategyNotAdaptive)) +{ + // Only the first load is used by this load balancing strategy. + if (loads.length () == 0) + ACE_THROW (CORBA::BAD_PARAM ()); + + const CosLoadBalancing::Load & new_load = loads[0]; + + TAO_LB_LoadMap::ENTRY * load; + if (this->load_map_.find (the_location, load) == 0) + { + CosLoadBalancing::Load & previous_load = load->int_id_; + + if (previous_load.id != new_load.id) + ACE_THROW (CORBA::BAD_PARAM ()); // Somebody switched LoadIds + // on us! + + previous_load.value = + this->effective_load (previous_load.value, new_load.value); + } + else + { + const CosLoadBalancing::Load eff_load = + { + new_load.id, + this->effective_load (0, new_load.value); + }; + + if (this->load_map_.bind (the_location, eff_load) != 0) + { + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "ERROR: TAO_LB_LeastLoaded - Unable to push loads\n")); + + ACE_THROW (CORBA::INTERNAL ()); + } + } +} + +CORBA::Object_ptr +TAO_LB_LeastLoaded::next_member ( + PortableGroup::ObjectGroup_ptr object_group, + CosLoadBalancing::LoadManager_ptr load_manager + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)) +{ + if (CORBA::is_nil (load_manager)) + ACE_THROW_RETURN (CORBA::BAD_PARAM (), + CORBA::Object::_nil ()); + + PortableGroup::Locations_var locations = + load_manager->locations_of_members (object_group + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + if (locations->length () == 0) + ACE_THROW_RETURN (CORBA::TRANSIENT (), + CORBA::Object::_nil ()); + + // @@ RACE CONDITION. OBJECT GROUP MEMBERSHIP MAY CHANGE AFTER + // RETRIEVING LOCATIONS! HOW DO WE HANDLE THAT? + + PortableGroup::Location location; + CORBA::Boolean found_location = + this->get_location (locations.in (), location); + + if (found_location) + { + return load_manager->get_member_ref (object_group, + location + ACE_ENV_ARG_PARAMETER); + } + else + { + // This should never occur. + ACE_THROW_RETURN (CORBA::INTERNAL (), + CORBA::Object::_nil ()); + } +} + +void +TAO_LB_LeastLoaded::analyze_loads ( + PortableGroup::ObjectGroup_ptr object_group, + CosLoadBalancing::LoadManager_ptr load_manager + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + int send_load_advisory = 0; + + { + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + + TAO_LB_Location_Map::iterator begin = + location_map.begin (); + + TAO_LB_Location_Map::iterator end = + location_map.end (); + + float s = 0; + CORBA::ULong n = 0; + TAO_LB_Location_Map::iterator i = begin; + for ( ; i != end; ++i) + { + s += (*i)->int_id_.load_list[0].value; // @@ Hard coded to + // get things + // going. + n++; + } + + float avg = (n == 0 ? s : s / n); + float cl = proxy->current_load (); + + if (avg == 0) + return; + + float relative_load = cl / avg; + + // @@ Ossama: Make the 1.5 factor adjustable, it is how much + // dispersion we tolerate before starting to send advisories. + if (relative_load > 1 + 1.5F / n) + { + proxy->has_high_load_ = 1; + send_load_advisory = 2; // 2 == Send high load advisory + } + + if (send_load_advisory == 1 && relative_load < 1 + 0.9F / n) + { + proxy->has_high_load_ = 0; + send_load_advisory = 1; // 1 == Send nominal load advisory + } + } + + // @@ Ossama: no debug messages in production code, my fault.... + // ACE_DEBUG ((LM_DEBUG, "Load[%x] %f %f %f\n", + // proxy, cl, avg, relative_load)); + + // @@ Ossama: Make the 1.5 factor adjustable, it is how much + // dispersion we tolerate before starting to send advisories. + if (send_load_advisory == 2) + { + proxy->control_->high_load_advisory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + return; // We may not throw an exception, so explicitly return. + } + + // @@ Ossama: notice that we wait until the load is signifcantly + // lower before sending the nominal load advisory, it does not + // matter that much because the replicas automatically restart after + // rejecting one client.... + // @@ Ossama: make the 0.9 factor adjustable, at least at + // construction time... + if (send_load_advisory == 1) + { + proxy->control_->nominal_load_advisory (ACE_ENV_SINGLE_ARG_PARAMETE); + ACE_CHECK; + } + +} + +CORBA::Boolean +TAO_LB_LeastLoaded::get_location ( + const PortableGroup::Locations & locations, + PortableGroup::Location & location) +{ + CORBA::Float min_load = 0; + CORBA::ULong location_index = 0; + CORBA::Boolean found_location = 0; + + const CORBA::ULong len = locations.length (); + + { + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, + guard, + this->lock_, + 0); + + for (CORBA::ULong i = 0; i < len; ++i) + { + // WRONG!!! THIS IS LEAST LOADED, NOT MINIMUM DISPERSION! + LoadMap::ENTRY * entry; + if (this->load_map_.find (locations[i], entry) == 0 + && (i == 0 || entry.value < min_load)) + { + min_load = entry->value; + location_index = i; + found_location = 1; + } + } + } + + if (found_location) + location = locations[location_index]; + + return found_location; +} + +CORBA::Object_ptr +TAO_LB_LeastLoaded::replica ( + TAO_LB_ObjectGroup_Map_Entry *entry + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + for ( ; ; ) + { + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, + guard, + entry->lock, + CORBA::Object::_nil ()); + + if (entry->replica_infos.is_empty ()) + // @@ What do we do if the set is empty? + ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (), + CORBA::Object::_nil ()); + + TAO_LB_ReplicaInfo_Set::iterator begin = entry->replica_infos.begin (); + TAO_LB_ReplicaInfo_Set::iterator end = entry->replica_infos.end (); + + TAO_LB_ReplicaInfo_Set::iterator i = begin; + TAO_LB_ReplicaInfo *replica_info = (*i); + + LoadBalancing::LoadList *d = + replica_info->location_entry->load_list.ptr (); + + for (++i ; i != end; ++i) + { + LoadBalancing::LoadList *load = + (*i)->location_entry->load_list.ptr (); + + // @@ Hardcode one load and don't bother checking the + // LoadId, for now. (just to get things going) + if ((*d)[CORBA::ULong (0)].value > (*load)[CORBA::ULong (0)].value) + { + replica_info = *i; + d = (*i)->location_entry->load_list.ptr (); + } + } + + // Before returning an object reference to the client + // validate it first. + CORBA::Object_ptr object = replica_info->replica.in (); + + { + ACE_Reverse_Lock<TAO_SYNCH_MUTEX> reverse_lock (entry->lock); + + ACE_GUARD_RETURN (ACE_Reverse_Lock<TAO_SYNCH_MUTEX>, + reverse_guard, + reverse_lock, + CORBA::Object::_nil ()); + + // @@ Ossama: we should setup a timeout policy here... + ACE_TRY + { + CORBA::Boolean non_existent = + object->_non_existent (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!non_existent) + { + return CORBA::Object::_duplicate (object); + } + } + ACE_CATCHANY + { + // @@ HACK! Do the right thing! + return CORBA::Object::_duplicate (object); + } + ACE_ENDTRY; + } + } +} + +void +TAO_LB_LeastLoaded::analyze_loads ( + TAO_LB_Location_Map &location_map + ACE_ENV_ARG_DECL) +{ + int send_load_advisory = 0; + + { + ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX, + guard, + this->lock_)); + + + TAO_LB_Location_Map::iterator begin = + location_map.begin (); + + TAO_LB_Location_Map::iterator end = + location_map.end (); + + float s = 0; + CORBA::ULong n = 0; + TAO_LB_Location_Map::iterator i = begin; + for ( ; i != end; ++i) + { + s += (*i)->int_id_.load_list[0].value; // @@ Hard coded to + // get things + // going. + n++; + } + + float avg = (n == 0 ? s : s / n); + float cl = proxy->current_load (); + + if (avg == 0) + return; + + float relative_load = cl / avg; + + // @@ Ossama: Make the 1.5 factor adjustable, it is how much + // dispersion we tolerate before starting to send advisories. + if (relative_load > 1 + 1.5F / n) + { + proxy->has_high_load_ = 1; + send_load_advisory = 2; // 2 == Send high load advisory + } + + if (send_load_advisory == 1 && relative_load < 1 + 0.9F / n) + { + proxy->has_high_load_ = 0; + send_load_advisory = 1; // 1 == Send nominal load advisory + } + } + + // @@ Ossama: no debug messages in production code, my fault.... + // ACE_DEBUG ((LM_DEBUG, "Load[%x] %f %f %f\n", + // proxy, cl, avg, relative_load)); + + // @@ Ossama: Make the 1.5 factor adjustable, it is how much + // dispersion we tolerate before starting to send advisories. + if (send_load_advisory == 2) + { + proxy->control_->high_load_advisory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + return; // We may not throw an exception, so explicitly return. + } + + // @@ Ossama: notice that we wait until the load is signifcantly + // lower before sending the nominal load advisory, it does not + // matter that much because the replicas automatically restart after + // rejecting one client.... + // @@ Ossama: make the 0.9 factor adjustable, at least at + // construction time... + if (send_load_advisory == 1) + { + proxy->control_->nominal_load_advisory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.h new file mode 100644 index 00000000000..266244c55d8 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.h @@ -0,0 +1,120 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_LeastLoaded.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef LB_LEAST_LOADED_H +#define LB_LEAST_LOADED_H + +#include "ace/pre.h" + +#include "LB_LoadMap.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/CosLoadBalancingS.h" + +#include "ace/Synch.h" + +/** + * @class TAO_LB_LeastLoaded + * + * @brief "Least loaded" load balancing strategy + * + * This load balancing strategy is designed to select an object group + * member residing at a location with the smallest load. + */ +class TAO_LoadBalancing_Export TAO_LB_LeastLoaded + : public virtual POA_CosLoadBalancing::Strategy +{ +public: + typedef TAO_LB_LoadMap LoadMap; + + /// Constructor. + TAO_LB_LeastLoaded (void); + + /// Destructor + ~TAO_LB_LeastLoaded (void); + + /** + * @name CosLoadBalancing::Strategy methods + * + * Methods required by the CosLoadBalancing::Strategy interface. + */ + //@{ + virtual char * name (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CosLoadBalancing::Properties * get_properties ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void push_loads ( + const PortableGroup::Location & the_location, + const CosLoadBalancing::LoadList & loads + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::StrategyNotAdaptive)); + + virtual CORBA::Object_ptr next_member ( + PortableGroup::ObjectGroup_ptr object_group, + CosLoadBalancing::LoadManager_ptr load_manager + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)); + + virtual void analyze_loads ( + PortableGroup::ObjectGroup_ptr object_group, + CosLoadBalancing::LoadManager_ptr load_manager + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + //@} + +protected: + + /// Retrieve the least loaded location from the given list of + /// locations. + CORBA::Boolean get_location (const PortableGroup::Locations & locations, + PortableGroup::Location & location); + + + /// Return the effective load. + CORBA::Float effective_load (CORBA::Float previous_load, + CORBA::Float new_load); + +private: + + /// Container that maps location to load list. + LoadMap load_map_; + + /// Lock used to ensure atomic access to state retained by this + /// class. + TAO_SYNCH_MUTEX lock_; + + CORBA::Float critical_threshold_; + CORBA::Float reject_threshold_; + CORBA::Float tolerance_; + CORBA::Float dampening_; + CORBA::Float per_balance_load_; + +}; + + +#if defined (__ACE_INLINE__) +#include "LB_LeastLoaded.inl" +#endif /* defined INLINE */ + +#include "ace/post.h" + +#endif /* LB_LEAST_LOADED_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.inl b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.inl new file mode 100644 index 00000000000..d2d3dc420cd --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.inl @@ -0,0 +1,36 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE CORBA::Float +TAO_LB_LeastLoaded::raw_load (CORBA::Float load) +{ + return this->dampened_load (load + this->per_balance_load_); +} + + +ACE_INLINE CORBA::Float +TAO_LB_LeastLoaded::raw_load (CORBA::Float load) +{ + return this->dampened_load (load + this->per_balance_load_); +} + + +ACE_INLINE CORBA::Float +TAO_LB_LeastLoaded::effective_load (CORBA::Float previous_load, + CORBA::Float new_load) +{ + // Apply per-balance load. (Recompute raw load) + previous_load += this->per_balance_load_; + + // Apply dampening. (Recompute new raw load) + CORBA::Float result = + this->dampening_ * previous_load + (1 - this->dampening_) * new_load; + + ACE_ASSERT (this->tolerance_ != 0); + + // Compute th effective load. + result = raw_load / this->tolerance_; + + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadManager.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadManager.cpp new file mode 100644 index 00000000000..b47a3d92b60 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadManager.cpp @@ -0,0 +1,621 @@ +#include "LB_LoadManager.h" +#include "LB_MemberLocator.h" +#include "LB_conf.h" + +#include "orbsvcs/PortableGroup/PG_Property_Utils.h" +#include "orbsvcs/PortableGroup/PG_conf.h" + +#include "tao/ORB_Core.h" + +//#include "ace/Auto_Ptr.h" + + +ACE_RCSID (LoadBalancing, + LB_LoadManager, + "$Id$") + + +TAO_LB_LoadManager::TAO_LB_LoadManager (void) + : reactor_ (0), + poa_ (), + lock_ (), + monitor_map_ (TAO_PG_MAX_LOCATIONS), + object_group_manager_ (), + property_manager_ (object_group_manager_), + generic_factory_ (object_group_manager_, property_manager_), + pull_handler_ (), + timer_id_ (-1), + lm_ref_ () +{ + this->pull_handler_.initialize (&this->monitor_map_, this); +} + +TAO_LB_LoadManager::~TAO_LB_LoadManager (void) +{ +} + +void +TAO_LB_LoadManager::push_loads ( + const PortableGroup::Location & /* the_location */, + const CosLoadBalancing::LoadList & /* loads */ + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::StrategyNotAdaptive)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LB_LoadManager::register_load_monitor ( + CosLoadBalancing::LoadMonitor_ptr load_monitor, + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::MonitorAlreadyPresent)) +{ + if (CORBA::is_nil (load_monitor)) + ACE_THROW (CORBA::BAD_PARAM ()); + + const CosLoadBalancing::LoadMonitor_var the_monitor = + CosLoadBalancing::LoadMonitor::_duplicate (load_monitor); + + ACE_GUARD (TAO_SYNCH_MUTEX, + guard, + this->lock_); + + int result = this->monitor_map_.bind (the_location, the_monitor); + + if (result == 0 + && this->monitor_map_.current_size () == 1) + { + // Register the "pull monitoring" event handler only after the + // first load monitor is registered. This is an optimization to + // prevent unnecessary invocation of the "pull monitoring" event + // handler. + ACE_Time_Value interval (TAO_LB_PULL_HANDLER_INTERVAL, 0); + ACE_Time_Value restart (TAO_LB_PULL_HANDLER_RESTART, 0); + this->timer_id_ = this->reactor_->schedule_timer (&this->pull_handler_, + 0, + interval, + restart); + + if (this->timer_id_ == -1) + { + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "TAO_LB_LoadManager::register_load_monitor: " + "Unable to schedule timer.\n")); + + ACE_THROW (CORBA::INTERNAL ()); + } + } + else if (result == 1) + ACE_THROW (CosLoadBalancing::MonitorAlreadyPresent ()); + else + { + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "TAO_LB_LoadManager::register_load_monitor: " + "Unable to register load monitor.\n")); + + ACE_THROW (CORBA::INTERNAL ()); + } +} + +CosLoadBalancing::LoadMonitor_ptr +TAO_LB_LoadManager::get_load_monitor ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::LocationNotFound)) +{ + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, + guard, + this->lock_, + CosLoadBalancing::LoadMonitor::_nil ()); + + TAO_LB_MonitorMap::ENTRY * entry; + if (this->monitor_map_.find (the_location, entry) == 0) + { + return + CosLoadBalancing::LoadMonitor::_duplicate (entry->int_id_.in ()); + } + + ACE_THROW_RETURN (CosLoadBalancing::LocationNotFound (), + CosLoadBalancing::LoadMonitor::_nil ()); +} + +void +TAO_LB_LoadManager::remove_load_monitor ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::LocationNotFound)) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, + guard, + this->lock_); + + if (this->monitor_map_.unbind (the_location) != 0) + ACE_THROW (CosLoadBalancing::LocationNotFound ()); + + // If no load monitors are registered with the load balancer than + // shutdown the "pull monitoring." + if (this->timer_id_ != -1 + && this->monitor_map_.current_size () == 0) + { + if (this->reactor_->cancel_timer (this->timer_id_) == 0) + { + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "TAO_LB_LoadManager::remove_load_monitor: " + "Unable to cancel timer.\n")); + + ACE_THROW (CORBA::INTERNAL ()); + } + + this->timer_id_ = -1; + } +} + +void +TAO_LB_LoadManager::set_default_properties ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + this->property_manager_.set_default_properties (props + ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::Properties * +TAO_LB_LoadManager::get_default_properties ( + ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return + this->property_manager_.get_default_properties ( + ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +TAO_LB_LoadManager::remove_default_properties ( + const PortableGroup::Properties &props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + this->property_manager_.remove_default_properties (props + ACE_ENV_ARG_PARAMETER); +} + +void +TAO_LB_LoadManager::set_type_properties ( + const char *type_id, + const PortableGroup::Properties &overrides + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + this->property_manager_.set_type_properties (type_id, + overrides + ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::Properties * +TAO_LB_LoadManager::get_type_properties ( + const char *type_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return + this->property_manager_.get_type_properties (type_id + ACE_ENV_ARG_PARAMETER); +} + +void +TAO_LB_LoadManager::remove_type_properties ( + const char *type_id, + const PortableGroup::Properties &props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + this->property_manager_.remove_type_properties (type_id, + props + ACE_ENV_ARG_PARAMETER); +} + +void +TAO_LB_LoadManager::set_properties_dynamically ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Properties &overrides + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + this->property_manager_.set_properties_dynamically (object_group, + overrides + ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::Properties * +TAO_LB_LoadManager::get_properties ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)) +{ + return + this->property_manager_.get_properties (object_group + ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::ObjectGroup_ptr +TAO_LB_LoadManager::create_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location &the_location, + const char *type_id, + const PortableGroup::Criteria &the_criteria + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberAlreadyPresent, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)) +{ + return + this->object_group_manager_.create_member (object_group, + the_location, + type_id, + the_criteria + ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::ObjectGroup_ptr +TAO_LB_LoadManager::add_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location &the_location, + CORBA::Object_ptr member + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberAlreadyPresent, + PortableGroup::ObjectNotAdded)) +{ + return + this->object_group_manager_.add_member (object_group, + the_location, + member + ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::ObjectGroup_ptr +TAO_LB_LoadManager::remove_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location &the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)) +{ + return + this->object_group_manager_.remove_member (object_group, + the_location + ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::Locations * +TAO_LB_LoadManager::locations_of_members ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)) +{ + return + this->object_group_manager_.locations_of_members (object_group + ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::ObjectGroupId +TAO_LB_LoadManager::get_object_group_id ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)) +{ + return + this->object_group_manager_.get_object_group_id (object_group + ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::ObjectGroup_ptr +TAO_LB_LoadManager::get_object_group_ref ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)) +{ + return + this->object_group_manager_.get_object_group_ref (object_group + ACE_ENV_ARG_PARAMETER); +} + +CORBA::Object_ptr +TAO_LB_LoadManager::get_member_ref ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location &the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)) +{ + return + this->object_group_manager_.get_member_ref (object_group, + the_location + ACE_ENV_ARG_PARAMETER); +} + +CORBA::Object_ptr +TAO_LB_LoadManager::create_object ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out + factory_creation_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::InvalidProperty, + PortableGroup::CannotMeetCriteria)) +{ +// this->init (ACE_ENV_SINGLE_ARG_PARAMETER); +// ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + CORBA::Object_ptr obj = + this->generic_factory_.create_object (type_id, + the_criteria, + factory_creation_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + + return obj; +} + +#if 0 +void +TAO_LB_LoadManager::process_criteria ( + const PortableGroup::Criteria & the_criteria + ACE_ENV_ARG_DECL) +{ + // List of invalid criteria. If this list has a length greater than + // zero, then the PortableGroup::InvalidCriteria exception will + // be thrown. + PortableGroup::Criteria invalid_criteria; + + int found_factory = 0; // If factory was found in the_criteria, then + // set to 1. + + // Parse the criteria. + CORBA::ULong criteria_count = the_criteria.length (); + for (CORBA::ULong i = 0; i < criteria_size; ++i) + { + CORBA::UShort initial_number_replicas = 0; + PortableGroup::FactoryInfos factory_infos; + + // Obtain the InitialNumberMembers from the_criteria. + if (this->get_initial_number_replicas (type_id, + the_criteria[i], + initial_number_replicas) != 0) + { + CORBA::ULong len = invalid_criteria.length (); + invalid_criteria.length (len + 1); + invalid_criteria[len] = the_criteria[i]; + } + + // Obtain the FactoryInfos from the_criteria. This method also + // ensures that GenericFactories at different locations are used. + else if (this->get_factory_infos (type_id, + the_criteria[i], + factory_infos) == 0) + found_factory = 1; + + // Unknown property + else + ACE_THROW (PortableGroup::InvalidProperty (the_criteria[i].nam, + the_criteria[i].val)); + } + + if (invalid_criteria.length () != 0) + ACE_THROW (PortableGroup::InvalidCriteria (invalid_criteria)); + + if (found_factory == 0) + ACE_THROW (PortableGroup::NoFactory ()); +} +#endif /* 0 */ + +void +TAO_LB_LoadManager::delete_object ( + const PortableGroup::GenericFactory::FactoryCreationId & + factory_creation_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectNotFound)) +{ + this->generic_factory_.delete_object (factory_creation_id + ACE_ENV_ARG_PARAMETER); +} + +CORBA::Object_ptr +TAO_LB_LoadManager::member (const PortableServer::ObjectId & oid + ACE_ENV_ARG_DECL) +{ + // Pass the cached loads to the balancing strategy so that the + // strategy may choose which member to forward requests to next. + + PortableGroup::ObjectGroup_var object_group = + this->object_group_manager_.object_group (oid); + + if (CORBA::is_nil (object_group.in ())) + ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (), + CORBA::Object::_nil ()); + + PortableGroup::Properties_var properties = + this->get_properties (object_group.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + // @todo Cache this property name. No need to create it each time + // this method is called. + PortableGroup::Name balancing_strategy_name (1); + balancing_strategy_name.length (1); + balancing_strategy_name[0].id = + CORBA::string_dup ("org.omg.CosLoadBalancing.Strategy"); + + PortableGroup::Value value; + CosLoadBalancing::Strategy_var balancing_strategy; + if (TAO_PG::get_property_value (balancing_strategy_name, + properties.in (), + value) + && (value >>= balancing_strategy.inout ()) + && !CORBA::is_nil (balancing_strategy.in ())) + { + // @todo Cache this ObjectGroupManager reference. + PortableGroup::ObjectGroupManager_var group_manager = + this->object_group_manager_._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + return balancing_strategy->next_member (object_group.in (), + this->lm_ref_.in () + ACE_ENV_ARG_PARAMETER); + } + else + { + ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (), + CORBA::Object::_nil ()); + } +} + +void +TAO_LB_LoadManager::init ( + CORBA::ORB_ptr orb, + PortableServer::POA_ptr root_poa + ACE_ENV_ARG_DECL) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, + guard, + this->lock_); + + if (CORBA::is_nil (this->poa_.in ())) + { + // Create a new transient servant manager object in the child + // POA. + PortableServer::ServantManager_ptr tmp; + ACE_NEW_THROW_EX (tmp, + TAO_LB_MemberLocator (this), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK; + + PortableServer::ServantManager_var member_locator = tmp; + + // Create the appropriate RequestProcessingPolicy + // (USE_SERVANT_MANAGER) and ServantRetentionPolicy (NON_RETAIN) + // for a ServantLocator. + PortableServer::RequestProcessingPolicy_var request = + root_poa->create_request_processing_policy ( + PortableServer::USE_SERVANT_MANAGER + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ServantRetentionPolicy_var retention = + root_poa->create_servant_retention_policy ( + PortableServer::NON_RETAIN + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Create the PolicyList containing the policies necessary for + // the POA to support ServantLocators. + CORBA::PolicyList policy_list; + policy_list.length (2); + policy_list[0] = + PortableServer::RequestProcessingPolicy::_duplicate ( + request.in ()); + policy_list[1] = + PortableServer::ServantRetentionPolicy::_duplicate ( + retention.in ()); + + // Create the child POA with the above ServantManager policies. + // The ServantManager will be the MemberLocator. + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + + // The child POA's name will consist of a string that includes + // the current time in milliseconds in hexidecimal format (only + // four bytes will be used). This is an attempt to prevent + // different load manager servants within the same ORB from + // using the same POA. + const ACE_Time_Value tv = ACE_OS::gettimeofday (); + const CORBA::Long time = + ACE_static_cast (CORBA::Long, + tv.msec ()); // Time in milliseconds. + + char poa_name[] = "TAO_LB_LoadManager_POA - 0xZZZZZZZZ"; + char * astr = + poa_name + + sizeof (poa_name) + - 9 /* 8 + 1 */; + + // Overwrite the last 8 characters in the POA name. + ACE_OS::sprintf (astr, "%d", time); + + this->poa_ = root_poa->create_POA (poa_name, + poa_manager.in (), + policy_list + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + request->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + retention->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Now set the MemberLocator as the child POA's Servant + // Manager. + this->poa_->set_servant_manager (member_locator.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->object_group_manager_.poa (this->poa_.in ()); + this->generic_factory_.poa (this->poa_.in ()); + + // Activate the child POA. + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->reactor_ = orb->orb_core ()->reactor (); + } + + if (CORBA::is_nil (this->lm_ref_.in ())) + { + this->lm_ref_ = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadManager.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadManager.h new file mode 100644 index 00000000000..8ac92176c53 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadManager.h @@ -0,0 +1,393 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_LoadManager.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef TAO_LB_LOAD_MANAGER_H +#define TAO_LB_LOAD_MANAGER_H + +#include "ace/pre.h" + +#include "orbsvcs/CosLoadBalancingS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +#include "LB_MonitorMap.h" +#include "LB_Pull_Handler.h" + +#include "orbsvcs/PortableGroupC.h" + +#include "orbsvcs/PortableGroup/PG_PropertyManager.h" +#include "orbsvcs/PortableGroup/PG_GenericFactory.h" +#include "orbsvcs/PortableGroup/PG_ObjectGroupManager.h" + + +/// Forward declarations +class TAO_LB_Balancing_Strategy; + + +class TAO_LoadBalancing_Export TAO_LB_LoadManager + : public virtual POA_CosLoadBalancing::LoadManager +{ +public: + + /// Constructor. + TAO_LB_LoadManager (void); + + /// Destructor. + ~TAO_LB_LoadManager (void); + + /** + * @name CosLoadBalancing::LoadManager Methods + * + * Methods required by the CosLoadBalancing::LoadManager interface. + */ + //@{ + + // For the PUSH load monitoring style. + virtual void push_loads (const PortableGroup::Location & the_location, + const CosLoadBalancing::LoadList & loads + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::StrategyNotAdaptive)); + + /// Register a load monitor with the load balancer. + virtual void register_load_monitor ( + CosLoadBalancing::LoadMonitor_ptr load_monitor, + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::MonitorAlreadyPresent)); + + /// Return a reference to the load monitor at the given location. + virtual CosLoadBalancing::LoadMonitor_ptr get_load_monitor ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::LocationNotFound)); + + /// Remove a load monitor at the given location from the load + /// balancer. + virtual void remove_load_monitor ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::LocationNotFound)); + + //@} + + /** + * @name PortableGroup::PropertyManager Methods + * + * Methods required by the PortableGroup::PropertyManager interface. + */ + //@{ + + /// Set the default properties to be used by all object groups. + virtual void set_default_properties ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /// Get the default properties used by all object groups. + virtual PortableGroup::Properties * get_default_properties ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Remove default properties. + virtual void remove_default_properties ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /// Set properties associated with a given Replica type. These + /// properties override the default properties. + virtual void set_type_properties ( + const char * type_id, + const PortableGroup::Properties & overrides + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /** + * Return the properties associated with a give Replica type. These + * properties include the type-specific properties in use, in + * addition to the default properties that were not overridden. + */ + virtual PortableGroup::Properties * get_type_properties ( + const char * type_id + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Remove the given properties associated with the Replica type ID. + virtual void remove_type_properties ( + const char * type_id, + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /** + * Dynamically set the properties associated with a given object + * group as the load balancer and replicas are being executed. + * These properties override the type-specific and default + * properties. + */ + virtual void set_properties_dynamically ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Properties & overrides + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /** + * Return the properties currently in use by the given object + * group. These properties include those that were set dynamically, + * type-specific properties that weren't overridden, properties that + * were used when the Replica was created, and default properties + * that weren't overridden. + */ + virtual PortableGroup::Properties * get_properties ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)); + + //@} + + /** + * @name PortableGroup::ObjectGroupManager methods + * + * Methods required by the PortableGroup::ObjectGroupManager + * interface. + */ + //@{ + + /// Create a member using the load balancer ObjectGroupManager, and + /// add the created object to the ObjectGroup. + virtual PortableGroup::ObjectGroup_ptr create_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location, + const char * type_id, + const PortableGroup::Criteria & the_criteria + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberAlreadyPresent, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)); + + /// Add an existing object to the ObjectGroup. + virtual PortableGroup::ObjectGroup_ptr add_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location, + CORBA::Object_ptr member + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberAlreadyPresent, + PortableGroup::ObjectNotAdded)); + + /** + * Remove an object at a specific location from the given + * ObjectGroup. Deletion of application created objects must be + * deleted by the application. Objects created by the + * infrastructure (load balancer) will be deleted by the + * infrastructure. + */ + virtual PortableGroup::ObjectGroup_ptr remove_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)); + + /// Return the locations of the members in the given ObjectGroup. + virtual PortableGroup::Locations * locations_of_members ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)); + + /// Return the ObjectGroupId for the given ObjectGroup. + virtual PortableGroup::ObjectGroupId get_object_group_id ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)); + + /// @note Does this method make sense for load balanced objects? + virtual PortableGroup::ObjectGroup_ptr get_object_group_ref ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)); + + /// Return the reference corresponding to the Replica of a given + /// ObjectGroup at the given location. + virtual CORBA::Object_ptr get_member_ref ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & loc + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)); + + //@} + + /** + * @name PortableGroup::GenericFactory methods + * + * Methods required by the PortableGroup::GenericFactory interface. + */ + //@{ + + /** + * Create an object of the specified type that adheres to the + * restrictions defined by the provided Criteria. The out + * FactoryCreationId parameter may be passed to the delete_object() + * method to delete the object. + */ + virtual CORBA::Object_ptr create_object ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out + factory_creation_id + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::InvalidProperty, + PortableGroup::CannotMeetCriteria)); + + /** + * Delete the object corresponding to the provided + * FactoryCreationId. If the object is actually an ObjectGroup, + * then all members within the ObjectGroup will be deleted. + * Afterward, the ObjectGroup itself will be deleted. + */ + virtual void delete_object ( + const PortableGroup::GenericFactory::FactoryCreationId & + factory_creation_id + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectNotFound)); + + //@} + + /// Return the next member to which client requests will be + /// forwarded. + /** + * Select the next member of the object group corresponding to the + * given ObjectId. The object group's load balancing strategy + * will be queried that member. + */ + CORBA::Object_ptr member (const PortableServer::ObjectId & oid + ACE_ENV_ARG_DECL); + +public: + + /// Return a reference to the replica to which the current client + /// request will be forwarded. + /** + * The load balancer does the right thing and figures which object + * group the replica should be chosen from. + */ + CORBA::Object_ptr replica (const PortableServer::ObjectId &oid + ACE_ENV_ARG_DECL); + + + /// Initialize the load balancer. This will cause a child POA to be + /// created with the appropriate policies to support ServantLocators + /// (i.e. for the ReplicaLocator). + void init (CORBA::ORB_ptr orb, + PortableServer::POA_ptr root_poa + ACE_ENV_ARG_DECL); + +private: + + /// Extract the value of the InitialNumberReplicas property from + /// the_criteria. + int get_initial_number_replicas ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + CORBA::UShort & initial_number_replicas) const; + + /// Extract the value of the Factories property from the_criteria. + /** + * This method ensures that the locations in the returned + * FactoryInfos are unique. This is necessary to ensure that only + * one replica of a given type is created by the load balancer at a + * given location. + */ + int get_factory_infos ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::FactoryInfos & factory_infos) const; + +private: + + /// Reactor used when pulling loads from registered load monitors. + ACE_Reactor * reactor_; + + /// The POA that dispatches requests to the ReplicaLocator. + PortableServer::POA_var poa_; + + /// Mutex that provides synchronization. + TAO_SYNCH_MUTEX lock_; + + /// Table that maps PortableGroup::Location to load monitor at that + /// location. + TAO_LB_MonitorMap monitor_map_; + + /// The ObjectGroupManager that implements the functionality + /// necessary for application-controlled object group membership. + TAO_PG_ObjectGroupManager object_group_manager_; + + /// The PropertyManager that is reponsible for parsing all criteria, + /// and keeping track of property-type_id associations. + TAO_PG_PropertyManager property_manager_; + + /// The GenericFactory responsible for creating all object groups. + TAO_PG_GenericFactory generic_factory_; + + /// The event handler that performs "pull monitoring" on all + /// registered load monitors. + TAO_LB_Pull_Handler pull_handler_; + + /// Timer ID corresponding to the timer that fires off the "pull + /// monitoring" event handler. + long timer_id_; + + /// Cached object reference that points to this servant. + CosLoadBalancing::LoadManager_var lm_ref_; + +}; + + +#include "ace/post.h" + +#endif /* TAO_LB_LOAD_MANAGER_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMap.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMap.cpp new file mode 100644 index 00000000000..6c49f1327c0 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMap.cpp @@ -0,0 +1,26 @@ +// -*- C++ -*- + +#include "LB_LoadMap.h" + +ACE_RCSID (LoadBalancing, + LB_LoadMap, + "$Id$") + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class ACE_Hash_Map_Entry<PortableGroup::Location, CosLoadBalancing::Load>; +template class ACE_Hash_Map_Manager_Ex<PortableGroup::Location, CosLoadBalancing::Load, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Base_Ex<PortableGroup::Location, CosLoadBalancing::Load, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Ex<PortableGroup::Location, CosLoadBalancing::Load, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator_Ex<PortableGroup::Location, CosLoadBalancing::Load, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Hash_Map_Entry<PortableGroup::Location, CosLoadBalancing::Load> +#pragma instantiate ACE_Hash_Map_Manager_Ex<PortableGroup::Location, CosLoadBalancing::Load, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<PortableGroup::Location, CosLoadBalancing::Load, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Ex<PortableGroup::Location, CosLoadBalancing::Load, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<PortableGroup::Location, CosLoadBalancing::Load, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMap.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMap.h new file mode 100644 index 00000000000..26c62ecfed3 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMap.h @@ -0,0 +1,43 @@ +// -*- C++ -*- + +//======================================================================= +/** + * @file LB_LoadMap.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//======================================================================= + + +#ifndef TAO_LB_LOAD_MAP_H +#define TAO_LB_LOAD_MAP_H + +#include "ace/pre.h" + +#include "orbsvcs/CosLoadBalancingC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/PortableGroupC.h" + +#include "orbsvcs/PortableGroup/PG_Location_Hash.h" +#include "orbsvcs/PortableGroup/PG_Location_Equal_To.h" + +#include "ace/Hash_Map_Manager_T.h" + + +/// Load hash map. +typedef ACE_Hash_Map_Manager_Ex< + PortableGroup::Location, + CosLoadBalancing::Load, + TAO_PG_Location_Hash, + TAO_PG_Location_Equal_To, + ACE_Null_Mutex> TAO_LB_LoadMap; + +#include "ace/post.h" + +#endif /* TAO_LB_LOAD_MAP_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MemberLocator.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MemberLocator.cpp new file mode 100644 index 00000000000..1c189bf7f2c --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MemberLocator.cpp @@ -0,0 +1,49 @@ +#include "LB_MemberLocator.h" +#include "LB_LoadManager.h" + +ACE_RCSID (LoadBalancing, + LB_MemberLocator, + "$Id$") + +TAO_LB_MemberLocator::TAO_LB_MemberLocator ( + TAO_LB_LoadManager * lm) + : load_manager_ (lm) +{ + ACE_ASSERT (lm != 0); +} + +PortableServer::Servant +TAO_LB_MemberLocator::preinvoke ( + const PortableServer::ObjectId & oid, + PortableServer::POA_ptr /* adapter */, + const char * /* operation */, + PortableServer::ServantLocator::Cookie & /* the_cookie */ + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableServer::ForwardRequest)) +{ + CORBA::Object_var member = + this->load_manager_->member (oid + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + +// ACE_DEBUG ((LM_DEBUG, +// "FORWARDED\n")); + + // Throw a forward exception to force the client to redirect its + // requests to the member chosen by the LoadBalancer. + ACE_THROW_RETURN (PortableServer::ForwardRequest (member.in ()), + 0); +} + +void +TAO_LB_MemberLocator::postinvoke ( + const PortableServer::ObjectId & /* oid */, + PortableServer::POA_ptr /* adapter */, + const char * /* operation */, + PortableServer::ServantLocator::Cookie /* the_cookie */, + PortableServer::Servant /* the_servant */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MemberLocator.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MemberLocator.h new file mode 100644 index 00000000000..b664866cec9 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MemberLocator.h @@ -0,0 +1,89 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_MemberLocator.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef TAO_LB_MEMBER_LOCATOR_H +#define TAO_LB_MEMBER_LOCATOR_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PortableServer/PortableServerC.h" +#include "tao/LocalObject.h" + +// Forward declarations. +class TAO_LB_LoadManager; + + +/** + * @class TAO_LB_MemberLocator + * + * @brief ServantLocator implementation for the Load Balancer. + * + * This is a Servant Locator implementation that forwards requests to + * a member returned by the Load Balancer. + */ +class TAO_LB_MemberLocator + : public virtual PortableServer::ServantLocator, + public virtual TAO_Local_RefCounted_Object +{ +public: + + /// Constructor + TAO_LB_MemberLocator (TAO_LB_LoadManager * load_balancer); + + /** + * @name The PortableServer::ServantLocator methods. + * + * Methods required by the PortableServer::ServantLocator + * interface. + */ + //@{ + + /// Clients requests are forwarded via the + /// PortableServer::ForwardRequest exception thrown in this method. + virtual PortableServer::Servant preinvoke ( + const PortableServer::ObjectId & oid, + PortableServer::POA_ptr adapter, + const char * operation, + PortableServer::ServantLocator::Cookie & the_cookie + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableServer::ForwardRequest)); + + /// This method is no-op in this ServantLocator implementation. + virtual void postinvoke ( + const PortableServer::ObjectId &oid, + PortableServer::POA_ptr adapter, + const char * operation, + PortableServer::ServantLocator::Cookie the_cookie, + PortableServer::Servant the_servant + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + //@} + +private: + + /// The load balancer/manager implementation. + TAO_LB_LoadManager * load_manager_; + +}; + +#include "ace/post.h" + +#endif /* TAO_LB_MEMBER_LOCATOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MonitorMap.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MonitorMap.cpp new file mode 100644 index 00000000000..9089e0021f2 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MonitorMap.cpp @@ -0,0 +1,27 @@ +// -*- C++ -*- + +#include "LB_LoadMap.h" + + +ACE_RCSID (LoadBalancing, + LB_MonitorMap, + "$Id$") + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class ACE_Hash_Map_Entry<PortableGroup::Location, CosLoadBalancing::LoadMonitor_var>; +template class ACE_Hash_Map_Manager_Ex<PortableGroup::Location, CosLoadBalancing::LoadMonitor_var, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Base_Ex<PortableGroup::Location, CosLoadBalancing::LoadMonitor_var, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Ex<PortableGroup::Location, CosLoadBalancing::LoadMonitor_var, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator_Ex<PortableGroup::Location, CosLoadBalancing::LoadMonitor_var, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Hash_Map_Entry<PortableGroup::Location, CosLoadBalancing::LoadMonitor_var> +#pragma instantiate ACE_Hash_Map_Manager_Ex<PortableGroup::Location, CosLoadBalancing::LoadMonitor_var, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<PortableGroup::Location, CosLoadBalancing::LoadMonitor_var, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Ex<PortableGroup::Location, CosLoadBalancing::LoadMonitor_var, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<PortableGroup::Location, CosLoadBalancing::LoadMonitor_var, TAO_PG_Location_Hash, TAO_PG_Location_Equal_To, ACE_Null_Mutex> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MonitorMap.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MonitorMap.h new file mode 100644 index 00000000000..4f839696573 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_MonitorMap.h @@ -0,0 +1,42 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_MonitorMap.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef TAO_LB_MONITOR_MAP_H +#define TAO_LB_MONITOR_MAP_H + +#include "ace/pre.h" + +#include "orbsvcs/CosLoadBalancingC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/PortableGroup/PG_Location_Hash.h" +#include "orbsvcs/PortableGroup/PG_Location_Equal_To.h" + +#include "ace/Hash_Map_Manager_T.h" + + +/// Load monitor hash map. +typedef ACE_Hash_Map_Manager_Ex< + PortableGroup::Location, + CosLoadBalancing::LoadMonitor_var, + TAO_PG_Location_Hash, + TAO_PG_Location_Equal_To, + ACE_Null_Mutex> TAO_LB_MonitorMap; + + +#include "ace/post.h" + +#endif /* TAO_LB_MONITOR_MAP_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Pull_Handler.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Pull_Handler.cpp new file mode 100644 index 00000000000..460d3b4e22d --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Pull_Handler.cpp @@ -0,0 +1,80 @@ +#include "LB_Pull_Handler.h" +#include "LB_LoadManager.h" + +#include "tao/debug.h" + + +ACE_RCSID (LoadBalancing, + LB_Pull_Handler, + "$Id$") + + +TAO_LB_Pull_Handler::TAO_LB_Pull_Handler (void) + : monitor_map_ (0), + load_manager_ (0) +{ +} + +void +TAO_LB_Pull_Handler::initialize (TAO_LB_MonitorMap * monitor_map, + TAO_LB_LoadManager * load_manager) +{ + this->monitor_map_ = monitor_map; + this->load_manager_ = load_manager; +} + +int +TAO_LB_Pull_Handler::handle_timeout ( + const ACE_Time_Value & /* current_time */, + const void * /* arg */) +{ + // @todo Fix the race condtions in this method. + + TAO_LB_MonitorMap::iterator begin = this->monitor_map_->begin (); + TAO_LB_MonitorMap::iterator end = this->monitor_map_->end (); + + if (begin == end) + return 0; // No work to be done. + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // Iterate over all registered load monitors. + // + // @todo This could be potentially very slow. Improve concurrent + // operation at some point in the near future. + for (TAO_LB_MonitorMap::iterator i = begin; i != end; ++i) + { + const PortableGroup::Location & location = (*i).ext_id_; + CosLoadBalancing::LoadMonitor_var & monitor = (*i).int_id_; + + // The load monitor reference should never be nil since the + // LoadManager prevents nil load monitor references from + // being registered. + CosLoadBalancing::LoadList_var load_list = + monitor->loads (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->load_manager_->push_loads (location, + load_list.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + +// ACE_DEBUG ((LM_DEBUG, +// "LOCATION = %s\tLOAD = %f\n", +// (*i).ext_id_[0].id.in (), +// location->load_list[0].value)); + } + } + ACE_CATCHANY + { + // Catch the exception and ignore it. + + if (TAO_debug_level > 0) + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "(%P|%t) PullHandler::handle_timeout()\n"); + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Pull_Handler.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Pull_Handler.h new file mode 100644 index 00000000000..d4018a4e13a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Pull_Handler.h @@ -0,0 +1,70 @@ +// -*- C++ -*- + +//======================================================================= +/** + * @file LB_Pull_Handler.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//======================================================================= + + +#ifndef TAO_LB_PULL_HANDLER_H +#define TAO_LB_PULL_HANDLER_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "LB_MonitorMap.h" + +#include "ace/Event_Handler.h" + + +/// Forward declarations. +class TAO_LB_LoadManager; + + +/** + * @class TAO_LB_Pull_Handler + * + * @brief Event handler used when the "pull" monitoring style is + * configured. + * + * An event handler designed to pull loads from all load monitors + * registered with the load balancer. + */ +class TAO_LB_Pull_Handler : public ACE_Event_Handler +{ +public: + + /// Constructor + TAO_LB_Pull_Handler (void); + + /// Receive the timeout event. + virtual int handle_timeout (const ACE_Time_Value ¤t_time, + const void *arg); + + /// Initialize this event handler. + void initialize (TAO_LB_MonitorMap * monitor_map, + TAO_LB_LoadManager * load_manager); + +private: + + /// The table that contains all load monitors registered with the + /// load balancer. + TAO_LB_MonitorMap * monitor_map_; + + /// Pointer to the LoadManager servant. + TAO_LB_LoadManager * load_manager_; + +}; +#include "ace/post.h" + +#endif /* TAO_LB_PULL_HANDLER_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Random.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Random.cpp new file mode 100644 index 00000000000..38a018f12c7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Random.cpp @@ -0,0 +1,102 @@ +// -*- C++ -*- + +#include "LB_Random.h" + +ACE_RCSID (LoadBalancing, + LB_Random, + "$Id$") + +TAO_LB_Random::TAO_LB_Random (void) +{ + // Seed the random number generator with the current time. + ACE_OS::srand (ACE_static_cast (unsigned int, ACE_OS::time ())); +} + +char * +TAO_LB_Random::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::string_dup ("TAO_LB_Random"); +} + +CosLoadBalancing::Properties * +TAO_LB_Random::get_properties (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CosLoadBalancing::Properties * props = 0; + ACE_NEW_THROW_EX (props, + CosLoadBalancing::Properties, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (props); + + return props; +} + +void +TAO_LB_Random::push_loads ( + const PortableGroup::Location & /* the_location */, + const CosLoadBalancing::LoadList & /* loads */ + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::StrategyNotAdaptive)) +{ + ACE_THROW (CosLoadBalancing::StrategyNotAdaptive ()); +} + +CORBA::Object_ptr +TAO_LB_Random::next_member ( + PortableGroup::ObjectGroup_ptr object_group, + CosLoadBalancing::LoadManager_ptr load_manager + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)) +{ + PortableGroup::Locations_var locations = + load_manager->locations_of_members (object_group + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + const CORBA::ULong len = locations->length (); + if (len == 0) + ACE_THROW_RETURN (CORBA::TRANSIENT (), + CORBA::Object::_nil ()); + + // Pick a random location in the sequence using the higher order + // bits (zero based indexing). + // + // See Numerical Recipes in C: The Art of Scientific Computing + // (William H. Press, Brian P. Flannery, Saul A. Teukolsky, + // William T. Vetterling; New York: Cambridge University Press, + // 1992 (2nd ed., p. 277)) for details on why using the lower order + // bits, as in (rand() % 10), is bad. In particular, the lower + // order bits in older rand() implementations may not be as random + // as the higher order bits. + // + // @todo It would be better to use the random() function since it + // is supposed to have a larger period than rand(), in + // addition to the fact that the lower order bits should be as + // random as the higher order bits. + const CORBA::ULong i = + ACE_static_cast (CORBA::ULong, + (len * ACE_OS::rand () / (RAND_MAX + 1.0))); + + ACE_ASSERT (i < len); + + return load_manager->get_member_ref (object_group, + locations[i] + ACE_ENV_ARG_PARAMETER); +} + +void +TAO_LB_Random::analyze_loads ( + PortableGroup::ObjectGroup_ptr /* object_group */, + CosLoadBalancing::LoadManager_ptr /* load_manager */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Random.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Random.h new file mode 100644 index 00000000000..5518bdb1e76 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Random.h @@ -0,0 +1,84 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_Random.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef LB_RANDOM_H +#define LB_RANDOM_H + +#include "ace/pre.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/CosLoadBalancingS.h" + +/** + * @class TAO_LB_Random + * + * @brief "Random" load balancing strategy + * + * This load balancing strategy is designed to select an object group + * member residing at a random location. + */ +class TAO_LoadBalancing_Export TAO_LB_Random + : public virtual POA_CosLoadBalancing::Strategy +{ +public: + + /// Constructor. + /** + * Seeds the OS' random number generator. + */ + TAO_LB_Random (void); + + /** + * @name CosLoadBalancing::Strategy methods + * + * Methods required by the CosLoadBalancing::Strategy interface. + */ + //@{ + virtual char * name (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CosLoadBalancing::Properties * get_properties ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void push_loads ( + const PortableGroup::Location & the_location, + const CosLoadBalancing::LoadList & loads + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + CosLoadBalancing::StrategyNotAdaptive)); + + virtual CORBA::Object_ptr next_member ( + PortableGroup::ObjectGroup_ptr object_group, + CosLoadBalancing::LoadManager_ptr load_manager + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)); + + virtual void analyze_loads ( + PortableGroup::ObjectGroup_ptr object_group, + CosLoadBalancing::LoadManager_ptr load_manager + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + //@} + +}; + + +#include "ace/post.h" + +#endif /* LB_RANDOM_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_conf.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_conf.h new file mode 100644 index 00000000000..8386057144d --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_conf.h @@ -0,0 +1,43 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_conf.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef TAO_LB_CONF_H +#define TAO_LB_CONF_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/CosLoadBalancingC.h" + + +#ifndef TAO_LB_PULL_HANDLER_INTERVAL +/// The interval in seconds the load balancer queries registered load +/// monitors for loads. +const long TAO_LB_PULL_HANDLER_INTERVAL = 1; +#endif /* TAO_LB_PULL_HANDLER_INTERVAL */ + +#ifndef TAO_LB_PULL_HANDLER_RESTART +/// The time in seconds the load balancer's "pull handler" is +/// restarted after being fired. +const long TAO_LB_PULL_HANDLER_RESTART = 1; +#endif /* TAO_LB_PULL_HANDLER_RESTART */ + + +#include "ace/post.h" + +#endif /* TAO_LB_CONF_H */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup.dsp b/TAO/orbsvcs/orbsvcs/PortableGroup.dsp index c779e2bef9b..f93a4e3711f 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup.dsp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup.dsp @@ -173,6 +173,10 @@ SOURCE=.\miopC.cpp # End Source File
# Begin Source File
+SOURCE=.\PortableGroup\PG_Default_Property_Validator.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\PortableGroup\PG_Factory_Map.cpp
# End Source File
# Begin Source File
@@ -201,6 +205,10 @@ SOURCE=.\PortableGroup\PG_MemberInfo.cpp # End Source File
# Begin Source File
+SOURCE=.\PortableGroup\PG_Null_Property_Validator.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\PortableGroup\PG_ObjectGroup_Map.cpp
# End Source File
# Begin Source File
@@ -474,6 +482,10 @@ SOURCE=.\PortableGroup\PG_conf.h # End Source File
# Begin Source File
+SOURCE=.\PortableGroup\PG_Default_Property_Validator.h
+# End Source File
+# Begin Source File
+
SOURCE=.\PortableGroup\PG_Factory_Map.h
# End Source File
# Begin Source File
@@ -502,6 +514,10 @@ SOURCE=.\PortableGroup\PG_MemberInfo.h # End Source File
# Begin Source File
+SOURCE=.\PortableGroup\PG_Null_Property_Validator.h
+# End Source File
+# Begin Source File
+
SOURCE=.\PortableGroup\PG_ObjectGroup_Map.h
# End Source File
# Begin Source File
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.cpp new file mode 100644 index 00000000000..16955c48ac0 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.cpp @@ -0,0 +1,135 @@ +#include "PG_Default_Property_Validator.h" +#include "PG_Operators.h" + + +ACE_RCSID (PortableGroup, + PG_Default_Property_Validator, + "$Id$") + + +TAO_PG_Default_Property_Validator::TAO_PG_Default_Property_Validator (void) + : membership_ (1), + factories_ (1) +{ + this->membership_.length (1); + this->membership_[0].id = CORBA::string_dup ("org.omg.PortableGroup.MembershipStyle"); + + this->factories_.length (1); + this->factories_[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories"); +} + +void +TAO_PG_Default_Property_Validator::validate_property ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + const CORBA::ULong len = props.length (); + + for (CORBA::ULong i = 0; i < len; ++i) + { + const PortableGroup::Property & property = props[i]; + + if (property.nam == this->membership_) + { + PortableGroup::MembershipStyleValue membership; + if (!(property.val >>= membership) + || (membership != PortableGroup::MEMB_APP_CTRL + && membership != PortableGroup::MEMB_INF_CTRL)) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + } + else if (property.nam == this->factories_) + { + PortableGroup::FactoriesValue * factories; + if (!(property.val >>= factories)) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + else + { + const CORBA::ULong flen = factories->length (); + + if (flen == 0) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + + for (CORBA::ULong j = 0; j < flen; ++j) + { + const PortableGroup::FactoryInfo & factory_info = + (*factories)[j]; + + if (CORBA::is_nil (factory_info.the_factory.in ()) + || factory_info.the_location.length () == 0) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + } + } + } + } +} + +void +TAO_PG_Default_Property_Validator::validate_criteria ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)) +{ + const CORBA::ULong len = props.length (); + PortableGroup::Criteria invalid_criteria; + + // Optimize for the worst case scenario where all properties are + // invalid. + invalid_criteria.length (len); + + /// The invalid criteria index. + CORBA::ULong p = 0; + + for (CORBA::ULong i = 0; i < len; ++i) + { + const PortableGroup::Property & property = props[i]; + + if (property.nam == this->membership_) + { + PortableGroup::MembershipStyleValue membership; + if (!(property.val >>= membership) + || (membership != PortableGroup::MEMB_APP_CTRL + && membership != PortableGroup::MEMB_INF_CTRL)) + invalid_criteria[p++] = property; + } + else if (property.nam == this->factories_) + { + PortableGroup::FactoriesValue * factories; + if (!(property.val >>= factories)) + invalid_criteria[p++] = property; + else + { + const CORBA::ULong flen = factories->length (); + + if (flen == 0) + invalid_criteria[p++] = property; + else + { + for (CORBA::ULong j = 0; j < flen; ++j) + { + const PortableGroup::FactoryInfo & factory_info = + (*factories)[j]; + + if (CORBA::is_nil (factory_info.the_factory.in ()) + || factory_info.the_location.length () == 0) + { + invalid_criteria[p++] = property; + break; + } + } + } + } + } + } + + if (p > 0) + ACE_THROW (PortableGroup::InvalidCriteria (invalid_criteria)); +} diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.h new file mode 100644 index 00000000000..f3aa3b06049 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.h @@ -0,0 +1,77 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file PG_Default_Property_Validator.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + +#ifndef TAO_PG_DEFAULT_PROPERTY_VALIDATOR_H +#define TAO_PG_DEFAULT_PROPERTY_VALIDATOR_H + +#include "ace/pre.h" + +#include "orbsvcs/PortableGroupC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +/** + * @class TAO_PG_Default_Property_Validator + * + * @brief Default property validator implementation. + * + * This Property_Validator verifies that all properties defined in the + * PortableGroup IDL module are valid. + */ +class TAO_PortableGroup_Export TAO_PG_Default_Property_Validator +{ +public: + + /// Constructor. + TAO_PG_Default_Property_Validator (void); + + /// Validate the given properties. Throw an exception when the + /// first invalid property is encountered. The remaining properties + /// will not be validated. + void validate_property (const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /// Validate the given properties/criteria. All criteria + /// will be validated regardless of whether or not an invalid + /// property was encountered. + void validate_criteria (const PortableGroup::Properties & criteria) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)); + +private: + + /** + * @name Pre-initialize property Names. + * + * These properties are pre-initialized once to reduce property + * validation overhead. Note that the InitialNumberMembers and + * MinimumNumberMembers properties are not validated since there are + * no restrictions imposed by TAO's PortableGroup implementation + * regarding the number of such members. + */ + //@{ + PortableGroup::Name membership_; + PortableGroup::Name factories_; + //@} + +}; + +#include "ace/post.h" + +#endif /* TAO_PG_PROPERTY_VALIDATOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_GenericFactory.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_GenericFactory.cpp index 9119b3aaa34..50c8fb56849 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_GenericFactory.cpp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_GenericFactory.cpp @@ -18,7 +18,7 @@ TAO_PG_GenericFactory::TAO_PG_GenericFactory ( : poa_ (), object_group_manager_ (object_group_manager), property_manager_ (property_manager), - factory_map_ (TAO_PG_MAX_NUMBER_OF_OBJECT_GROUPS), + factory_map_ (TAO_PG_MAX_OBJECT_GROUPS), next_fcid_ (0), lock_ () { @@ -288,6 +288,9 @@ TAO_PG_GenericFactory::delete_object_i (TAO_PG_Factory_Set & factory_set, void TAO_PG_GenericFactory::poa (PortableServer::POA_ptr p) { + ACE_ASSERT (CORBA::is_nil (this->poa_.in ()) + && !CORBA::is_nil (p)); + this->poa_ = PortableServer::POA::_duplicate (p); } @@ -462,7 +465,7 @@ TAO_PG_GenericFactory::process_criteria ( PortableGroup::Value value; - name[0].id = CORBA::string_dup ("org.omg.pg.MembershipStyle"); + name[0].id = CORBA::string_dup ("org.omg.PortableGroup.MembershipStyle"); if (TAO_PG::get_property_value (name, props.in (), value) && (!(value >>= membership_style) @@ -474,7 +477,7 @@ TAO_PG_GenericFactory::process_criteria ( ACE_THROW (PortableGroup::InvalidProperty (name, value)); } - name[0].id = CORBA::string_dup ("org.omg.pg.Factories"); + name[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories"); if (TAO_PG::get_property_value (name, props.in (), value) && !(value >>= factory_infos)) { @@ -483,7 +486,8 @@ TAO_PG_GenericFactory::process_criteria ( ACE_THROW (PortableGroup::InvalidProperty (name, value)); } - name[0].id = CORBA::string_dup ("org.omg.pg.InitialNumberMembers"); + name[0].id = + CORBA::string_dup ("org.omg.PortableGroup.InitialNumberMembers"); if (TAO_PG::get_property_value (name, props.in (), value) && !(value >>= initial_number_members)) { @@ -492,7 +496,8 @@ TAO_PG_GenericFactory::process_criteria ( ACE_THROW (PortableGroup::InvalidProperty (name, value)); } - name[0].id = CORBA::string_dup ("org.omg.pg.MinimumNumberMembers"); + name[0].id = + CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers"); if (TAO_PG::get_property_value (name, props.in (), value) && !(value >>= minimum_number_members)) { diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_GenericFactory.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_GenericFactory.h index 09a45fe3dc4..5bc8e314ffb 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_GenericFactory.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_GenericFactory.h @@ -45,7 +45,7 @@ struct TAO_PG_ObjectGroup_Map_Entry; * of replicas. Those replicas will be created by this GenericFactory * if the "infrastructure-controlled" membership style is configured. */ -class TAO_PG_GenericFactory +class TAO_PortableGroup_Export TAO_PG_GenericFactory : public virtual PortableGroup::GenericFactory { public: diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Location_Equal_To.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Location_Equal_To.h index 065a4d2a788..319ddfa7874 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Location_Equal_To.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Location_Equal_To.h @@ -36,7 +36,7 @@ * This functor simply does a string comparison of each of the * elements in the given TAO_PortableGroup::Location name sequences. */ -class TAO_PG_Location_Equal_To +class TAO_PortableGroup_Export TAO_PG_Location_Equal_To { public: diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Location_Hash.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Location_Hash.h index 83d894bfb1a..122ce529519 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Location_Hash.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Location_Hash.h @@ -29,7 +29,7 @@ * * @brief Hash function object for generating a hash for a Location. */ -class TAO_PG_Location_Hash +class TAO_PortableGroup_Export TAO_PG_Location_Hash { public: diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Null_Property_Validator.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Null_Property_Validator.cpp new file mode 100644 index 00000000000..ef9eb998bb8 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Null_Property_Validator.cpp @@ -0,0 +1,27 @@ +#include "PG_Null_Property_Validator.h" + + +ACE_RCSID (PortableGroup, + PG_Null_Property_Validator, + "$Id$") + + +void +TAO_PG_Null_Property_Validator::validate_property ( + const PortableGroup::Properties & + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ +} + +void +TAO_PG_Null_Property_Validator::validate_criteria ( + const PortableGroup::Properties & + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Null_Property_Validator.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Null_Property_Validator.h new file mode 100644 index 00000000000..06973a03482 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Null_Property_Validator.h @@ -0,0 +1,61 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file PG_Null_Property_Validator.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + +#ifndef TAO_PG_NULL_PROPERTY_VALIDATOR_H +#define TAO_PG_NULL_PROPERTY_VALIDATOR_H + +#include "ace/pre.h" + +#include "orbsvcs/PortableGroupC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +/** + * @class TAO_PG_Null_Property_Validator + * + * @brief No-op property validator. + * + * This property validator performs no validation whatsoever. + */ +class TAO_PortableGroup_Export TAO_PG_Null_Property_Validator +{ +public: + + /// Validate the given properties. + /** + * This particular implementation performs no validation + * whatsoever. + */ + void validate_property (const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /// Validate the given criteria. + /** + * This particular implementation performs no validation + * whatsoever. + */ + void validate_criteria (const PortableGroup::Properties & criteria) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)); + +}; + +#include "ace/post.h" + +#endif /* TAO_PG_PROPERTY_VALIDATOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.cpp index 417ccc3a43d..ef535a4805e 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.cpp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.cpp @@ -13,11 +13,10 @@ ACE_RCSID (PortableGroup, "$Id$") -TAO_PG_ObjectGroupManager::TAO_PG_ObjectGroupManager ( - PortableServer::POA_ptr poa) - : poa_ (PortableServer::POA::_duplicate (poa)), - object_group_map_ (TAO_PG_MAX_NUMBER_OF_OBJECT_GROUPS), - location_map_ (TAO_PG_MAX_NUMBER_OF_LOCATIONS), +TAO_PG_ObjectGroupManager::TAO_PG_ObjectGroupManager (void) + : poa_ (), + object_group_map_ (TAO_PG_MAX_OBJECT_GROUPS), + location_map_ (TAO_PG_MAX_LOCATIONS), lock_ () { } @@ -398,6 +397,32 @@ TAO_PG_ObjectGroupManager::type_id ( return CORBA::string_dup (group_entry->type_id.in ()); } +PortableGroup::ObjectGroup_ptr +TAO_PG_ObjectGroupManager::object_group (const PortableServer::ObjectId & oid) +{ + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, + guard, + this->lock_, + PortableGroup::ObjectGroup::_nil ()); + + TAO_PG_ObjectGroup_Map_Entry * group_entry = 0; + if (this->object_group_map_.find (oid, group_entry) == 0) + return + PortableGroup::ObjectGroup::_duplicate (group_entry->object_group.in ()); + else + return PortableGroup::ObjectGroup::_nil (); +} + +void +TAO_PG_ObjectGroupManager::poa (PortableServer::POA_ptr p) +{ + ACE_ASSERT (CORBA::is_nil (this->poa_.in ()) + && !CORBA::is_nil (p)); + + this->poa_ = PortableServer::POA::_duplicate (p); +} + + PortableGroup::Properties * TAO_PG_ObjectGroupManager::get_properties ( PortableGroup::ObjectGroup_ptr object_group diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.h index f29ffa07927..9802a020b67 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.h @@ -37,13 +37,13 @@ * The ObjectGroupManager provides the interface necessary to * facilitate application-controlled object group membership. */ -class TAO_PG_ObjectGroupManager +class TAO_PortableGroup_Export TAO_PG_ObjectGroupManager : public virtual POA_PortableGroup::ObjectGroupManager { public: /// Constructor. - TAO_PG_ObjectGroupManager (PortableServer::POA_ptr poa); + TAO_PG_ObjectGroupManager (void); /// Destructor. ~TAO_PG_ObjectGroupManager (void); @@ -164,6 +164,18 @@ public: char * type_id (PortableGroup::ObjectGroup_ptr object_group ACE_ENV_ARG_DECL); + /// Return the object group associated with the given ObjectId. + /** + * @return Returns PortableGroup::ObjectGroup::_nil() if no object + * group corresponding to the given ObjectId exists. + */ + PortableGroup::ObjectGroup_ptr object_group ( + const PortableServer::ObjectId & oid); + + /// Set the POA to use when converting object group references to + /// ObjectIds. + void poa (PortableServer::POA_ptr p); + protected: /// Obtain the ObjectGroup hash map entry corresponding to the given diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp index 2d6b49c2ee2..51057169c59 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.cpp @@ -14,10 +14,12 @@ TAO_PG_PropertyManager::TAO_PG_PropertyManager ( : object_group_manager_ (object_group_manager), default_properties_ (), type_properties_ (), - lock_ () + lock_ (), + property_validator_ () { } + void TAO_PG_PropertyManager::set_default_properties ( const PortableGroup::Properties & props @@ -31,7 +33,7 @@ TAO_PG_PropertyManager::set_default_properties ( // be set as part of the default properties. PortableGroup::Name factories; factories.length (1); - factories[0].id = CORBA::string_dup ("org.omg.pg.Factories"); + factories[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories"); CORBA::ULong len = props.length (); for (CORBA::ULong i = 0; i < len; ++i) @@ -43,11 +45,16 @@ TAO_PG_PropertyManager::set_default_properties ( property.val)); } + this->property_validator_.validate_property (props + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); this->default_properties_ = props; } + PortableGroup::Properties * TAO_PG_PropertyManager::get_default_properties ( ACE_ENV_SINGLE_ARG_DECL) @@ -68,6 +75,7 @@ TAO_PG_PropertyManager::get_default_properties ( return props; } + void TAO_PG_PropertyManager::remove_default_properties ( const PortableGroup::Properties &props @@ -87,6 +95,7 @@ TAO_PG_PropertyManager::remove_default_properties ( ACE_CHECK; } + void TAO_PG_PropertyManager::set_type_properties ( const char * type_id, @@ -96,6 +105,10 @@ TAO_PG_PropertyManager::set_type_properties ( PortableGroup::InvalidProperty, PortableGroup::UnsupportedProperty)) { + this->property_validator_.validate_property (overrides + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + CORBA::ULong num_overrides = overrides.length (); if (num_overrides == 0) @@ -111,6 +124,7 @@ TAO_PG_PropertyManager::set_type_properties ( props = overrides; } + PortableGroup::Properties * TAO_PG_PropertyManager::get_type_properties ( const char * type_id @@ -154,6 +168,7 @@ TAO_PG_PropertyManager::get_type_properties ( return properties._retn (); } + void TAO_PG_PropertyManager::remove_type_properties ( const char * type_id, @@ -180,6 +195,7 @@ TAO_PG_PropertyManager::remove_type_properties ( ACE_CHECK; } + void TAO_PG_PropertyManager::set_properties_dynamically ( PortableGroup::ObjectGroup_ptr /* object_group */, @@ -196,7 +212,8 @@ TAO_PG_PropertyManager::set_properties_dynamically ( // allowed to be set as part of the default properties. PortableGroup::Name factories; factories.length (1); - factories[0].id = CORBA::string_dup ("org.omg.pg.InitialNumberMembers"); + factories[0].id = + CORBA::string_dup ("org.omg.PortableGroup.InitialNumberMembers"); CORBA::ULong len = props.length (); for (CORBA::ULong i = 0; i < len; ++i) @@ -207,11 +224,18 @@ TAO_PG_PropertyManager::set_properties_dynamically ( ACE_THROW (PortableGroup::InvalidProperty (property.nam, property.val)); } + + this->property_validator_.validate_property (overrides + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // @todo Set the properties in the object group map entry. #endif /* 0 */ ACE_THROW (CORBA::NO_IMPLEMENT ()); } + PortableGroup::Properties * TAO_PG_PropertyManager::get_properties ( PortableGroup::ObjectGroup_ptr object_group @@ -284,6 +308,7 @@ TAO_PG_PropertyManager::get_properties ( return properties._retn (); } + void TAO_PG_PropertyManager::remove_properties ( const PortableGroup::Properties & to_be_removed, diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.h index 1b9ffbe2e84..f5843005c97 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_PropertyManager.h @@ -22,9 +22,13 @@ #pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "PG_Default_Property_Validator.h" + +#include "orbsvcs/PortableGroupS.h" + #include "ace/Functor.h" #include "ace/Hash_Map_Manager_T.h" -#include "orbsvcs/PortableGroupS.h" + /// Forward declarations. @@ -43,7 +47,7 @@ class TAO_PG_ObjectGroupManager; * TAO_PG_ObjectGroup_Map_Entry structure. However, the * PropertyManager is still used to manage those properties. */ -class TAO_PG_PropertyManager +class TAO_PortableGroup_Export TAO_PG_PropertyManager : public virtual POA_PortableGroup::PropertyManager { public: @@ -173,6 +177,12 @@ private: /// the type-specific properties. TAO_SYNCH_MUTEX lock_; + /// The property validator. + /** + * @todo Strategize the validator, or use template policies. + */ + TAO_PG_Default_Property_Validator property_validator_; + }; #include "ace/post.h" diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Utils.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Utils.h index d5582f0a759..ab275a0af05 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Utils.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Utils.h @@ -32,7 +32,7 @@ namespace TAO_PG /** * @return true if successful, false otherwise */ - CORBA::Boolean get_property_value ( + TAO_PortableGroup_Export CORBA::Boolean get_property_value ( const PortableGroup::Name & property_name, const PortableGroup::Properties & properties, PortableGroup::Value & property_value); @@ -43,8 +43,9 @@ namespace TAO_PG * If no property is overridden, the override in question will be * appended to the "properties" list. */ - void override_properties (const PortableGroup::Properties & overrides, - PortableGroup::Properties &properties); + TAO_PortableGroup_Export void override_properties ( + const PortableGroup::Properties & overrides, + PortableGroup::Properties &properties); }; diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_conf.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_conf.h index 06f455fb556..b59757ace71 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_conf.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_conf.h @@ -24,18 +24,18 @@ #include "orbsvcs/PortableGroupC.h" -#ifndef TAO_PG_MAX_NUMBER_OF_OBJECT_GROUPS +#ifndef TAO_PG_MAX_OBJECT_GROUPS /// The maximum number of object groups to be managed by the /// ObjectGroupManager. This number is also equal to the number of /// factory sets managed by the GenericFactory. -const size_t TAO_PG_MAX_NUMBER_OF_OBJECT_GROUPS = 1024; +const size_t TAO_PG_MAX_OBJECT_GROUPS = 1024; #endif /* TAO_PG_MAX_NUMBER_OF_OBJECT_GROUPS */ -#ifndef TAO_PG_MAX_NUMBER_OF_LOCATIONS +#ifndef TAO_PG_MAX_LOCATIONS /// The maximum number of locations to be managed by the /// ObjectGroupManager. -const size_t TAO_PG_MAX_NUMBER_OF_LOCATIONS = 1024; -#endif /* TAO_PG_MAX_NUMBER_OF_OBJECT_GROUPS */ +const size_t TAO_PG_MAX_LOCATIONS = 1024; +#endif /* TAO_PG_MAX_LOCATIONS */ #ifndef TAO_PG_MEMBERSHIP_STYLE /// The default object group membership style. |