ec2cc255272dca854d4aad680c36b32755e856dc
[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.5  2005/11/21 09:03:48  byordano
19  one more print added
20
21  Revision 1.4  2005/11/20 10:12:37  byordano
22  comments added to AliShuttleTrigger
23
24  */
25
26
27 // 
28 // This class is to deal with DAQ LogBook and DAQ "end of run" notification.
29 // It has severeal two modes:
30 //      1) syncrhnized - Collect(), CollectNew() and CollectAll methods
31 //      2) asynchronized - Run() - starts listening for DAQ "end of run" 
32 //              notification by DIM service.
33 //
34
35 #include "AliShuttleTrigger.h"
36
37 #include <TSQLServer.h>
38 #include <TSQLResult.h>
39 #include <TSQLRow.h>
40 #include <TObjArray.h>
41 #include <TSystem.h>
42
43 #include "AliLog.h"
44 #include "AliCDBStorage.h"
45 #include "AliCDBEntry.h"
46
47 #include "AliSimpleValue.h"
48 #include "AliShuttleConfig.h"
49 #include "AliShuttle.h"
50 #include "DATENotifier.h"
51
52 ClassImp(TerminateSignalHandler)
53 Bool_t TerminateSignalHandler::Notify() {
54
55         AliInfo("Terminate signal received ...");
56         fTrigger->Terminate();
57
58         return kTRUE;
59 }
60
61 ClassImp(AliShuttleTrigger)
62 AliShuttleTrigger::AliShuttleTrigger(const AliShuttleConfig* config,
63                 AliCDBStorage* storage, UInt_t timeout, Int_t retries):
64         fConfig(config), fStorage(storage), fShuttle(NULL),
65         fNotified(kFALSE), fTerminate(kFALSE), fCondition(&fMutex),
66         fQuitSignalHandler(this, kSigQuit), 
67         fInterruptSignalHandler(this, kSigInterrupt)
68 {
69         //
70         // config - pointer to the AliShuttleConfig object which represents
71         // the configuration
72         // storage - pointer to AliCDBStorage for the undelying CDBStorage
73         //
74
75         fShuttle = new AliShuttle(config, storage, timeout, retries);
76
77         gSystem->AddSignalHandler(&fQuitSignalHandler);
78         gSystem->AddSignalHandler(&fInterruptSignalHandler);
79 }
80
81 AliShuttleTrigger::~AliShuttleTrigger() {
82
83         gSystem->RemoveSignalHandler(&fQuitSignalHandler);
84         gSystem->RemoveSignalHandler(&fInterruptSignalHandler);
85
86         delete fShuttle;
87 }
88
89 Bool_t AliShuttleTrigger::Notify() {
90         //
91         // Trigger CollectNew() methods in asynchronized (listen) mode.
92         // Usually called automaticly by DATENotifier on "end of run" 
93         // notification event.
94         //
95
96         fMutex.Lock();
97
98         fNotified = kTRUE;
99         fCondition.Signal();
100
101         fMutex.UnLock();
102
103         return kTRUE;
104 }
105
106 void AliShuttleTrigger::Terminate() {
107         //
108         // Stop triggers listen mode and exist from Run()
109         // Usually called automaticly by TerminateSignalHandler.
110         //
111
112         fTerminate = kTRUE;
113         fCondition.Signal();
114 }
115
116 void AliShuttleTrigger::Run() {
117         //
118         // AliShuttleTrigger main loop for asynchronized (listen) mode.
119         // It spawns DIM service listener and waits for DAQ "end of run"
120         // notification. Calls CollectNew() on notification.
121         //
122
123         fTerminate = kFALSE;
124
125         DATENotifier* notifier = new DATENotifier(this, "/DATE/LOGBOOK/UPDATE");
126
127         while (1) {
128         
129                 fMutex.Lock();
130
131                 while (!(fNotified || fTerminate)) {
132                         fCondition.Wait();
133                 }
134
135                 fNotified = kFALSE;
136                 
137                 fMutex.UnLock();
138
139                 if (fTerminate) {
140                         AliInfo("Terminated.");
141                         break;          
142                 }
143         
144                 CollectNew();
145         }
146
147         delete notifier;
148 }
149
150 Bool_t AliShuttleTrigger::RetrieveDATEEntries(const char* whereClause,
151                 TObjArray& entries, Int_t& lastRun) {
152
153         TString sqlQuery;
154         sqlQuery += "select run, time_start, time_end from logbook ";
155         sqlQuery += whereClause;
156         sqlQuery += " order by run";
157
158         TSQLServer* aServer;
159         aServer = TSQLServer::Connect(fConfig->GetLogBookURI(),
160                         fConfig->GetLogBookUser(),
161                         fConfig->GetLogBookPassword());
162         if (!aServer) {
163                 AliError("Can't establish connection to DAQ log book DB!");
164                 return kFALSE;
165         }
166
167         TSQLResult* aResult;
168         aResult = aServer->Query(sqlQuery);
169         if (!aResult) {
170                 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
171                 delete aServer;
172                 return kFALSE;
173         }
174
175         if (aResult->GetFieldCount() != 3) {
176                 AliError("Invalid SQL result field number!");
177                 delete aResult;
178                 delete aServer;
179                 return kFALSE;
180         }
181
182         lastRun = 0;
183
184         TSQLRow* aRow;
185         while ((aRow = aResult->Next())) {
186                 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
187                 Int_t run = runString.Atoi();
188
189                 TString startTimeString(aRow->GetField(1),
190                                 aRow->GetFieldLength(1));
191                 Int_t startTime = startTimeString.Atoi();
192                 if (!startTime) {
193                         AliWarning(Form("Zero StartTime for run <%d>!", run));
194                         AliWarning("Going to skip this run!");
195                         continue;
196                 }
197
198                 TString endTimeString(aRow->GetField(2),
199                                 aRow->GetFieldLength(2));
200                 Int_t endTime = endTimeString.Atoi();
201                 if (!endTime) {
202                         AliWarning(Form("Zero EndTime for run <%d>!", run));
203                         AliWarning("Going to skip this run!");
204                         continue;
205                 }
206
207                 if (startTime > endTime) {
208                         AliWarning(Form("StartTime bigger than EndTime for run <%d>", run));
209                         AliWarning("Going to skip this run!");
210                         continue;
211                 }
212
213                 entries.AddLast(new DATEEntry(run, startTime, endTime));
214                 if (lastRun < run) {
215                         lastRun = run;
216                 }
217                 delete aRow;
218         }
219
220         delete aResult;
221         
222         aServer->Shutdown();
223         delete aServer;
224
225         entries.SetOwner(1);
226
227         return kTRUE;
228 }
229
230 Bool_t AliShuttleTrigger::RetrieveConditionsData(const TObjArray& dateEntries) {
231
232         Bool_t hasError = kFALSE;
233
234         TIter iter(&dateEntries);
235         DATEEntry* anEntry;
236         while ((anEntry = (DATEEntry*) iter.Next())) {
237                 if(!fShuttle->Process(anEntry->GetRun(), 
238                                 anEntry->GetStartTime(),
239                                 anEntry->GetEndTime())) {
240                         hasError = kTRUE;
241                 }       
242         }
243
244         return !hasError;
245 }
246
247 Bool_t AliShuttleTrigger::Collect(Int_t run) {
248         //
249         // Collects conditions date for the given run.
250         //
251
252         AliInfo(Form("Collecting conditions data for run <%d> ...", run));
253
254         TString whereClause("where run = ");
255         whereClause += run;
256
257         Int_t lastRun;
258         TObjArray dateEntries;
259         if (!RetrieveDATEEntries(whereClause, dateEntries, lastRun)) {
260                 AliError("Can't retrieve entries from DAQ log book.");
261                 return kFALSE;
262         }
263
264         if (!dateEntries.GetEntriesFast()) {
265                 AliError(Form("There isn't entry for run <%d> in DAQ log book!",
266                         run));
267                 return kFALSE;
268         }
269
270         if (dateEntries.GetEntriesFast() > 1) {
271                 AliError(Form("There is more than one entry for run <%d> in DAQ log book", run));
272                 return kFALSE;
273         }
274
275         if (!RetrieveConditionsData(dateEntries)) {
276                 AliError("An error occured during conditions data retrieval!");
277                 return kFALSE;
278         }
279
280         return kTRUE;
281 }
282
283 Bool_t AliShuttleTrigger::CollectNew() {
284         //
285         // Collects conditions data for all new run written to DAQ LogBook.
286         //
287
288         AliInfo("Collecting conditions data for new runs ...");
289
290         Int_t lastRun;
291
292         AliCDBEntry* cdbEntry = fStorage->Get("/SHUTTLE/SYSTEM/LASTRUN", 0);
293         if (cdbEntry) {
294                 TObject* anObject = cdbEntry->GetObject();
295                 if (anObject == NULL || 
296                         anObject->IsA() != AliSimpleValue::Class()) {
297                         AliError("Invalid last run object stored to CDB!");
298                         return kFALSE;
299                 }
300                 AliSimpleValue* simpleValue = (AliSimpleValue*) anObject;
301                 lastRun = simpleValue->GetInt();
302                 delete cdbEntry;
303         } else {
304                 AliWarning("There isn't last run stored! Starting from run 0");
305                 lastRun = -1;
306         }
307
308         AliInfo(Form("Last run number <%d>", lastRun));
309
310         TString whereClause("where run > ");
311         whereClause += lastRun;
312
313         Int_t newLastRun;
314         TObjArray dateEntries;
315         if (!RetrieveDATEEntries(whereClause, dateEntries, newLastRun)) {
316                 AliError("Can't retrieve entries from DAQ log book.");
317                 return kFALSE;
318         }
319
320         if (newLastRun > lastRun) {
321                 AliSimpleValue lastRunObj(newLastRun);
322                 AliCDBMetaData metaData;
323                 AliCDBId cdbID(AliCDBPath("SHUTTLE", "SYSTEM", "LASTRUN"), 0, 0);
324
325                 if (!fStorage->Put(&lastRunObj, cdbID, &metaData)) {
326                         AliError("Can't store last run to CDB!");
327                         return kFALSE;
328                 }
329         }
330
331         if (!RetrieveConditionsData(dateEntries)) {
332                 AliError("An error occured during conditions data retrieval!");
333                 return kFALSE;
334         }
335
336         return kTRUE;
337 }
338
339 Bool_t AliShuttleTrigger::CollectAll() {
340         //
341         // Collects conditions data for all run written in DAQ LogBook.
342         //
343
344         AliInfo("Collecting conditions data for all runs ...");
345
346         Int_t lastRun;
347         TObjArray dateEntries;
348         if (!RetrieveDATEEntries("", dateEntries, lastRun)) {
349                 AliError("Can't retrieve entries from DAQ log book.");
350                 return kFALSE;
351         }
352
353         if (!RetrieveConditionsData(dateEntries)) {
354                 AliError("An error occured during conditions data retrieval!");
355                 return kFALSE;
356         }
357
358         return kTRUE;
359 }
360