Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

CdbBdbInit.cc

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id: CdbBdbInit.cc,v 1.8 2005/10/25 19:36:51 gapon Exp $
00004 //
00005 // Description:
00006 //      Class CdbBdbInit.  Initialize Cdb.
00007 //
00008 // Environment:
00009 //      Software developed for the BaBar Detector at the SLAC B-Factory.
00010 //
00011 // Author List:
00012 //     David Brown, Igor Gaponenko 4/26/02
00013 //
00014 // Copyright Information:
00015 //      Copyright (C) 2002              Lawrence Berkeley Laboratory
00016 //
00017 //------------------------------------------------------------------------
00018 
00019 #include "BaBar/BaBar.hh"
00020 
00021 #include "BdbCondModules/CdbBdbInit.hh"
00022 
00023 #include "CdbBase/CdbEnvironment.hh"
00024 #include "CdbBase/CdbDatabase.hh"
00025 #include "CdbBase/CdbOrigin.hh"
00026 #include "CdbBdb/CdbBdbTransaction.hh"
00027 #include "CdbBdbWrapper/CdbBdbWrapper.hh"
00028 #include "CdbBdbShared/CdbBdbShared.hh"
00029 #include "BdbUtil/BdbDebug.hh"
00030 #include "BdbCond/BdbConditions.hh"
00031 #include "ErrLogger/ErrLog.hh"
00032 
00033 #include "BbrStdUtils/Tokenize.hh" 
00034 using namespace babar::String; 
00035 #include "BbrStdUtils/String.hh"
00036 #include <string>
00037 using std::endl;
00038 using std::string;
00039 
00040 namespace {
00041 
00042   // These are the minimally allowed and the default interval (in seconds) between
00043   // restarted transactions if the corresponding option is choosen. 
00044 
00045   const double MINIMAL_INTERVAL_BETWEEN_RESTARTS = 1.0;
00046   const double DEFAULT_INTERVAL_BETWEEN_RESTARTS = 300.0;
00047 
00048   // The default numver of Objectivity clienty cache pages
00049   const unsigned DEFAULT_OO_CACHE_MAX = 1500;
00050 };
00051 
00052 CdbBdbInit::CdbBdbInit( const char* const theName,
00053                         const char* const theDescription ) :
00054   AppModule( theName, theDescription ),
00055   _implementation( "Implementation", this ),
00056   _view( "View", this, "<local>::<recent>" ),
00057   _truncateTime( "TruncateTime", this, "+Infinity" ),
00058   _mainTransactionPolicy( "MainTransactionPolicy", this ),
00059   _mainTransactionRestartInterval( "MainTransactionRestartInterval", this, DEFAULT_INTERVAL_BETWEEN_RESTARTS ),
00060   _cacheMaxPages( "CacheMaxPages", this, DEFAULT_OO_CACHE_MAX ),
00061   _numEvents(0),
00062   _previousTimestamp(BdbTime::minusInfinity),
00063   _allowedOrigins("AllowedOrigins", this, "*" )
00064 {
00065   commands( )->append( &_implementation );
00066   commands( )->append( &_view );
00067   commands( )->append( &_truncateTime );
00068   commands( )->append( &_mainTransactionPolicy );
00069   commands( )->append( &_mainTransactionRestartInterval );
00070   commands( )->append( &_allowedOrigins );
00071 
00072   // create the commands: first entry becomes default
00073   _implementation.addItem( "<autodetection>", CdbBdbInit::AUTODETECTION );
00074   _implementation.addItem( "Wrapper",         CdbBdbInit::WRAPPER );
00075   _implementation.addItem( "Shared",          CdbBdbInit::SHARED  );
00076 
00077   _mainTransactionPolicy.addItem( "RestartedLongTransaction",  CdbBdbInit::RESTARTED_LONG_MAIN_TRANSACTION );
00078   _mainTransactionPolicy.addItem( "LongTransaction",           CdbBdbInit::LONG_MAIN_TRANSACTION );
00079   _mainTransactionPolicy.addItem( "ShortTransaction",          CdbBdbInit::SHORT_MAIN_TRANSACTION );
00080   _mainTransactionPolicy.addItem( "NoTransaction",             CdbBdbInit::NO_MAIN_TRANSACTION );
00081 
00082   // force linking of "Wrapper" implementation
00083   CdbBdbWrapper::forceLoad();
00084  
00085   // force linking of "Shared" implementation
00086   CdbBdbShared::forceLoad();
00087 }
00088 
00089 // Destructor
00090 CdbBdbInit::~CdbBdbInit( )
00091 {}
00092 
00093 AppResult
00094 CdbBdbInit::beginJob(AbsEvent* anEvent)
00095 {
00096     // We want to make sure this call was made before any Objy initialization took place.
00097     // Otherwise it just won't work.
00098 
00099     COUT1 << "Setting OO_CACH_MAX value to " << _cacheMaxPages.value( ) << " in CdbBdbInit::beginJob" << endl;
00100     BdbConditions::instance( )->setCacheMaxPages( _cacheMaxPages.value( ));
00101 
00102     _previousTimestamp = BdbTime::now( );
00103 
00104     if( CdbBdbInit::NO_MAIN_TRANSACTION != _mainTransactionPolicy.value( )) {
00105 
00106         COUT1 << "Starting main CDB trans in CdbBdbInit::beginJob" << endl;
00107 
00108         if( CdbBdbInit::RESTARTED_LONG_MAIN_TRANSACTION == _mainTransactionPolicy.value( )) {
00109 
00110             if( _mainTransactionRestartInterval.value( ) < MINIMAL_INTERVAL_BETWEEN_RESTARTS ) {
00111                 ErrMsg(fatal) << "An incorrect value of the \"MainTransactionRestartInterval\" = "
00112                               << _mainTransactionRestartInterval.value( ) << " detected by the module." << endl
00113                               << "    The parameter must be equal or greater than " << MINIMAL_INTERVAL_BETWEEN_RESTARTS << " seconds." << endl
00114                               << "    Note, that this is a fatal error. The application is considered misconfigured." << endmsg;
00115                 return AppResult::ERROR;
00116             }
00117             COUT1 << "The main CDB transaction will be restarted every " << _mainTransactionRestartInterval.value( ) << " seconds at CdbBdbInit::event()." << endl;
00118         }
00119         startTransaction( );
00120     }
00121 
00122   // Set requested defaults
00123   switch( _implementation.value( )){
00124 
00125   case SHARED:
00126 
00127     CdbEnvironment::setDefault("Bdb",
00128                                "Shared",
00129                                "<default>",
00130                                _view.value( ));
00131     break;
00132 
00133   case WRAPPER:
00134 
00135     CdbEnvironment::setDefault("Bdb",
00136                                "Wrapper",
00137                                "<default>",
00138                                _view.value( ));
00139     break;
00140 
00141   case AUTODETECTION:
00142 
00143   default:
00144 
00145     // Rely on the CDB API "autodetection" mechanizm for the CDB API implementation.
00146     // Explicitly set up a user specified view if the one specified by a user differs
00147     // from the current default. This extra check is done to avoid noisy diagnostics
00148     // produced by CDB API when modifying default.
00149 
00150     std::string t = CdbEnvironment::defaultTechnology    ( );
00151     std::string i = CdbEnvironment::defaultImplementation( t.c_str( ));
00152     std::string d = CdbEnvironment::defaultDatabase      ( t.c_str( ), i.c_str( ));
00153     std::string v = CdbEnvironment::defaultView          ( t.c_str( ), i.c_str( ), d.c_str( ));
00154 
00155     if( v != std::string( _view.value( ))) {
00156       CdbEnvironment::setDefault( t.c_str( ),
00157                                   i.c_str( ),
00158                                   d.c_str( ),
00159                                   _view.value( ));
00160     }
00161     break;
00162   }
00163   ErrMsg(warning) << "CdbBdbInit: Using CDB view \"" << _view.value( ) << "\"." << endmsg;
00164 
00165   // set truncate time if changed from the default (+Infinity)
00166   if( 0 != strcmp( "+Infinity", _truncateTime.value( ))) {
00167     BdbTime truncateTime( 0 );
00168     if( !BdbTime::parseTime( std::string( _truncateTime.value( )),
00169                              BdbTime::Local,
00170                              truncateTime )) {
00171       ErrMsg(error) << "CdbBdbInit: Failed to trunslate specified value of the truncate time \"" << _truncateTime.value( ) << "\"." << endmsg;
00172       return AppResult::ERROR;
00173     }
00174     CdbEnvironment::setTruncateTime( truncateTime );
00175     ErrMsg(warning) << "CdbBdbInit: Using truncate time \"" << _truncateTime.value( ) << "\" \"Local Timezone\"." << endmsg;
00176   }
00177 
00178   // Make sure we're running on the right type of CDB federation (so called "origin")
00179   // See the description of the syntax of the corresponding parameter at the header file
00180   // of the current class.
00181   //
00182   // NOTE: That the diagnostics message will only be reported if a non-default
00183   //       value of the parameter is set up.
00184 
00185   if( 0 != strcmp( "*", _allowedOrigins.value( ))) {
00186 
00187     CdbBdbTransaction readOnlyTransaction;  // the transaction will end at the end of the current block
00188 
00189     CdbDatabasePtr databasePtr;
00190     if( CdbStatus::Success != CdbDatabase::instance( databasePtr )) {
00191       ErrMsg(fatal) << "CdbBdbInit: Failed to obtain an API object for the default database." << endmsg;
00192       return AppResult::ERROR;
00193     }
00194     CdbOriginPtr originPtr = databasePtr->localOrigin( );
00195     if( originPtr.isNull( )) {
00196       ErrMsg(fatal) << "CdbBdbInit: Failed to obtain an API object for the current database origin." << endmsg;
00197       return AppResult::ERROR;
00198     }
00199 
00200     ErrMsg(warning) << "CdbBdbInit: Using user defined filter of CDB origins AllowedOrigins=\"" << _allowedOrigins.value( ) << "\"." << endmsg;
00201     ErrMsg(warning) << "CdbBdbInit: The current origin is \"" << originPtr->name( ) << "\"." << endmsg;
00202 
00203     // Now translate the filter and cross-check it with the current origin
00204 
00205     bool isAllowedOrigin = false;
00206     {
00207       Tokenize theTokenizer( _allowedOrigins.value( ));
00208       while( true ) {
00209         std::string origin = theTokenizer( "," );
00210         if( origin.empty( )) break;
00211 
00212         if( 0 == strcmp( originPtr->name( ), origin.c_str( ))) {
00213           isAllowedOrigin = true;
00214           break;
00215         }
00216       }
00217     }
00218     if( !isAllowedOrigin ) {
00219       ErrMsg(fatal) << "CdbBdbInit: The current CDB database you're attempting to use is not"
00220                     << " explicitly allowed by the \"AllowedOrigins\" parameter of CdbBdbInit module."
00221                     << " This parameter is here to prevent your application from running against a wrong CDB." << endmsg;
00222       return AppResult::ERROR;
00223     }
00224   }
00225   return AppResult::OK;
00226 }
00227 
00228 AppResult
00229 CdbBdbInit::event( AbsEvent* anEvent )
00230 {
00231     ++_numEvents;
00232 
00233 // Uncomment this debugging message if needed:
00234 //
00235 //  COUT1 << "CdbBdbInit::event() _numEvents = " << _numEvents << endl;
00236 
00237     switch( _mainTransactionPolicy.value( )) {
00238 
00239     case CdbBdbInit::RESTARTED_LONG_MAIN_TRANSACTION:
00240         {
00241             BdbTime currentTimestamp( BdbTime::now( ));
00242             d_ULong nSecondsElapsed = currentTimestamp.getGmtSec( ) - _previousTimestamp.getGmtSec( );
00243 
00244             if( nSecondsElapsed >= _mainTransactionRestartInterval.value( )) {
00245                 COUT1 << "Restarting main CDB trans in CdbBdbInit::event after " << _mainTransactionRestartInterval.value( ) << " seconds." << endl;
00246                 commitTransaction( );
00247                 startTransaction( );
00248                _previousTimestamp = currentTimestamp;
00249             }
00250         }
00251         break;
00252 
00253     case CdbBdbInit::SHORT_MAIN_TRANSACTION:
00254 
00255         if( 2 == _numEvents ) {
00256             COUT1 << "Commiting main CDB trans in CdbBdbInit::event at event " << _numEvents << endl;
00257             commitTransaction( );
00258         }
00259         break;
00260 
00261     case CdbBdbInit::LONG_MAIN_TRANSACTION:
00262 
00263         break;
00264 
00265     case CdbBdbInit::NO_MAIN_TRANSACTION:
00266 
00267         break;
00268     }
00269     return AppResult::OK;
00270 }
00271 
00272 AppResult
00273 CdbBdbInit::endJob( AbsEvent* anEvent )
00274 {
00275     if( CdbBdbInit::NO_MAIN_TRANSACTION != _mainTransactionPolicy.value( )) {
00276         COUT1 << "Commiting main CDB trans in CdbBdbInit::endJob" << endl;
00277         commitTransaction( );
00278     }
00279     return AppResult::OK;
00280 }
00281 
00282 void
00283 CdbBdbInit::startTransaction( )
00284 {
00285     BdbConditions* theApp = BdbConditions::instance( );
00286     if( BdbcNoOpen == theApp->mode( )) {
00287         theApp->activate( );
00288         theApp->startRead( );
00289     }
00290 }
00291 
00292 void
00293 CdbBdbInit::commitTransaction( )
00294 {
00295     BdbConditions* theApp = BdbConditions::instance( );
00296     if( BdbcNoOpen != theApp->mode( )) {
00297         theApp->activate( );
00298         theApp->commit( );
00299     }
00300 }

Generated on Mon Dec 5 18:21:59 2005 for CDB by doxygen1.3-rc3