* 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.
-// There are two way for retrieving data from the server.
+// This class represents the AliDCSClient, the client used for
+// data retrieval from the DCS server.
+// There are two ways for retrieving data from the server:
// 1) asking for DP (DataPoint) - usually changed frequently.
-// 2) asking for Alias (Alias) - alias should be the same through whole
-// experimnet.
+// 2) asking for Alias (Alias) - alias should be the same through
+// the whole experiment.
//
-// There are two type of read operations:
-// Asking for single alias/dp or asking for set of aliases/dp
+// There are two types of read operations:
+// Asking for a single alias/DP or asking for a set of aliases/DPs
//
-// In case of ServerError the coresponding error code and
+// In case of ServerError the corresponding error code and
// error string (description) could be got by GetServerErrorCode() and
// GetServerErrorString()
//
#include <TMap.h>
#include <TObjString.h>
#include <TSystem.h>
+#include <TTimeStamp.h>
ClassImp(AliDCSClient)
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
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 ++;
}
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));
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;
}
//______________________________________________________________________
-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];
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;
}
//______________________________________________________________________
// 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)
//
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;
case AliDCSClient::fgkServerError:
return AliDCSClient::fgkServerErrorString;
+
+ case AliDCSClient::fgkUnknownDP:
+ return AliDCSClient::fgkUnknownDPString;
default:
AliErrorGeneral("AliDCSClient::GetErrorString",