2525#pragma warning(disable : 4503)
2626#endif
2727
28+ #include < orea/app/cleanupsingletons.hpp>
2829#include < orea/app/marketdatacsvloader.hpp>
2930#include < orea/app/marketdatainmemoryloader.hpp>
3031#include < orea/app/oreapp.hpp>
4041
4142#include < qle/version.hpp>
4243
44+
4345#include < ql/cashflows/floatingratecoupon.hpp>
4446#include < ql/time/calendars/all.hpp>
4547#include < ql/time/daycounters/all.hpp>
@@ -157,7 +159,7 @@ boost::shared_ptr<AggregationScenarioData> OREApp::getMarketCube(std::string cub
157159}
158160
159161std::vector<std::string> OREApp::getErrors () {
160- return structuredLogger_-> messages () ;
162+ return errorMessages_ ;
161163}
162164
163165Real OREApp::getRunTime () {
@@ -287,60 +289,57 @@ void OREApp::analytics() {
287289 LOG (" ORE analytics done" );
288290}
289291
290- OREApp::OREApp (boost::shared_ptr<Parameters> params, bool console,
291- const boost::filesystem::path& logRootPath)
292- : params_(params), inputs_(nullptr ) {
293292
294- if (console) {
293+ void OREApp::initFromParams () {
294+ if (console_) {
295295 ConsoleLog::instance ().switchOn ();
296296 }
297297
298- string outputPath = params_->get (" setup" , " outputPath" );
299- string logFile = outputPath + " /" + params_->get (" setup" , " logFile" );
300- Size logMask = 15 ;
298+ outputPath_ = params_->get (" setup" , " outputPath" );
299+ logFile_ = outputPath_ + " /" + params_->get (" setup" , " logFile" );
300+ logMask_ = 15 ;
301301 // Get log mask if available
302302 if (params_->has (" setup" , " logMask" )) {
303- logMask = static_cast <Size>(parseInteger (params_->get (" setup" , " logMask" )));
303+ logMask_ = static_cast <Size>(parseInteger (params_->get (" setup" , " logMask" )));
304304 }
305305
306- string progressLogFile, structuredLogFile;
307- Size progressLogRotationSize = 0 ;
308- bool progressLogToConsole = false ;
309- Size structuredLogRotationSize = 0 ;
306+ progressLogRotationSize_ = 0 ;
307+ progressLogToConsole_ = false ;
308+ structuredLogRotationSize_ = 0 ;
310309
311310 if (params_->hasGroup (" logging" )) {
312- string logFileOverride = params_->get (" logging" , " logFile" , false );
313- if (!logFileOverride .empty ()) {
314- logFile = outputPath + ' /' + logFileOverride ;
311+ string tmp = params_->get (" logging" , " logFile" , false );
312+ if (!tmp .empty ()) {
313+ logFile_ = outputPath_ + ' /' + tmp ;
315314 }
316- string logMaskOverride = params_->get (" logging" , " logMask" , false );
317- if (!logMaskOverride .empty ()) {
318- logMask = static_cast <Size>(parseInteger (logMaskOverride ));
315+ tmp = params_->get (" logging" , " logMask" , false );
316+ if (!tmp .empty ()) {
317+ logMask_ = static_cast <Size>(parseInteger (tmp ));
319318 }
320- progressLogFile = params_->get (" logging" , " progressLogFile" , false );
321- if (!progressLogFile .empty ()) {
322- progressLogFile = outputPath + ' /' + progressLogFile ;
319+ tmp = params_->get (" logging" , " progressLogFile" , false );
320+ if (!tmp .empty ()) {
321+ progressLogFile_ = outputPath_ + ' /' + tmp ;
323322 }
324- string tmp = params_->get (" logging" , " progressLogRotationSize" , false );
323+ tmp = params_->get (" logging" , " progressLogRotationSize" , false );
325324 if (!tmp.empty ()) {
326- progressLogRotationSize = static_cast <Size>(parseInteger (tmp));
325+ progressLogRotationSize_ = static_cast <Size>(parseInteger (tmp));
327326 }
328327 tmp = params_->get (" logging" , " progressLogToConsole" , false );
329328 if (!tmp.empty ()) {
330- progressLogToConsole = ore::data::parseBool (tmp);
329+ progressLogToConsole_ = ore::data::parseBool (tmp);
331330 }
332- structuredLogFile = params_->get (" logging" , " structuredLogFile" , false );
333- if (!structuredLogFile .empty ()) {
334- structuredLogFile = outputPath + ' /' + structuredLogFile ;
331+ tmp = params_->get (" logging" , " structuredLogFile" , false );
332+ if (!tmp .empty ()) {
333+ structuredLogFile_ = outputPath_ + ' /' + tmp ;
335334 }
336335 tmp = params_->get (" logging" , " structuredLogRotationSize" , false );
337336 if (!tmp.empty ()) {
338- structuredLogRotationSize = static_cast <Size>(parseInteger (tmp));
337+ structuredLogRotationSize_ = static_cast <Size>(parseInteger (tmp));
339338 }
340339 }
341340
342- setupLog (outputPath, logFile, logMask, logRootPath, progressLogFile, progressLogRotationSize, progressLogToConsole ,
343- structuredLogFile, structuredLogRotationSize );
341+ setupLog (outputPath_, logFile_, logMask_, logRootPath_, progressLogFile_, progressLogRotationSize_, progressLogToConsole_ ,
342+ structuredLogFile_, structuredLogRotationSize_ );
344343
345344 // Log the input parameters
346345 params_->log ();
@@ -353,20 +352,18 @@ OREApp::OREApp(boost::shared_ptr<Parameters> params, bool console,
353352 CONSOLE (" OK" );
354353
355354 Settings::instance ().evaluationDate () = inputs_->asof ();
356- }
357-
358- OREApp::OREApp (const boost::shared_ptr<InputParameters>& inputs, const std::string& logFile, Size logLevel,
359- bool console, const boost::filesystem::path& logRootPath)
360- : params_(nullptr ), inputs_(inputs) {
361-
355+ }
356+
357+ void OREApp::initFromInputs () {
362358 // Initialise Singletons
363359 Settings::instance ().evaluationDate () = inputs_->asof ();
364360 InstrumentConventions::instance ().setConventions (inputs_->conventions ());
365- if (console ) {
361+ if (console_ ) {
366362 ConsoleLog::instance ().switchOn ();
367363 }
368364
369- setupLog (inputs_->resultsPath ().string (), logFile, logLevel, logRootPath);
365+ outputPath_ = inputs_->resultsPath ().string ();
366+ setupLog (outputPath_, logFile_, logMask_, logRootPath_);
370367}
371368
372369OREApp::~OREApp () {
@@ -376,6 +373,24 @@ OREApp::~OREApp() {
376373
377374void OREApp::run () {
378375
376+ // only one thread at a time should call run
377+ static std::mutex _s_mutex;
378+ std::lock_guard<std::mutex> lock (_s_mutex);
379+
380+ // clean up after finishing the run
381+ CleanUpThreadLocalSingletons cleanupThreadLocalSingletons;
382+ CleanUpThreadGlobalSingletons cleanupThreadGloablSingletons;
383+ CleanUpLogSingleton cleanupLogSingleton (true , true );
384+
385+ if (inputs_ == nullptr )
386+ initFromParams ();
387+ else if (params_ == nullptr )
388+ initFromInputs ();
389+ else {
390+ ALOG (" both inputs are empty" );
391+ return ;
392+ }
393+
379394 runTimer_.start ();
380395
381396 try {
@@ -389,13 +404,35 @@ void OREApp::run() {
389404
390405 runTimer_.stop ();
391406
407+ // cache the error messages because we reset the loggers
408+ errorMessages_ = structuredLogger_->messages ();
409+
392410 CONSOLE (" run time: " << runTimer_.format (default_places, " %w" ) << " sec" );
393411 CONSOLE (" ORE done." );
394412 LOG (" ORE done." );
395413}
396414
397415void OREApp::run (const std::vector<std::string>& marketData,
398416 const std::vector<std::string>& fixingData) {
417+
418+ // only one thread at a time should call run
419+ static std::mutex _s_mutex;
420+ std::lock_guard<std::mutex> lock (_s_mutex);
421+
422+ // clean up after finishing the run
423+ CleanUpThreadLocalSingletons cleanupThreadLocalSingletons;
424+ CleanUpThreadGlobalSingletons cleanupThreadGloablSingletons;
425+ CleanUpLogSingleton cleanupLogSingleton (true , true );
426+
427+ if (inputs_ == nullptr )
428+ initFromParams ();
429+ else if (params_ == nullptr )
430+ initFromInputs ();
431+ else {
432+ ALOG (" both inputs are empty" );
433+ return ;
434+ }
435+
399436 runTimer_.start ();
400437
401438 try {
0 commit comments