180a0089e03b8bf4119ace33c8a16794f02e33a2
[u/mrichter/AliRoot.git] / STORAGE / AliStorageServerThread.cxx
1 #include "AliStorageServerThread.h"
2 #include "AliStorageTypes.h"
3 #include "AliESDEvent.h"
4
5 #include "zmq.hpp"
6 #include <iostream>
7 #include <fstream>
8
9 #include <TFile.h>
10 #include <TThread.h>
11
12 using namespace std;
13 using namespace zmq;
14
15 AliStorageServerThread::AliStorageServerThread() :
16         fEventManager(0),
17         fDatabase(0),
18         fStoragePath("")
19 {
20         TThread::Lock();
21         fDatabase = new AliStorageDatabase();
22         //load parameters from config file
23         ifstream configFile (Form("%s/STORAGE/setupStorageDatabase.sh",
24                                   gSystem->Getenv("ALICE_ROOT")));
25
26         
27         if (configFile.is_open())
28         {
29                 string line;
30                 int from,to;
31                 while(configFile.good())
32                 {
33                         getline(configFile,line);
34                         from = line.find("\"")+1;
35                         to = line.find_last_of("\"");
36                         if(line.find("STORAGE_PATH=")==0)
37                         {
38                                 fStoragePath=line.substr(from,to-from);
39                         }
40                 }
41                 if(configFile.eof())
42                 {
43                         configFile.clear();
44                 }
45                 configFile.close();
46         }
47         else
48         {
49                 cout<<"SERVER -- Unable to open config file"<<endl;
50         }
51         TThread::UnLock();
52
53         //start communication on socket
54         fEventManager = new AliStorageEventManager();
55         StartCommunication();
56 }
57
58 AliStorageServerThread::~AliStorageServerThread()
59 {
60         cout<<"SERVER -- AliStorageServerThread destructor called";
61         
62         cout<<" --- OK"<<endl;
63 }
64
65 void AliStorageServerThread::StartCommunication()
66 {
67         //create two-way communication socket
68         context_t *context = new context_t(1);
69         socket_t *socket = new socket_t(*context,ZMQ_REP);
70         socket->bind(Form("tcp://*:%d",gServerCommunicationPort));      
71         
72         message_t *request = new message_t;
73         message_t *reply;
74         struct serverRequestStruct *requestMessage = new struct serverRequestStruct;
75         char *buffer;
76         
77         while(1)
78         {
79                 socket->recv(request);
80                 requestMessage = static_cast<struct serverRequestStruct*>(request->data());
81                 
82                 switch(requestMessage->messageType)
83                 {
84                 case REQUEST_LIST_EVENTS:
85                 {
86                         vector<serverListStruct> result = fDatabase->GetList(requestMessage->list);
87                         fEventManager->Send(result,socket);
88                         break;
89                 }
90                 case REQUEST_GET_EVENT:
91                 {
92                         AliESDEvent *event = fDatabase->GetEvent(requestMessage->event);
93                         fEventManager->Send(event,socket);
94                         delete event;
95                         break;
96                 }
97                 case REQUEST_GET_NEXT_EVENT:
98                 {
99                         AliESDEvent *event = fDatabase->GetNextEvent(requestMessage->event);
100                         fEventManager->Send(event,socket);
101                         delete event;
102                         break;
103                 }
104                 case REQUEST_GET_LAST_EVENT:
105                 {
106                         AliESDEvent *event = fDatabase->GetLastEvent();
107                         fEventManager->Send(event,socket);
108                         delete event;
109                         break;
110                 }
111                 case REQUEST_MARK_EVENT:
112                 {
113                         struct eventStruct *markData  = &(requestMessage->event);
114                         buffer =(char*)(MarkEvent(*markData) ? "true" : "false");
115                         reply = new message_t((void*)buffer,sizeof(char*),0);
116                         socket->send(*reply);
117                         break;
118                 }
119                 default:break;
120                 }
121                 
122         }
123 }
124
125 bool AliStorageServerThread::MarkEvent(struct eventStruct event)
126 {
127         string pathToFile = fDatabase->GetFilePath(event);
128         TFile *tmpFile = new TFile(pathToFile.c_str(),"read");
129         if(!tmpFile)
130         {
131                 cout<<"SERVER -- couldn't open temp file"<<endl;
132                 return false;
133         }
134         AliESDEvent *eventToMark = (AliESDEvent*)tmpFile->Get(Form("event%d",event.eventNumber));
135         if(!eventToMark)
136         {
137                 cout<<"SERVER -- couldn't find such event"<<endl;
138                 if(tmpFile){delete tmpFile;}
139                 return false;
140         }
141         cout<<"SERVER -- Marking event:"<<eventToMark->GetEventNumberInFile()<<endl;
142                 
143         TFile *permFile = new TFile(Form("%s/permEvents.root",fStoragePath.c_str()),"update");//open/create perm file
144         
145         if(!permFile)
146         {
147                 cout<<"SERVER -- Couldn't open perm file"<<endl;
148                 if(tmpFile){delete tmpFile;}
149                 if(eventToMark){delete eventToMark;}
150                 return false;
151         }
152
153         //create new directory for this run
154         TDirectory *currentRun;
155         if((currentRun = permFile->mkdir(Form("run%d",event.runNumber))))
156         {
157                 cout<<"SERVER -- creating new directory for this run"<<endl;
158                 currentRun->cd();
159         }
160         else
161         {
162                 cout<<"SERVER -- opening existing directory for this run"<<endl;
163                 permFile->cd(Form("run%d",event.runNumber));
164         }
165
166         //try to add record to the database
167         if(!fDatabase->MarkEvent(event))
168         {
169                 cout<<"SERVER -- could not mark event in the database"<<endl;
170                 if(tmpFile){delete tmpFile;}
171                 if(eventToMark){delete eventToMark;}
172                 if(permFile){delete permFile;}
173                 return false;
174         }
175
176         eventToMark->Write(Form("event%d",event.eventNumber));
177         permFile->Close();
178         tmpFile->Close();
179
180         if(tmpFile){delete tmpFile;}
181         if(eventToMark){delete eventToMark;}
182         if(permFile){delete permFile;}
183 //      if(currentRun)delete currentRun;//this line crashes if there is no permanent file yet
184         return true;
185 }
186