]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - SHUTTLE/DCSClient/AliDCSClient.cxx
adding warning in case result is outside of queried period
[u/mrichter/AliRoot.git] / SHUTTLE / DCSClient / AliDCSClient.cxx
index c4b1b86c24053ac5a99c2914e606901c69cda96b..50a1e5bfb9345b2ce2808012b86266b879e7dfd5 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
-/*
-$Log$
-Revision 1.2  2007/06/09 13:01:09  jgrosseo
-Switching to retrieval of several DCS DPs at a time (multiDPrequest)
-
-Revision 1.1  2006/11/06 14:22:47  jgrosseo
-major update (Alberto)
-o) reading of run parameters from the logbook
-o) online offline naming conversion
-o) standalone DCSclient package
-
-Revision 1.6  2006/10/02 16:38:39  jgrosseo
-update (alberto):
-fixed memory leaks
-storing of objects that failed to be stored to the grid before
-interfacing of shuttle status table in daq system
-
-Revision 1.5  2006/08/15 10:50:00  jgrosseo
-effc++ corrections (alberto)
-
-Revision 1.4  2006/07/04 14:59:57  jgrosseo
-revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
-
-Revision 1.3  2006/06/12 09:11:16  jgrosseo
-coding conventions (Alberto)
-
-Revision 1.2  2006/03/07 07:52:34  hristov
-New version (B.Yordanov)
-
-Revision 1.3  2005/11/17 17:47:34  byordano
-TList changed to TObjArray
-
-Revision 1.2  2005/11/17 14:43:23  byordano
-import to local CVS
-
-Revision 1.1.1.1  2005/10/28 07:33:58  hristov
-Initial import as subdirectory in AliRoot
-
-Revision 1.1.1.1  2005/09/12 22:11:40  byordano
-SHUTTLE package
-
-Revision 1.3  2005/08/30 10:53:23  byordano
-some more descriptions added
-
-*/
-
 //
 // This class represents the AliDCSClient.
 // The client used for data retrieval from DCS server.
@@ -84,6 +38,7 @@ some more descriptions added
 #include <TMap.h>
 #include <TObjString.h>
 #include <TSystem.h>
+#include <TTimeStamp.h>
 
 ClassImp(AliDCSClient)
 
@@ -93,12 +48,13 @@ const char* AliDCSClient::fgkTimeoutString = "Timeout";
 const char* AliDCSClient::fgkBadMessageString = "BadMessage";
 const char* AliDCSClient::fgkCommErrorString = "CommunicationError";
 const char* AliDCSClient::fgkServerErrorString = "ServerError";
+const char* AliDCSClient::fgkUnknownDPString = "UnknownAlias/DP";
 
 //______________________________________________________________________
 AliDCSClient::AliDCSClient(const char* host, Int_t port, UInt_t timeout,
-       Int_t retries):
-       fSocket(NULL), fHost(host), fPort(port), fTimeout(timeout), fRetries(retries),
-       fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
+       Int_t retries, Int_t multiSplit):
+       fSocket(NULL), fHost(host), fPort(port), fTimeout(timeout), fRetries(retries), fMultiSplit(multiSplit),
+       fServerErrorCode(AliDCSMessage::kNoneError), fServerError(""), fResultErrorCode(0)
 {
        // 
        // host: DCS server host
@@ -125,23 +81,27 @@ Bool_t AliDCSClient::Connect()
        
        Close();
        
-       Int_t tries = 0;        
+       Int_t tries = 0;
+       Int_t sleeptime=300;
+       
        while (tries < fRetries) 
        {
                fSocket = new TSocket(fHost, fPort);
-               if (fSocket->IsValid()) 
+                       
+               if (fSocket && fSocket->IsValid()) 
                {
-                       AliDebug(1, Form("Connected to %s:%d", fHost.Data(), fPort));
+                       AliDebug(1, Form("%s  *** Connected to %s:%d", TTimeStamp(time(0)).AsString("s"), fHost.Data(), fPort));
                        fSocket->SetOption(kNoBlock, 1);
                        return kTRUE;
                }
 
-               AliDebug(1, Form("Connection timeout! tries <%d> ...", tries));
+               AliError(Form(" *** Connection to AMANDA server failed Tried <%d> times ...", tries+1));
+               if(tries<fRetries-1) AliInfo(Form(" *** Waiting %d seconds before next retry.", sleeptime));
 
                delete fSocket;
                fSocket = NULL;
 
-               gSystem->Sleep(fTimeout);
+               gSystem->Sleep(sleeptime);
                tries ++;
        }
        
@@ -158,7 +118,7 @@ Int_t AliDCSClient::SendBuffer(const char* buffer, Int_t size)
 
         while (sentSize < size && tries < fRetries) {
 
-                Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout);
+                Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout*1000); //timeout for TSocket::Select is in msec
 
                 if (sResult == 0) {
                        AliDebug(1, Form("Timeout! tries <%d> ...", tries));
@@ -200,9 +160,10 @@ Int_t AliDCSClient::ReceiveBuffer(char* buffer, Int_t size)
 
         while (receivedSize < size && tries < fRetries) {
 
-                Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout);
+                Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout*1000); //timeout for TSocket::Select is in msec
 
                 if (sResult == 0) {
+                       AliDebug(1, Form("Time when timing out: %s   Timeout value: %d seconds",TTimeStamp(time(0)).AsString("s"),fTimeout));
                         AliDebug(1, Form("Timeout! tries <%d> ...", tries));
                         tries ++;
                         continue;
@@ -246,9 +207,9 @@ Int_t AliDCSClient::SendMessage(AliDCSMessage& message)
 }
 
 //______________________________________________________________________
-Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message) 
+Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message)
 {
-// receive message from the DCS server
+       // receive message from the DCS server
        
        char header[HEADER_SIZE];
 
@@ -308,11 +269,20 @@ Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
                return sResult;
        }
 
-       sResult = ReceiveValueSet(result);
+       Int_t receivedValues = 0;
 
-       Close();
+       while (1)
+       {
+               Int_t tmp = 0;
+               sResult = ReceiveValueSet(result, tmp);
+               if (sResult <= 0)
+                       break;
+               receivedValues += sResult;
+       }
 
-       return sResult;
+       Close();
+       
+       return receivedValues;
 }
 
 //______________________________________________________________________
@@ -326,141 +296,173 @@ TMap* AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
        // Result: map containing the array of alias names. It will be filled with
        // the values retrieved for each alias
 
-       Connect();
-       
-       if (!IsConnected()) {
-               AliError("Not connected!");
-               return 0;
-       }
-
-       AliDCSMessage multiRequestMessage;
-       multiRequestMessage.CreateMultiRequestMessage(reqType,
-                       startTime, endTime);
+       TMap* result = new TMap;
+       result->SetOwner(1);
 
        if (endIndex < 0 || endIndex > list->GetEntries())
                endIndex = list->GetEntries();
-                       
-       for (Int_t i=startIndex; i<endIndex; i++)
+
+       for (Int_t subsetBegin = startIndex; subsetBegin < endIndex; subsetBegin += fMultiSplit)
        {
-               TObjString* aRequest = (TObjString*) list->At(i);
-               if (!multiRequestMessage.AddRequestString(aRequest->String()))
+               Connect();
+
+               if (!IsConnected())
+               {
+                       AliError("Not connected!");
+                       delete result;
+                       fResultErrorCode = fgkBadState;
                        return 0;
-       }
+               }
+
+               Int_t subsetEnd = subsetBegin + fMultiSplit;
+               if (subsetEnd > endIndex)
+                   subsetEnd = endIndex;
        
-       Int_t sResult = 0;
-       if ((sResult = SendMessage(multiRequestMessage)) < 0)
-       {
-                AliError(Form("Can't send request message! Reason: %s",
-                        GetErrorString(sResult)));
-                Close();
-                return 0;
-        }
+               AliDCSMessage requestMessage;
+               if (fMultiSplit == 1)
+               {
+                       // single dp request
+
+                       TObjString* aRequest = (TObjString*) list->At(subsetBegin);
+                       requestMessage.CreateRequestMessage(reqType, startTime, endTime, aRequest->String());
+               }
+               else
+               {
+                       // multi dp request
+
+                       requestMessage.CreateMultiRequestMessage(reqType,
+                               startTime, endTime);
+
+                       for (Int_t i=subsetBegin; i<subsetEnd; i++)
+                       {
+                               TObjString* aRequest = (TObjString*) list->At(i);
+                               if (!requestMessage.AddRequestString(aRequest->String()))
+                               {
+                                       delete result;
+                                       fResultErrorCode = fgkBadMessage;
+                                       return 0;
+                               }
+                       }
+               }
 
-       TMap* result = new TMap;
-       result->SetOwner(1);
+               if ((fResultErrorCode = SendMessage(requestMessage)) < 0)
+               {
+                       AliError(Form("Can't send request message! Reason: %s",
+                               GetErrorString(fResultErrorCode)));
+                       Close();
+                       delete result;
+                       return 0;
+               }
 
-       for (Int_t i=startIndex; i<endIndex; i++)
-       {
-               TObjString* aRequest = (TObjString*) list->At(i);
-               
-               TObjArray* resultSet = new TObjArray();
-               resultSet->SetOwner(1);
+               while (1)
+               {
+                       TObjArray* resultSet = new TObjArray();
+                       resultSet->SetOwner(1);
 
-               if ((sResult = ReceiveValueSet(resultSet)) < 0) {
-                       AliError(Form("Can't get values for %s!" ,
-                               aRequest->String().Data()));
+                       Int_t ownerIndex = -1;
+                       fResultErrorCode = ReceiveValueSet(resultSet, ownerIndex);
 
-                       delete resultSet;
-                       result->DeleteValues();
-                       delete result;
-                       return 0;
+                       if (fResultErrorCode < 0)
+                       {
+                               if (fResultErrorCode == fgkUnknownDP)
+                               {
+                                       AliError(Form("%s",fServerError.Data()));
+                               }
+                               
+                               AliError("Can't get values");
+
+                               delete resultSet;
+                               result->DeleteValues();
+                               delete result;
+                               return 0;
+                       }
+
+                       if (ownerIndex < 0)
+                       {
+                               // no more values
+                               delete resultSet;
+                               break;
+                       }
+
+                       TObjString* aRequest = (TObjString*) list->At(ownerIndex + subsetBegin);
+                       
+                       for (Int_t i=0; i<resultSet->GetEntries(); i++)
+                       {
+                               AliDCSValue* value = (AliDCSValue*) resultSet->At(i);
+                               if (!value)
+                                       continue;
+                               if (value->GetTimeStamp() < startTime || value->GetTimeStamp() > endTime)
+                                       AliWarning(Form("Value for %s outside of queried interval (%d to %d): %d", aRequest->String().Data(), startTime, endTime, value->GetTimeStamp()));
+                       }
+               
+                       TObjArray* target = dynamic_cast<TObjArray*> (result->GetValue(aRequest));
+                       if (target)
+                       {
+                               target->AddAll(resultSet);
+                               resultSet->SetOwner(0);
+                               delete resultSet;
+                       }
+                       else
+                               result->Add(aRequest, resultSet);
                }
 
-               result->Add(aRequest, resultSet);
-       }
+               Close();
 
-       Close();
+               Int_t nValues = 0;
+               TObjArray* example = (TObjArray*) result->GetValue(list->At(subsetBegin));
+               if (example)
+                       nValues = example->GetEntries();
+               AliInfo(Form("Retrieved entries %d..%d (total %d..%d); E.g. %s has %d values collected",
+                       subsetBegin, subsetEnd-1, startIndex, endIndex-1, list->At(subsetBegin)->GetName(), nValues));
+       }
 
        return result;
 }
        
 //______________________________________________________________________
-Int_t AliDCSClient::ReceiveValueSet(TObjArray* result)
+Int_t AliDCSClient::ReceiveValueSet(TObjArray* result, Int_t& ownerIndex)
 {
-// receive set of values 
+       // receive set of values
 
-       Int_t sResult;
-
-       AliDCSMessage responseMessage;
-       if ((sResult = ReceiveMessage(responseMessage)) < 0) {
-               AliError(Form("Can't receive response message! Reason: %s",
-                       GetErrorString(sResult)));
+       AliDCSMessage message;
+       Int_t sResult = ReceiveMessage(message);
+       if (sResult < 0)
+       {
+               AliError(Form("Can't receive message! Reason: %s", GetErrorString(sResult)));
                return sResult;
-       }       
+       }
 
-       UInt_t valueCount;
+       if (message.GetType() == AliDCSMessage::kResultSet)
+       {
+               // this was the last message
+               ownerIndex = message.GetOwnerIndex();
+               if (ownerIndex < 0)
+                       return 0;
 
-       if (responseMessage.GetType() == AliDCSMessage::kCount) {
-               valueCount = responseMessage.GetCount();
+               sResult = message.GetValues(result);
 
-       } else if (responseMessage.GetType() == AliDCSMessage::kError) {
-               fServerErrorCode = responseMessage.GetErrorCode();
-               fServerError = responseMessage.GetErrorString();
+               return sResult;
+       }
+       else if (message.GetType() == AliDCSMessage::kError)
+       {
+               fServerErrorCode = message.GetErrorCode();
+               fServerError = message.GetErrorString();
 
                return AliDCSClient::fgkServerError;
-
-       } else {
-               AliError("Bad message type received!"); 
-               return AliDCSClient::fgkBadMessage;
        }
+       
+       else if (message.GetType() == AliDCSMessage::kUnknownDP)
+       {
+               fServerError = message.GetErrorString();
 
-       UInt_t receivedValues = 0;
-
-       AliDCSValue::Type valueType = AliDCSValue::kInvalid;
-
-       while (receivedValues < valueCount) {
-
-                AliDCSMessage message;
-
-                if ((sResult = ReceiveMessage(message)) < 0) {
-                        AliError(Form("Can't receive message! Reason: %s",
-                               GetErrorString(sResult)));
-                        return sResult;
-                }
-
-                if (message.GetType() == AliDCSMessage::kResultSet) {
-
-                       if (valueType == AliDCSValue::kInvalid) {
-                               valueType = message.GetValueType();
-                       } else {
-                               if (valueType != message.GetValueType()) {
-                                       AliError("Unexpected value type!");
-                                       return AliDCSClient::fgkBadMessage;
-                               }
-                       }
-
-                       receivedValues += message.GetValues(result);
-
-                       if (receivedValues > valueCount) {
-                               AliError("Message contains more values than expected!");
-                               return AliDCSClient::fgkBadMessage;
-                       }
-
-               } else if (message.GetType() == AliDCSMessage::kError) {
-                               fServerErrorCode = 
-                                       responseMessage.GetErrorCode();
-                               fServerError = responseMessage.GetErrorString();
-
-                               return AliDCSClient::fgkServerError;
-               } else {
-                        AliError("Bad message type received!");
-                        return AliDCSClient::fgkBadMessage;
-                }       
-        }       
+               return AliDCSClient::fgkUnknownDP;
+       }
        
-       return receivedValues;
+
+       AliError("Bad message type received!");
+       return AliDCSClient::fgkBadMessage;
 }
-               
+
 //______________________________________________________________________
 Int_t AliDCSClient::GetDPValues(const char* dpName, UInt_t startTime,
                                UInt_t endTime, TObjArray* result)
@@ -557,6 +559,7 @@ void AliDCSClient::Close()
        //
 
        if (fSocket) {
+               AliDebug(1, Form("%s  *** Closing connection to %s:%d", TTimeStamp(time(0)).AsString("s"), fHost.Data(), fPort));
                fSocket->Close();
                delete fSocket;
                fSocket = 0;
@@ -590,6 +593,9 @@ const char* AliDCSClient::GetErrorString(Int_t code)
 
                case AliDCSClient::fgkServerError:
                        return AliDCSClient::fgkServerErrorString;
+               
+               case AliDCSClient::fgkUnknownDP:
+                       return AliDCSClient::fgkUnknownDPString;
 
                default:
                        AliErrorGeneral("AliDCSClient::GetErrorString",