last run is stored after each run
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttleTrigger.cxx
CommitLineData
d477ad88 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/*
17 $Log$
7bfb2090 18 Revision 1.7 2006/07/20 09:54:40 jgrosseo
19 introducing status management: The processing per subdetector is divided into several steps,
20 after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
21 can keep track of the number of failures and skips further processing after a certain threshold is
22 exceeded. These thresholds can be configured in LDAP.
23
5164a766 24 Revision 1.6 2006/07/19 10:09:55 jgrosseo
25 new configuration, accesst to DAQ FES (Alberto)
26
57f50b3c 27 Revision 1.5 2006/07/10 13:01:41 jgrosseo
28 enhanced storing of last sucessfully processed run (alberto)
29
a7160fe9 30 Revision 1.4 2006/07/04 14:59:57 jgrosseo
31 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
32
45a493ce 33 Revision 1.3 2006/06/12 09:11:16 jgrosseo
34 coding conventions (Alberto)
35
58bc3020 36 Revision 1.2 2006/06/06 14:26:40 jgrosseo
37 o) removed files that were moved to STEER
38 o) shuttle updated to follow the new interface (Alberto)
39
b948db8d 40 Revision 1.1 2006/03/07 07:52:34 hristov
41 New version (B.Yordanov)
42
d477ad88 43 Revision 1.5 2005/11/21 09:03:48 byordano
44 one more print added
45
46 Revision 1.4 2005/11/20 10:12:37 byordano
47 comments added to AliShuttleTrigger
48
49 */
50
51
52//
53// This class is to deal with DAQ LogBook and DAQ "end of run" notification.
54// It has severeal two modes:
55// 1) syncrhnized - Collect(), CollectNew() and CollectAll methods
b948db8d 56// 2) asynchronized - Run() - starts listening for DAQ "end of run"
d477ad88 57// notification by DIM service.
58//
59
60#include "AliShuttleTrigger.h"
61
62#include <TSQLServer.h>
63#include <TSQLResult.h>
64#include <TSQLRow.h>
65#include <TObjArray.h>
66#include <TSystem.h>
67
68#include "AliLog.h"
b948db8d 69#include "AliCDBManager.h"
d477ad88 70#include "AliCDBStorage.h"
71#include "AliCDBEntry.h"
72
45a493ce 73#include "AliDCSValue.h"
d477ad88 74#include "AliShuttleConfig.h"
75#include "AliShuttle.h"
76#include "DATENotifier.h"
77
78ClassImp(TerminateSignalHandler)
b948db8d 79
58bc3020 80//______________________________________________________________________
81TerminateSignalHandler::TerminateSignalHandler(const TerminateSignalHandler& /*other*/):
82TSignalHandler()
83{
84// copy constructor (not implemented)
85
86}
87
88//______________________________________________________________________
89TerminateSignalHandler &TerminateSignalHandler::operator=(const TerminateSignalHandler& /*other*/)
90{
91// assignment operator (not implemented)
92
93return *this;
94}
95
b948db8d 96//______________________________________________________________________________________________
58bc3020 97Bool_t TerminateSignalHandler::Notify()
98{
99// Sentd terminate command to the Shuttle trigger
d477ad88 100
101 AliInfo("Terminate signal received ...");
102 fTrigger->Terminate();
103
104 return kTRUE;
105}
106
58bc3020 107//______________________________________________________________________________________________
108//______________________________________________________________________________________________
109
d477ad88 110ClassImp(AliShuttleTrigger)
b948db8d 111
112//______________________________________________________________________________________________
d477ad88 113AliShuttleTrigger::AliShuttleTrigger(const AliShuttleConfig* config,
b948db8d 114 UInt_t timeout, Int_t retries):
115 fConfig(config), fShuttle(NULL),
7bfb2090 116 fNotified(kFALSE), fTerminate(kFALSE), fLastRun(0), fCondition(&fMutex),
d477ad88 117 fQuitSignalHandler(this, kSigQuit),
118 fInterruptSignalHandler(this, kSigInterrupt)
119{
120 //
121 // config - pointer to the AliShuttleConfig object which represents
122 // the configuration
b948db8d 123 // mainStorage - pointer to AliCDBStorage for the undelying CDBStorage
124 // localStorage (local) CDB storage to be used if mainStorage is unavailable
d477ad88 125 //
126
b948db8d 127 fShuttle = new AliShuttle(config, timeout, retries);
d477ad88 128
129 gSystem->AddSignalHandler(&fQuitSignalHandler);
130 gSystem->AddSignalHandler(&fInterruptSignalHandler);
131}
132
58bc3020 133
134
135//______________________________________________________________________
136AliShuttleTrigger::AliShuttleTrigger(const AliShuttleTrigger& /*other*/):
137TObject()
138{
139// copy constructor (not implemented)
140
141}
142
143//______________________________________________________________________
144AliShuttleTrigger &AliShuttleTrigger::operator=(const AliShuttleTrigger& /*other*/)
145{
146// assignment operator (not implemented)
147
148return *this;
149}
150
151
152
153
154
b948db8d 155//______________________________________________________________________________________________
58bc3020 156AliShuttleTrigger::~AliShuttleTrigger()
157{
158// destructor
d477ad88 159
160 gSystem->RemoveSignalHandler(&fQuitSignalHandler);
161 gSystem->RemoveSignalHandler(&fInterruptSignalHandler);
162
163 delete fShuttle;
164}
165
b948db8d 166//______________________________________________________________________________________________
d477ad88 167Bool_t AliShuttleTrigger::Notify() {
168 //
169 // Trigger CollectNew() methods in asynchronized (listen) mode.
170 // Usually called automaticly by DATENotifier on "end of run"
171 // notification event.
172 //
173
174 fMutex.Lock();
175
176 fNotified = kTRUE;
177 fCondition.Signal();
178
179 fMutex.UnLock();
180
181 return kTRUE;
182}
183
b948db8d 184//______________________________________________________________________________________________
d477ad88 185void AliShuttleTrigger::Terminate() {
186 //
187 // Stop triggers listen mode and exist from Run()
188 // Usually called automaticly by TerminateSignalHandler.
189 //
190
191 fTerminate = kTRUE;
192 fCondition.Signal();
193}
194
b948db8d 195//______________________________________________________________________________________________
d477ad88 196void AliShuttleTrigger::Run() {
197 //
198 // AliShuttleTrigger main loop for asynchronized (listen) mode.
199 // It spawns DIM service listener and waits for DAQ "end of run"
200 // notification. Calls CollectNew() on notification.
201 //
202
203 fTerminate = kFALSE;
204
205 DATENotifier* notifier = new DATENotifier(this, "/DATE/LOGBOOK/UPDATE");
206
207 while (1) {
208
209 fMutex.Lock();
210
211 while (!(fNotified || fTerminate)) {
212 fCondition.Wait();
213 }
214
215 fNotified = kFALSE;
216
217 fMutex.UnLock();
218
219 if (fTerminate) {
220 AliInfo("Terminated.");
221 break;
222 }
223
224 CollectNew();
225 }
226
227 delete notifier;
228}
229
b948db8d 230//______________________________________________________________________________________________
d477ad88 231Bool_t AliShuttleTrigger::RetrieveDATEEntries(const char* whereClause,
a7160fe9 232 TObjArray& entries)
58bc3020 233{
234// Retrieve start time and end time for all runs in the DAQ logbook
235// that aren't processed yet
d477ad88 236
237 TString sqlQuery;
57f50b3c 238 sqlQuery = Form("select run, time_start, time_end from logbook %s order by run",
239 whereClause);
d477ad88 240
241 TSQLServer* aServer;
57f50b3c 242 TString logbookHost=Form("mysql://%s", fConfig->GetDAQlbHost());
243
b948db8d 244 aServer = TSQLServer::Connect(logbookHost,
57f50b3c 245 fConfig->GetDAQlbUser(),
246 fConfig->GetDAQlbPass());
d477ad88 247 if (!aServer) {
248 AliError("Can't establish connection to DAQ log book DB!");
249 return kFALSE;
250 }
57f50b3c 251
b948db8d 252 aServer->GetTables("REFSYSLOG");
d477ad88 253
254 TSQLResult* aResult;
255 aResult = aServer->Query(sqlQuery);
256 if (!aResult) {
257 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
258 delete aServer;
259 return kFALSE;
260 }
261
262 if (aResult->GetFieldCount() != 3) {
263 AliError("Invalid SQL result field number!");
264 delete aResult;
265 delete aServer;
266 return kFALSE;
267 }
268
d477ad88 269 TSQLRow* aRow;
270 while ((aRow = aResult->Next())) {
271 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
272 Int_t run = runString.Atoi();
273
274 TString startTimeString(aRow->GetField(1),
275 aRow->GetFieldLength(1));
276 Int_t startTime = startTimeString.Atoi();
277 if (!startTime) {
278 AliWarning(Form("Zero StartTime for run <%d>!", run));
279 AliWarning("Going to skip this run!");
280 continue;
281 }
282
283 TString endTimeString(aRow->GetField(2),
284 aRow->GetFieldLength(2));
285 Int_t endTime = endTimeString.Atoi();
286 if (!endTime) {
287 AliWarning(Form("Zero EndTime for run <%d>!", run));
288 AliWarning("Going to skip this run!");
289 continue;
290 }
291
292 if (startTime > endTime) {
293 AliWarning(Form("StartTime bigger than EndTime for run <%d>", run));
294 AliWarning("Going to skip this run!");
295 continue;
296 }
297
58bc3020 298 entries.AddLast(new AliShuttleTriggerDATEEntry(run, startTime, endTime));
d477ad88 299 delete aRow;
300 }
301
302 delete aResult;
57f50b3c 303
a7160fe9 304 aServer->Close();
d477ad88 305 delete aServer;
306
307 entries.SetOwner(1);
308
309 return kTRUE;
310}
311
b948db8d 312//______________________________________________________________________________________________
7bfb2090 313Bool_t AliShuttleTrigger::RetrieveConditionsData(const TObjArray& dateEntries, Bool_t updateLastRun)
58bc3020 314{
7bfb2090 315 // Retrieve conditions data for all runs that aren't processed yet
316
317 Bool_t hasError = kFALSE;
318
319 TIter iter(&dateEntries);
320 AliShuttleTriggerDATEEntry* anEntry;
321
322 while ((anEntry = (AliShuttleTriggerDATEEntry*) iter.Next()))
323 {
324 if (!fShuttle->Process(anEntry->GetRun(),
325 anEntry->GetStartTime(),
326 anEntry->GetEndTime()))
327 {
328 hasError = kTRUE;
329 }
330
331 if (!hasError && updateLastRun && fLastRun < anEntry->GetRun())
332 {
333 fLastRun = anEntry->GetRun();
334 WriteLastRun();
335 }
336 }
337
338 return hasError == kFALSE;
339}
340
341//______________________________________________________________________________________________
342Bool_t AliShuttleTrigger::ReadLastRun()
343{
344 // reads the last processed run from local CDB
345
346 AliCDBEntry* cdbEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalURI())
347 ->Get("/SHUTTLE/SYSTEM/LASTRUN", 0);
348
349 if (cdbEntry)
350 {
351 TObject* anObject = cdbEntry->GetObject();
352 if (anObject == NULL || anObject->IsA() != AliDCSValue::Class())
353 {
354 AliError("Invalid last run object stored to CDB!");
355 return kFALSE;
356 }
357 AliDCSValue* dcsValue = (AliDCSValue*) anObject;
358 fLastRun = dcsValue->GetInt();
359
360 delete cdbEntry;
361 }
362 else
363 {
364 AliFatal("No last run number stored. Please set first. Aborting");
365 return kFALSE;
366 }
367
368 AliInfo(Form("Last run number <%d>", fLastRun));
369
370 return kTRUE;
371}
d477ad88 372
7bfb2090 373//______________________________________________________________________________________________
374Bool_t AliShuttleTrigger::WriteLastRun()
375{
376 // writes the last succesfully processed run to local CDB
377
378 AliDCSValue lastRunObj(fLastRun, 0);
379 AliCDBMetaData metaData;
380 AliCDBId cdbID(AliCDBPath("SHUTTLE", "SYSTEM", "LASTRUN"), 0, 0);
381
382 UInt_t result = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalURI())
383 ->Put(&lastRunObj, cdbID, &metaData);
384
385 if (!result) {
386 AliError("Can't store last run to CDB!");
387 return kFALSE;
388 }
389
390 return kTRUE;
391}
392
393//______________________________________________________________________________________________
394Bool_t AliShuttleTrigger::SetNewLastRun(Int_t run)
395{
396 // sets a new run manually, use with caution!
397
398 fShuttle->Log("SHUTTLE", Form("Setting last run manually to %d", run));
399
400 fLastRun = run;
401 return WriteLastRun();
d477ad88 402}
403
b948db8d 404//______________________________________________________________________________________________
a7160fe9 405Bool_t AliShuttleTrigger::Collect(Int_t run)
58bc3020 406{
d477ad88 407 //
408 // Collects conditions date for the given run.
409 //
410
411 AliInfo(Form("Collecting conditions data for run <%d> ...", run));
412
413 TString whereClause("where run = ");
414 whereClause += run;
415
d477ad88 416 TObjArray dateEntries;
a7160fe9 417 if (!RetrieveDATEEntries(whereClause, dateEntries)) {
d477ad88 418 AliError("Can't retrieve entries from DAQ log book.");
419 return kFALSE;
420 }
421
422 if (!dateEntries.GetEntriesFast()) {
423 AliError(Form("There isn't entry for run <%d> in DAQ log book!",
424 run));
425 return kFALSE;
426 }
427
428 if (dateEntries.GetEntriesFast() > 1) {
429 AliError(Form("There is more than one entry for run <%d> in DAQ log book", run));
430 return kFALSE;
431 }
432
7bfb2090 433 if (!RetrieveConditionsData(dateEntries, kFALSE)) {
d477ad88 434 AliError("An error occured during conditions data retrieval!");
435 return kFALSE;
436 }
437
438 return kTRUE;
439}
440
b948db8d 441//______________________________________________________________________________________________
7bfb2090 442Bool_t AliShuttleTrigger::CollectNew()
58bc3020 443{
d477ad88 444 //
445 // Collects conditions data for all new run written to DAQ LogBook.
446 //
447
448 AliInfo("Collecting conditions data for new runs ...");
449
7bfb2090 450 if (!ReadLastRun())
451 {
452 AliError("Retrieving of last run failed");
453 return kFALSE;
454 }
d477ad88 455
456 TString whereClause("where run > ");
7bfb2090 457 whereClause += fLastRun;
d477ad88 458
d477ad88 459 TObjArray dateEntries;
a7160fe9 460 if (!RetrieveDATEEntries(whereClause, dateEntries)) {
d477ad88 461 AliError("Can't retrieve entries from DAQ log book.");
462 return kFALSE;
463 }
464
7bfb2090 465 if (!RetrieveConditionsData(dateEntries, kTRUE)) {
a7160fe9 466 AliError("Process of at least one run failed!");
467 // return kFALSE;
468 }
b948db8d 469
d477ad88 470 return kTRUE;
471}
472
b948db8d 473//______________________________________________________________________________________________
7bfb2090 474Bool_t AliShuttleTrigger::CollectAll()
58bc3020 475{
d477ad88 476 //
477 // Collects conditions data for all run written in DAQ LogBook.
478 //
479
7bfb2090 480 if (!ReadLastRun())
481 {
482 AliError("Retrieving of last run failed");
483 return kFALSE;
484 }
485
d477ad88 486 AliInfo("Collecting conditions data for all runs ...");
487
d477ad88 488 TObjArray dateEntries;
a7160fe9 489 if (!RetrieveDATEEntries("", dateEntries)) {
d477ad88 490 AliError("Can't retrieve entries from DAQ log book.");
491 return kFALSE;
492 }
493
7bfb2090 494 if (!RetrieveConditionsData(dateEntries, kTRUE)) {
d477ad88 495 AliError("An error occured during conditions data retrieval!");
496 return kFALSE;
497 }
498
499 return kTRUE;
500}
501