#include <ObjectManager_i.h>
Diagramma delle classi per fbfs::ObjectManager_i
Membri pubblici | |
ObjectManager_i (const utils::Prefs &prefs, const CORBA::ORB_ptr &orb) | |
Invocato al momento della creazione dell'oggetto sigleton utilizzato dal server CORBA. Continua... | |
virtual | ~ObjectManager_i () |
Invocato alla chiusura del server. Continua... | |
char* | lookup (const Security &cert, const Obj_id &id) throw (NotFound, SecurityException, InternalError) |
void | remove (const Security &cert, const Obj_id &id) throw (PartialExecution, NotFound, SecurityException, InternalError) |
void | put (const Security &cert, const Obj_id &id, const Obj &o, const Obj_prop &p) throw (PartialExecution, AlreadyPresent, SecurityException, InternalError) |
void | reparse (const Security &cert) throw (SecurityException) |
|
Invocato al momento della creazione dell'oggetto sigleton utilizzato dal server CORBA. Qui è inizializzato lo stato del server. Definizione alla linea 38 del file ObjectManager_i.cc. 00039 : prefs(p), orb(o) { 00040 00041 // Scandisco il file con l'elenco degli hosts e riempio la struttura servers. 00042 ifstream file; 00043 file.open(prefs.get("hostfile", "objectmanager-server.hosts").c_str()); 00044 while(!file.eof()) { 00045 string s; 00046 file >> s; 00047 URI uri(s); 00048 if(uri.isValid()) 00049 servers.push_front(s); 00050 }; 00051 00052 // Eseguo la funzione di convalida degli Storage e di preparazione della 00053 // struttura Repository. 00054 validate(); 00055 00056 // Ora rep contiene il repository aggiornato e consistente. 00057 // Posso attivare il servizio. 00058 } |
|
Invocato alla chiusura del server.
Definizione alla linea 56 del file ObjectManager_i.h. 00056 {} |
|
Definizione alla linea 60 del file ObjectManager_i.cc. 00061 { 00062 string name(id.name); 00063 lock.lock(name); 00064 00065 if( rep.count(name) == 0 ) { 00066 lock.unlock(name); 00067 throw NotFound(); 00068 }; 00069 00070 Servers &s = rep[name]; 00071 00072 if( s.size() < 1 ) { 00073 lock.unlock(name); 00074 throw InternalError(); 00075 }; 00076 00077 // Sceglie tra i server quello più opportuno. Potrebbe essere effettuato 00078 // secondo politiche di vicinanza, per esempio analizzando il certificato 00079 // di identità del richiedente. 00080 // Qui: scelta casuale tra i server disponibili. 00081 int n = utils::rand(s.size()); 00082 Servers::iterator i = s.begin(); 00083 while(n-->0) 00084 i++; 00085 lock.unlock(name); 00086 return strdup((*i).c_str()); 00087 } |
|
Definizione alla linea 136 del file ObjectManager_i.cc. 00137 { 00138 00139 string name(id.name); 00140 lock.lock(name, true); 00141 00142 // Verifico che l'oggetto non sia già nel repository 00143 if(rep.count(name) != 0) { 00144 lock.unlock(name); 00145 throw AlreadyPresent(); 00146 }; 00147 00148 // Genero una struttura Obj_ts per l'oggetto. 00149 Obj_ts ts; 00150 ts.time = utils::TimeStamp::current(); 00151 00152 // Stabilisco da Obj_prop la politica di replicazione e la metto in atto. 00153 switch(p.type) { 00154 case Properties::DONT_SAVE : 00155 break; 00156 case Properties::REPLICATE_ON_CREAT : 00157 case Properties::REPLICATE_ALWAYS : 00158 case Properties::REPLICATE_MIN_MAX : 00159 { 00160 int ns = servers.size(); 00161 int n = p.value_a; 00162 if(n>ns) 00163 n=ns; 00164 // itemserver sarà l'elenco dei server che contengolo l'oggetto desiderato. 00165 Servers itemservers; 00166 00167 // Metto gli oggetti nei server, scandendo in modo ciclico la lista. 00168 // Se arrivo in fondo, riparto dall'inizio. 00169 Servers::iterator i = servers.begin(); 00170 for(int skip = utils::rand(servers.size()); skip-- > 0; i++); 00171 bool failed = false; 00172 while(n--) { 00173 const string &s = (*i); 00174 URI uri(s); 00175 00176 // Contatto il server "s" e cerco di mettergli dento l'oggetto 00177 // desiderato. 00178 try{ 00179 CORBA::Object_var obj = utils::NameServer::get_object(orb, uri); 00180 fbfs::Storage_var server = fbfs::Storage::_narrow(obj); 00181 if(CORBA::is_nil(server)) 00182 throw NotFound(); 00183 server->put(cert, o, id, p, ts); 00184 itemservers.push_front(s); 00185 } catch (...) { 00186 // Potrei ritentare su altri server, ma la cosa indurre 00187 // deadlock difficilmente gestibili. 00188 // Meglio rinunciare. 00189 failed = true; 00190 }; 00191 // Incrementa l'iterator, ricominciando da capo se la lista è finita. 00192 i++; 00193 if(i == servers.end() ) 00194 i = servers.begin(); 00195 }; 00196 00197 // Nessun oggetto messo nel repository 00198 if(itemservers.size()==0) { 00199 lock.unlock(name); 00200 throw InternalError(); 00201 } 00202 00203 // In questo caso la creazione non rispecchia le necessità imposte. 00204 // Cancello l'oggetto dagli Storage che ce l'hanno e ritorno InternalError. 00205 if(p.type == Properties::REPLICATE_MIN_MAX && itemservers.size() < p.value_b) { 00206 Servers::iterator i = itemservers.begin(); 00207 while(i != itemservers.end()) { 00208 URI uri(*i); 00209 try { 00210 CORBA::Object_var obj = utils::NameServer::get_object(orb, uri); 00211 fbfs::Storage_var server = fbfs::Storage::_narrow(obj); 00212 if(CORBA::is_nil(server)) 00213 throw InternalError(); 00214 server->remove(cert, id); 00215 } catch (...) {}; 00216 }; 00217 lock.unlock(name); 00218 throw InternalError(); 00219 }; 00220 00221 // Metto la coppia [oggetto . lista dei server] nel repository. 00222 rep[name] = itemservers; 00223 00224 if(failed) { 00225 lock.unlock(name); 00226 throw PartialExecution(); 00227 }; 00228 break; 00229 }; 00230 default: 00231 lock.unlock(name); 00232 throw InternalError(); 00233 }; 00234 lock.unlock(name); 00235 } |
|
Definizione alla linea 89 del file ObjectManager_i.cc. 00090 { 00091 string name(id.name); 00092 lock.lock(name, true); 00093 00094 if( rep.count(name) == 0 ) { 00095 lock.unlock(name); 00096 throw NotFound(); 00097 }; 00098 00099 Servers &s = rep[name]; 00100 00101 if( s.size() < 1) { 00102 lock.unlock(name); 00103 throw InternalError(); 00104 }; 00105 00106 // Devo contattare ogni server, cancellare l'oggetto da ogniuno di essi 00107 // ed alla fine rimuovere l'entry da rep. 00108 00109 // Politica in caso di guasti: cerco di cancellare l'oggetto da ogni 00110 // Storage collegato. Se qualcuno dà errore, proseguo fino alla fine 00111 // con gli altri Storage e ritorno InternalError(). 00112 bool failed = false; 00113 00114 for(Servers::iterator i = s.begin(); i != s.end(); i++) { 00115 URI uri(*i); 00116 try { 00117 CORBA::Object_var obj = utils::NameServer::get_object(orb, uri); 00118 fbfs::Storage_var server = fbfs::Storage::_narrow(obj); 00119 if(CORBA::is_nil(server)) 00120 throw InternalError(); 00121 00122 server->remove(cert, id); 00123 } catch (...) { 00124 // Attenzione: in questo caso maledetto il repository può essere in 00125 // uno stato inconsistente. 00126 failed = true; 00127 } 00128 } 00129 rep.erase(name); 00130 lock.unlock(name); 00131 00132 if(failed) 00133 throw PartialExecution(); 00134 } |
|
Definizione alla linea 237 del file ObjectManager_i.cc. 00237 { 00238 } |