]>
Commit | Line | Data |
---|---|---|
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$ | |
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 |