00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00043
00044
00045 const double MINIMAL_INTERVAL_BETWEEN_RESTARTS = 1.0;
00046 const double DEFAULT_INTERVAL_BETWEEN_RESTARTS = 300.0;
00047
00048
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
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
00083 CdbBdbWrapper::forceLoad();
00084
00085
00086 CdbBdbShared::forceLoad();
00087 }
00088
00089
00090 CdbBdbInit::~CdbBdbInit( )
00091 {}
00092
00093 AppResult
00094 CdbBdbInit::beginJob(AbsEvent* anEvent)
00095 {
00096
00097
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
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
00146
00147
00148
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
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
00179
00180
00181
00182
00183
00184
00185 if( 0 != strcmp( "*", _allowedOrigins.value( ))) {
00186
00187 CdbBdbTransaction readOnlyTransaction;
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
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
00234
00235
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 }