From dc836d53bf637c01164117676a7c26e1146c3108 Mon Sep 17 00:00:00 2001 From: cvetan Date: Thu, 8 Oct 2009 12:19:48 +0000 Subject: [PATCH] Autorun functionality added (Matevz) --- MONITOR/AliDimIntNotifier.cxx | 15 +- MONITOR/AliDimIntNotifier.h | 7 +- MONITOR/AliOnlineReco.cxx | 314 +++++++++++++++++++++++----------- MONITOR/AliOnlineReco.h | 33 +++- MONITOR/alionlinemonitor.cxx | 25 ++- 5 files changed, 266 insertions(+), 128 deletions(-) diff --git a/MONITOR/AliDimIntNotifier.cxx b/MONITOR/AliDimIntNotifier.cxx index 99de6c2dd26..39ee16e68cb 100644 --- a/MONITOR/AliDimIntNotifier.cxx +++ b/MONITOR/AliDimIntNotifier.cxx @@ -8,7 +8,7 @@ **************************************************************************/ #include "AliDimIntNotifier.h" - +#include #include //______________________________________________________________________________ @@ -27,7 +27,6 @@ void AliDimIntNotifier::SetMainThreadId() AliDimIntNotifier::AliDimIntNotifier(const TString& service) : DimUpdatedInfo(service, -1), fNotifyLck(kTRUE), - fNotifyCnd(&fNotifyLck), fLastMessage(-1) { fReThreader.Connect("Timeout()", "AliDimIntNotifier", this, "DimMessage()"); @@ -54,11 +53,10 @@ void AliDimIntNotifier::infoHandler() if (TThread::SelfId() != fgMainThreadId) { StartTimer(); - fNotifyCnd.Wait(); } else { - Warning("infoHandler", "DIM message received from CINT thread."); + ::Warning("DIMinfoHandler", "DIM message received from CINT thread."); DimMessage(); } fNotifyLck.UnLock(); @@ -73,7 +71,6 @@ void AliDimIntNotifier::infoHandlerTest(Int_t fake) if (TThread::SelfId() != fgMainThreadId) { StartTimer(); - fNotifyCnd.Wait(); } else { @@ -89,13 +86,5 @@ void AliDimIntNotifier::DimMessage(Int_t) if (fLastMessage != -1) { Emit("DimMessage(Int_t)", fLastMessage); - printf("Notify %d\n", fLastMessage); - } - else - { - printf("NOTNotify %d\n", fLastMessage); } - fNotifyLck.Lock(); - fNotifyCnd.Signal(); - fNotifyLck.UnLock(); } diff --git a/MONITOR/AliDimIntNotifier.h b/MONITOR/AliDimIntNotifier.h index 8d2fc85fb9a..7e18b538a16 100644 --- a/MONITOR/AliDimIntNotifier.h +++ b/MONITOR/AliDimIntNotifier.h @@ -58,11 +58,10 @@ private: void StartTimer(); void StopTimer(); - TTimer fReThreader; - TMutex fNotifyLck; - TCondition fNotifyCnd; + TTimer fReThreader; + TMutex fNotifyLck; - Int_t fLastMessage; + Int_t fLastMessage; static Long_t fgMainThreadId; diff --git a/MONITOR/AliOnlineReco.cxx b/MONITOR/AliOnlineReco.cxx index 237f7364989..a256ca50738 100644 --- a/MONITOR/AliOnlineReco.cxx +++ b/MONITOR/AliOnlineReco.cxx @@ -2,7 +2,7 @@ // Author: Matevz Tadel 2007 /************************************************************************** - * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. * + * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *) * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for * * full copyright notice. * **************************************************************************/ @@ -13,6 +13,8 @@ #include "AliCDBManager.h" #include "AliGRPPreprocessor.h" +#include + #include #include @@ -28,8 +30,8 @@ ClassImp(AliOnlineReco) AliOnlineReco::AliOnlineReco() : TGMainFrame(gClient->GetRoot(), 400, 400), - fRunList(0), fStartButt(0), fStopButt(0), fXyzzButt(0), - + fRunList(0), fAutoRun(0), fStartButt(0), fStopButt(0), fExitButt(0), + fAutoRunTimer(0), fAutoRunScheduled(0), fAutoRunRunning(0), fTestMode(kFALSE) { // GUI components. @@ -38,6 +40,10 @@ AliOnlineReco::AliOnlineReco() : TGHorizontalFrame *hf = new TGHorizontalFrame(this, 1, 20); + fAutoRun = new TGCheckButton(hf, "AutoRun"); + hf->AddFrame(fAutoRun, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); + fAutoRun->Connect("Clicked()", "AliOnlineReco", this, "DoAutoRun()"); + fStartButt = new TGTextButton(hf, "Start"); hf->AddFrame(fStartButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); fStartButt->Connect("Clicked()", "AliOnlineReco", this, "DoStart()"); @@ -46,9 +52,9 @@ AliOnlineReco::AliOnlineReco() : hf->AddFrame(fStopButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); fStopButt->Connect("Clicked()", "AliOnlineReco", this, "DoStop()"); - fXyzzButt = new TGTextButton(hf, "Exit"); - hf->AddFrame(fXyzzButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); - fXyzzButt->Connect("Clicked()", "AliOnlineReco", this, "DoXyzz()"); + fExitButt = new TGTextButton(hf, "Exit"); + hf->AddFrame(fExitButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); + fExitButt->Connect("Clicked()", "AliOnlineReco", this, "DoExit()"); AddFrame(hf, new TGLayoutHints(kLHintsNormal | kLHintsExpandX)); @@ -69,15 +75,47 @@ AliOnlineReco::AliOnlineReco() : fSOR[i] = new AliDimIntNotifier(Form("/LOGBOOK/SUBSCRIBE/DAQ_SOR_PHYSICS_%d", i)); fEOR[i] = new AliDimIntNotifier(Form("/LOGBOOK/SUBSCRIBE/DAQ_EOR_PHYSICS_%d", i)); } + fSOR[i]->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "StartOfRun(Int_t)"); fEOR[i]->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "EndOfRun(Int_t)"); } + const Int_t autoRunDelay = 10; // should go to config + fAutoRunTimer = new TTimer(autoRunDelay * 1000l); + fAutoRunTimer->Connect("Timeout()", "AliOnlineReco", this, "AutoRunTimerTimeout()"); + // Signal handlers // ROOT's TSignalHAndler works not SIGCHLD ... AliChildProcTerminator::Instance()->Connect("ChildProcTerm(Int_t,Int_t)", "AliOnlineReco", this, "ChildProcTerm(Int_t,Int_t)"); } +AliOnlineReco::~AliOnlineReco() +{ + delete fAutoRunTimer; +} + +Int_t AliOnlineReco::GetLastRun() const +{ + return fRun2PidMap.empty() ? 0 : fRun2PidMap.rbegin()->first; +} + +Bool_t AliOnlineReco::GetAutoRunMode() const +{ + return fAutoRun->IsOn(); +} + +void AliOnlineReco::SetAutoRunMode(Bool_t ar) +{ + if (ar == fAutoRun->IsOn()) + return; + + fAutoRun->SetState(ar ? kButtonDown : kButtonUp, kTRUE); +} + +//------------------------------------------------------------------------------ +// Private methods +//------------------------------------------------------------------------------ + AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid) { for (mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); ++i) @@ -89,6 +127,142 @@ AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid) return fRun2PidMap.end(); } +void AliOnlineReco::StartAliEve(mIntInt_i& mi) +{ + Int_t run = mi->first; + + if (mi->second == 0) + { + pid_t pid = fork(); + if (pid == -1) + { + perror("DoStart -- Fork failed"); + return; + } + + if (pid) + { + mi->second = pid; + fRunList->RemoveEntry(run); + fRunList->AddEntrySort(TString::Format("%-20d -- RUNNING", run), run); + fRunList->Layout(); + } + else + { + int s; + if (fTestMode) + { + s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0); + } + else + { + Int_t procPID = gSystem->GetPid(); + TString logFile = Form("%s/reco/log/run%d_%d.log", + gSystem->Getenv("ONLINERECO_BASE_DIR"), + run, + (Int_t)procPID); + Info("DoStart","Reconstruction log will be written to %s",logFile.Data()); + gSystem->RedirectOutput(logFile.Data()); + + gSystem->cd(Form("%s/reco",gSystem->Getenv("ONLINERECO_BASE_DIR"))); + + TString gdcs; + if (RetrieveGRP(run,gdcs) <= 0 || gdcs.IsNull()) + gSystem->Exit(1); + + gSystem->Setenv("DATE_RUN_NUMBER", Form("%d", run)); + // Setting CDB +// AliCDBManager * man = AliCDBManager::Instance(); +// man->SetDefaultStorage("local:///local/cdb"); +// man->SetSpecificStorage("GRP/GRP/Data", +// Form("local://%s",gSystem->pwd())); +// man->SetSpecificStorage("GRP/CTP/Config", +// Form("local://%s",gSystem->pwd())); +// man->SetSpecificStorage("ACORDE/Align/Data", +// "local://$ALICE_ROOT/OCDB"); + + gSystem->mkdir(Form("run%d_%d", run, (Int_t)procPID)); + gSystem->cd(Form("run%d_%d", run, (Int_t)procPID)); + + const char *recMacroPath = "$ALICE_ROOT/test/cosmic/rec.C"; + + s = execlp("alieve", + "alieve", + "-q", + Form("%s(\"mem://@*:\")", gSystem->ExpandPathName(recMacroPath)), + (char*) 0); + } + + if (s == -1) + { + perror("execlp failed - this will not end well"); + gSystem->Exit(1); + } + } + } + else + { + Error("DoStart", "Process already running."); + } +} + +void AliOnlineReco::KillPid(Int_t pid) +{ + // Send terminate signal to process ... + + if (fTestMode) + { + kill(pid, SIGTERM); + } + else + { + // alieve will auto-destruct on SIGUSR1 + kill(pid, SIGUSR1); + } +} + +void AliOnlineReco::StartAutoRunTimer(Int_t run) +{ + // Start timer for given run. + // If an auto-started run is already active, this call is ignored. + // If timer is already active, it is restarted. + + if (fAutoRunRunning) + return; + + fAutoRunTimer->Reset(); + fAutoRunTimer->TurnOn(); + fAutoRunScheduled = run; + + Info("StartAutoRunTimer", "Scheduling run %d for auto-display.", run); +} + +void AliOnlineReco::StopAutoRunTimer() +{ + fAutoRunTimer->TurnOff(); + fAutoRunScheduled = 0; +} + +void AliOnlineReco::AutoRunTimerTimeout() +{ + Int_t run = fAutoRunScheduled; + + StopAutoRunTimer(); + + mIntInt_i i = fRun2PidMap.find(run); + + if (i == fRun2PidMap.end()) + { + Warning("AutoRunTimerTimeout", "run no longer active."); + return; + } + + Info("AutoRunTimerTimeout", "Starting display for run %d.", run); + + StartAliEve(i); + fAutoRunRunning = run; +} + //------------------------------------------------------------------------------ // Handlers of DIM signals. //------------------------------------------------------------------------------ @@ -101,6 +275,11 @@ void AliOnlineReco::StartOfRun(Int_t run) fRun2PidMap[run] = 0; fRunList->AddEntrySort(TString::Format("%d", run), run); fRunList->Layout(); + + if (fAutoRun->IsOn()) + { + StartAutoRunTimer(run); + } } else { @@ -119,18 +298,14 @@ void AliOnlineReco::EndOfRun(Int_t run) fRun2PidMap.erase(i); if (pid) { - // Send terminate signal to process ... - if (fTestMode) - { - kill(pid, SIGTERM); - } - else - { - // alieve will auto-destruct on SIGUSR1 - kill(pid, SIGUSR1); - } + KillPid(pid); } gClient->NeedRedraw(fRunList); + + if (fAutoRunRunning == run) + { + fAutoRunRunning = 0; + } } else { @@ -161,6 +336,16 @@ void AliOnlineReco::ChildProcTerm(Int_t pid, Int_t status) } fRunList->Layout(); i->second = 0; + + if (fAutoRunRunning == run && fAutoRun->IsOn()) + { + fAutoRunRunning = 0; + StartAutoRunTimer(run); + } + else + { + fAutoRunRunning = 0; + } } else { @@ -172,6 +357,16 @@ void AliOnlineReco::ChildProcTerm(Int_t pid, Int_t status) // Handlers of button signals. //------------------------------------------------------------------------------ +void AliOnlineReco::DoAutoRun() +{ + Bool_t autoRun = fAutoRun->IsOn(); + + if (autoRun) + fStartButt->SetEnabled(kFALSE); + else + fStartButt->SetEnabled(kTRUE); +} + void AliOnlineReco::DoStart() { Int_t run = fRunList->GetSelected(); @@ -183,80 +378,7 @@ void AliOnlineReco::DoStart() return; } - if (i->second == 0) - { - pid_t pid = fork(); - if (pid == -1) - { - perror("DoStart -- Fork failed"); - return; - } - - if (pid) - { - i->second = pid; - fRunList->RemoveEntry(run); - fRunList->AddEntrySort(TString::Format("%-20d -- RUNNING", run), run); - fRunList->Layout(); - } - else - { - int s; - if (fTestMode) - { - s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0); - } - else - { - Int_t procPID = gSystem->GetPid(); - TString logFile = Form("%s/reco/log/run%d_%d.log", - gSystem->Getenv("ONLINERECO_BASE_DIR"), - run, - (Int_t)procPID); - Info("DoStart","Reconstruction log will be written to %s",logFile.Data()); - gSystem->RedirectOutput(logFile.Data()); - - gSystem->cd(Form("%s/reco",gSystem->Getenv("ONLINERECO_BASE_DIR"))); - - TString gdcs; - if ((RetrieveGRP(run,gdcs) <= 0) || - gdcs.IsNull()) - gSystem->Exit(1); - - gSystem->Setenv("DATE_RUN_NUMBER",Form("%d",run)); - // Setting CDB -// AliCDBManager * man = AliCDBManager::Instance(); -// man->SetDefaultStorage("local:///local/cdb"); -// man->SetSpecificStorage("GRP/GRP/Data", -// Form("local://%s",gSystem->pwd())); -// man->SetSpecificStorage("GRP/CTP/Config", -// Form("local://%s",gSystem->pwd())); -// man->SetSpecificStorage("ACORDE/Align/Data", -// "local://$ALICE_ROOT/OCDB"); - - gSystem->mkdir(Form("run%d_%d",run,(Int_t)procPID)); - gSystem->cd(Form("run%d_%d",run,(Int_t)procPID)); - - const char *recMacroPath = "$ALICE_ROOT/test/cosmic/rec.C"; - - s = execlp("alieve", - "alieve", - "-q", - Form("%s(\"mem://@*:\")",gSystem->ExpandPathName(recMacroPath)), - (char*) 0); - } - - if (s == -1) - { - perror("execlp failed - this will not end well"); - gSystem->Exit(1); - } - } - } - else - { - Error("DoStart", "Process already running."); - } + StartAliEve(i); } void AliOnlineReco::DoStop() @@ -273,15 +395,7 @@ void AliOnlineReco::DoStop() Int_t pid = i->second; if (pid) { - if (fTestMode) - { - kill(pid, SIGTERM); - } - else - { - // alieve will auto-destruct on SIGUSR1 - kill(pid, SIGUSR1); - } + KillPid(pid); } else { @@ -289,7 +403,7 @@ void AliOnlineReco::DoStop() } } -void AliOnlineReco::DoXyzz() +void AliOnlineReco::DoExit() { gSystem->ExitLoop(); } diff --git a/MONITOR/AliOnlineReco.h b/MONITOR/AliOnlineReco.h index bcbb2e537e3..221bbc1f9d6 100644 --- a/MONITOR/AliOnlineReco.h +++ b/MONITOR/AliOnlineReco.h @@ -18,7 +18,10 @@ class AliDimIntNotifier; +class TTimer; + class TGTextButton; +class TGCheckButton; class TGListBox; //______________________________________________________________________________ @@ -30,11 +33,16 @@ class AliOnlineReco : public TGMainFrame { public: AliOnlineReco(); - virtual ~AliOnlineReco() {} + virtual ~AliOnlineReco(); AliDimIntNotifier* GetSOR(Int_t i) const { return fSOR[i]; } AliDimIntNotifier* GetEOR(Int_t i) const { return fEOR[i]; } + Int_t GetLastRun() const; + + Bool_t GetAutoRunMode() const; + void SetAutoRunMode(Bool_t ar); + void SetTestMode() { fTestMode = kTRUE; } //------------------------------------------------------------------------------ @@ -54,9 +62,10 @@ public: // Handlers of button signals. //------------------------------------------------------------------------------ + void DoAutoRun(); void DoStart(); void DoStop(); - void DoXyzz(); + void DoExit(); virtual void CloseWindow(); @@ -68,14 +77,20 @@ private: // GUI components. TGListBox *fRunList; + TGCheckButton *fAutoRun; TGTextButton *fStartButt; TGTextButton *fStopButt; - TGTextButton *fXyzzButt; + TGTextButton *fExitButt; - // DIM interface. Could do without ... + // DIM interface. Could do without members and just leak them ... AliDimIntNotifier *fSOR[5]; AliDimIntNotifier *fEOR[5]; + // AutoRun state and timer + TTimer *fAutoRunTimer; + Int_t fAutoRunScheduled; + Int_t fAutoRunRunning; + // Run-state, process mngmnt typedef std::map mIntInt_t; // value should be struct { pid, state, ... }; typedef mIntInt_t::iterator mIntInt_i; @@ -86,6 +101,16 @@ private: mIntInt_i FindMapEntryByPid(Int_t pid); + void StartAliEve(mIntInt_i& mi); + void KillPid(Int_t pid); + + void StartAutoRunTimer(Int_t run); + void StopAutoRunTimer(); + + // Things that should be private but have to be public for CINT. +public: + void AutoRunTimerTimeout(); + ClassDef(AliOnlineReco, 0); }; diff --git a/MONITOR/alionlinemonitor.cxx b/MONITOR/alionlinemonitor.cxx index 47277a317ee..22452bf6c25 100644 --- a/MONITOR/alionlinemonitor.cxx +++ b/MONITOR/alionlinemonitor.cxx @@ -20,6 +20,12 @@ int main(int argc, char **argv) AliOnlineReco *win = new AliOnlineReco; win->MapWindow(); + TString autoRun(gSystem->Getenv("ONLINERECO_AUTORUN")); + if (autoRun == "1" || autoRun.CompareTo("true", TString::kIgnoreCase) == 0) + { + win->SetAutoRunMode(kTRUE); + } + if (test) { win->SetTestMode(); @@ -31,10 +37,11 @@ int main(int argc, char **argv) printf("win = (AliOnlineReco*) 0x%lx\n", (unsigned long)win); } - else { - + else + { TString baseDir = gSystem->Getenv("ONLINERECO_BASE_DIR"); - if (baseDir.IsNull()) { + if (baseDir.IsNull()) + { printf("ERROR: ONLINERECO_BASE_DIR is not set. Exiting..."); return 0; } @@ -55,15 +62,19 @@ int main(int argc, char **argv) sqlQuery.Form("SELECT run FROM logbook WHERE DAQ_time_start > %u AND DAQ_time_end IS NULL AND partition REGEXP 'PHYSICS.*'", ts.GetSec()-86400); TSQLResult* result = server->Query(sqlQuery); - if (!result) { + if (!result) + { printf("ERROR: Can't execute query <%s>!", sqlQuery.Data()); return 0; } - if (result->GetRowCount() == 0) { + if (result->GetRowCount() == 0) + { printf("No active physics runs found"); } - else { - for (Int_t iRow = 0; iRow < result->GetRowCount(); iRow++) { + else + { + for (Int_t iRow = 0; iRow < result->GetRowCount(); iRow++) + { TSQLRow* row = result->Next(); TString runStr = row->GetField(0); if (runStr.IsDigit()) -- 2.39.3