coding conventions (Alberto)
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttleTrigger.cxx
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$
18  Revision 1.2  2006/06/06 14:26:40  jgrosseo
19  o) removed files that were moved to STEER
20  o) shuttle updated to follow the new interface (Alberto)
21
22  Revision 1.1  2006/03/07 07:52:34  hristov
23  New version (B.Yordanov)
24
25  Revision 1.5  2005/11/21 09:03:48  byordano
26  one more print added
27
28  Revision 1.4  2005/11/20 10:12:37  byordano
29  comments added to AliShuttleTrigger
30
31  */
32
33
34 // 
35 // This class is to deal with DAQ LogBook and DAQ "end of run" notification.
36 // It has severeal two modes:
37 //      1) syncrhnized - Collect(), CollectNew() and CollectAll methods
38 //      2) asynchronized - Run() - starts listening for DAQ "end of run"
39 //              notification by DIM service.
40 //
41
42 #include "AliShuttleTrigger.h"
43
44 #include <TSQLServer.h>
45 #include <TSQLResult.h>
46 #include <TSQLRow.h>
47 #include <TObjArray.h>
48 #include <TSystem.h>
49
50 #include "AliLog.h"
51 #include "AliCDBManager.h"
52 #include "AliCDBStorage.h"
53 #include "AliCDBEntry.h"
54
55 #include "AliSimpleValue.h"
56 #include "AliShuttleConfig.h"
57 #include "AliShuttle.h"
58 #include "DATENotifier.h"
59
60 ClassImp(TerminateSignalHandler)
61
62 //______________________________________________________________________
63 TerminateSignalHandler::TerminateSignalHandler(const TerminateSignalHandler& /*other*/):
64 TSignalHandler()
65 {
66 // copy constructor (not implemented)
67
68 }
69
70 //______________________________________________________________________
71 TerminateSignalHandler &TerminateSignalHandler::operator=(const TerminateSignalHandler& /*other*/)
72 {
73 // assignment operator (not implemented)
74
75 return *this;
76 }
77
78 //______________________________________________________________________________________________
79 Bool_t TerminateSignalHandler::Notify() 
80 {
81 // Sentd terminate command to the Shuttle trigger
82
83         AliInfo("Terminate signal received ...");
84         fTrigger->Terminate();
85
86         return kTRUE;
87 }
88
89 //______________________________________________________________________________________________
90 //______________________________________________________________________________________________
91
92 ClassImp(AliShuttleTrigger)
93
94 //______________________________________________________________________________________________
95 AliShuttleTrigger::AliShuttleTrigger(const AliShuttleConfig* config,
96                 UInt_t timeout, Int_t retries):
97         fConfig(config), fShuttle(NULL),
98         fNotified(kFALSE), fTerminate(kFALSE), fCondition(&fMutex),
99         fQuitSignalHandler(this, kSigQuit), 
100         fInterruptSignalHandler(this, kSigInterrupt)
101 {
102         //
103         // config - pointer to the AliShuttleConfig object which represents
104         // the configuration
105         // mainStorage - pointer to AliCDBStorage for the undelying CDBStorage
106         // localStorage (local) CDB storage to be used if mainStorage is unavailable
107         //
108
109         fShuttle = new AliShuttle(config, timeout, retries);
110
111         gSystem->AddSignalHandler(&fQuitSignalHandler);
112         gSystem->AddSignalHandler(&fInterruptSignalHandler);
113 }
114
115
116
117 //______________________________________________________________________
118 AliShuttleTrigger::AliShuttleTrigger(const AliShuttleTrigger& /*other*/):
119 TObject()
120 {
121 // copy constructor (not implemented)
122
123 }
124
125 //______________________________________________________________________
126 AliShuttleTrigger &AliShuttleTrigger::operator=(const AliShuttleTrigger& /*other*/)
127 {
128 // assignment operator (not implemented)
129
130 return *this;
131 }
132
133
134
135
136
137 //______________________________________________________________________________________________
138 AliShuttleTrigger::~AliShuttleTrigger() 
139 {
140 // destructor
141
142         gSystem->RemoveSignalHandler(&fQuitSignalHandler);
143         gSystem->RemoveSignalHandler(&fInterruptSignalHandler);
144
145         delete fShuttle;
146 }
147
148 //______________________________________________________________________________________________
149 Bool_t AliShuttleTrigger::Notify() {
150         //
151         // Trigger CollectNew() methods in asynchronized (listen) mode.
152         // Usually called automaticly by DATENotifier on "end of run" 
153         // notification event.
154         //
155
156         fMutex.Lock();
157
158         fNotified = kTRUE;
159         fCondition.Signal();
160
161         fMutex.UnLock();
162
163         return kTRUE;
164 }
165
166 //______________________________________________________________________________________________
167 void AliShuttleTrigger::Terminate() {
168         //
169         // Stop triggers listen mode and exist from Run()
170         // Usually called automaticly by TerminateSignalHandler.
171         //
172
173         fTerminate = kTRUE;
174         fCondition.Signal();
175 }
176
177 //______________________________________________________________________________________________
178 void AliShuttleTrigger::Run() {
179         //
180         // AliShuttleTrigger main loop for asynchronized (listen) mode.
181         // It spawns DIM service listener and waits for DAQ "end of run"
182         // notification. Calls CollectNew() on notification.
183         //
184
185         fTerminate = kFALSE;
186
187         DATENotifier* notifier = new DATENotifier(this, "/DATE/LOGBOOK/UPDATE");
188
189         while (1) {
190         
191                 fMutex.Lock();
192
193                 while (!(fNotified || fTerminate)) {
194                         fCondition.Wait();
195                 }
196
197                 fNotified = kFALSE;
198                 
199                 fMutex.UnLock();
200
201                 if (fTerminate) {
202                         AliInfo("Terminated.");
203                         break;          
204                 }
205         
206                 CollectNew();
207         }
208
209         delete notifier;
210 }
211
212 //______________________________________________________________________________________________
213 Bool_t AliShuttleTrigger::RetrieveDATEEntries(const char* whereClause,
214                 TObjArray& entries, Int_t& lastRun) 
215 {
216 // Retrieve start time and end time for all runs in the DAQ logbook
217 // that aren't processed yet
218
219         TString sqlQuery;
220         sqlQuery += "select run, time_start, time_end from logbook ";
221         sqlQuery += whereClause;
222         sqlQuery += " order by run";
223
224         TSQLServer* aServer;
225         TString logbookHost="mysql://";
226         logbookHost+=fConfig->GetDAQLogBookHost();
227         
228         aServer = TSQLServer::Connect(logbookHost,
229                         fConfig->GetDAQLogBookUser(),
230                         fConfig->GetDAQLogBookPassword());
231         if (!aServer) {
232                 AliError("Can't establish connection to DAQ log book DB!");
233                 return kFALSE;
234         }
235         
236         aServer->GetTables("REFSYSLOG");
237
238         TSQLResult* aResult;
239         aResult = aServer->Query(sqlQuery);
240         if (!aResult) {
241                 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
242                 delete aServer;
243                 return kFALSE;
244         }
245
246         if (aResult->GetFieldCount() != 3) {
247                 AliError("Invalid SQL result field number!");
248                 delete aResult;
249                 delete aServer;
250                 return kFALSE;
251         }
252
253         lastRun = 0;
254
255         TSQLRow* aRow;
256         while ((aRow = aResult->Next())) {
257                 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
258                 Int_t run = runString.Atoi();
259
260                 TString startTimeString(aRow->GetField(1),
261                                 aRow->GetFieldLength(1));
262                 Int_t startTime = startTimeString.Atoi();
263                 if (!startTime) {
264                         AliWarning(Form("Zero StartTime for run <%d>!", run));
265                         AliWarning("Going to skip this run!");
266                         continue;
267                 }
268
269                 TString endTimeString(aRow->GetField(2),
270                                 aRow->GetFieldLength(2));
271                 Int_t endTime = endTimeString.Atoi();
272                 if (!endTime) {
273                         AliWarning(Form("Zero EndTime for run <%d>!", run));
274                         AliWarning("Going to skip this run!");
275                         continue;
276                 }
277
278                 if (startTime > endTime) {
279                         AliWarning(Form("StartTime bigger than EndTime for run <%d>", run));
280                         AliWarning("Going to skip this run!");
281                         continue;
282                 }
283
284                 entries.AddLast(new AliShuttleTriggerDATEEntry(run, startTime, endTime));
285                 if (lastRun < run) {
286                         lastRun = run;
287                 }
288                 delete aRow;
289         }
290
291         delete aResult;
292         
293         aServer->Shutdown();
294         delete aServer;
295
296         entries.SetOwner(1);
297
298         return kTRUE;
299 }
300
301 //______________________________________________________________________________________________
302 Bool_t AliShuttleTrigger::RetrieveConditionsData(const TObjArray& dateEntries) 
303 {
304 // Retrieve conditions data for all runs that aren't processed yet
305
306         Bool_t hasError = kFALSE;
307
308         TIter iter(&dateEntries);
309         AliShuttleTriggerDATEEntry* anEntry;
310         while ((anEntry = (AliShuttleTriggerDATEEntry*) iter.Next())) {
311                 if(!fShuttle->Process(anEntry->GetRun(),
312                                 anEntry->GetStartTime(),
313                                 anEntry->GetEndTime())) {
314                         hasError = kTRUE;
315                 }
316         }
317
318         return !hasError;
319 }
320
321 //______________________________________________________________________________________________
322 Bool_t AliShuttleTrigger::Collect(Int_t run) 
323 {
324         //
325         // Collects conditions date for the given run.
326         //
327
328         AliInfo(Form("Collecting conditions data for run <%d> ...", run));
329
330         TString whereClause("where run = ");
331         whereClause += run;
332
333         Int_t lastRun;
334         TObjArray dateEntries;
335         if (!RetrieveDATEEntries(whereClause, dateEntries, lastRun)) {
336                 AliError("Can't retrieve entries from DAQ log book.");
337                 return kFALSE;
338         }
339
340         if (!dateEntries.GetEntriesFast()) {
341                 AliError(Form("There isn't entry for run <%d> in DAQ log book!",
342                         run));
343                 return kFALSE;
344         }
345
346         if (dateEntries.GetEntriesFast() > 1) {
347                 AliError(Form("There is more than one entry for run <%d> in DAQ log book", run));
348                 return kFALSE;
349         }
350
351         if (!RetrieveConditionsData(dateEntries)) {
352                 AliError("An error occured during conditions data retrieval!");
353                 return kFALSE;
354         }
355
356         return kTRUE;
357 }
358
359 //______________________________________________________________________________________________
360 Bool_t AliShuttleTrigger::CollectNew() 
361 {
362         //
363         // Collects conditions data for all new run written to DAQ LogBook.
364         //
365
366         AliInfo("Collecting conditions data for new runs ...");
367
368         Int_t lastRun;
369
370         AliCDBEntry* cdbEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalURI())
371                                 ->Get("/SHUTTLE/SYSTEM/LASTRUN", 0);
372         if (cdbEntry) {
373                 TObject* anObject = cdbEntry->GetObject();
374                 if (anObject == NULL ||
375                         anObject->IsA() != AliSimpleValue::Class()) {
376                         AliError("Invalid last run object stored to CDB!");
377                         return kFALSE;
378                 }
379                 AliSimpleValue* simpleValue = (AliSimpleValue*) anObject;
380                 lastRun = simpleValue->GetInt();
381                 delete cdbEntry;
382         } else {
383                 AliWarning("There isn't last run stored! Starting from run 21200");
384                 lastRun = 21200;
385         }
386
387         AliInfo(Form("Last run number <%d>", lastRun));
388
389         TString whereClause("where run > ");
390         whereClause += lastRun;
391
392         Int_t newLastRun;
393         TObjArray dateEntries;
394         if (!RetrieveDATEEntries(whereClause, dateEntries, newLastRun)) {
395                 AliError("Can't retrieve entries from DAQ log book.");
396                 return kFALSE;
397         }
398
399         if (newLastRun > lastRun) {
400                 AliSimpleValue lastRunObj(newLastRun);
401                 AliCDBMetaData metaData;
402                 AliCDBId cdbID(AliCDBPath("SHUTTLE", "SYSTEM", "LASTRUN"), 0, 0);
403
404                 UInt_t result = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalURI())
405                                 ->Put(&lastRunObj, cdbID, &metaData);
406
407                 if (!result) {
408                         AliError("Can't store last run to CDB!");
409                         return kFALSE;
410                 }
411         }
412
413         if (!RetrieveConditionsData(dateEntries)) {
414                 AliError("An error occured during conditions data retrieval!");
415                 return kFALSE;
416         }
417
418         return kTRUE;
419 }
420
421 //______________________________________________________________________________________________
422 Bool_t AliShuttleTrigger::CollectAll() 
423 {
424         //
425         // Collects conditions data for all run written in DAQ LogBook.
426         //
427
428         AliInfo("Collecting conditions data for all runs ...");
429
430         Int_t lastRun;
431         TObjArray dateEntries;
432         if (!RetrieveDATEEntries("", dateEntries, lastRun)) {
433                 AliError("Can't retrieve entries from DAQ log book.");
434                 return kFALSE;
435         }
436
437         if (!RetrieveConditionsData(dateEntries)) {
438                 AliError("An error occured during conditions data retrieval!");
439                 return kFALSE;
440         }
441
442         return kTRUE;
443 }
444