#include <Proxy_i.h>
Diagramma delle classi per fbfs::Proxy_i
Membri pubblici | |
Proxy_i (utils::Prefs &prefs, const CORBA::ORB_ptr &orb) | |
Invocato al momento della creazione dell'oggetto sigleton utilizzato dal server CORBA. Continua... | |
virtual | ~Proxy_i () |
Invocato alla chiusura del server. Continua... | |
fbfs::Obj* | get (const Security &cert, const Obj_id &id) throw (NotFound, SecurityException, InternalError) |
Preleva un oggetto dal repository. Continua... | |
void | put (const Security &cert, const Obj_id &id, const Obj &obj, const Obj_prop &props) throw (AlreadyPresent, NotFound, SecurityException, InternalError) |
Inserisce un oggetto nel repository. Continua... | |
void | remove (const Security &cert, const Obj_id &id) throw (NotFound, SecurityException, InternalError) |
Rimuove un oggetto dal repository. Continua... |
Questa classe si occupa di inviare le richieste desiderate agli appositi ObjectManager; di prelevare gli Obj deisderati dagli appositi Storage; di risolvere i nomi degli agenti attraverso gli appositi NameServer.
Essa mantiene una cache locale degli oggetti desidetati in lettura. La coerenza della cache con il repository viene valutata ogni lettura, confrontanto la struttura Obj_ts dell'oggetto locale con la corrispondente struttura dell'oggetto nel repository.
Definizione alla linea 49 del file Proxy_i.h.
|
Invocato al momento della creazione dell'oggetto sigleton utilizzato dal server CORBA. Qui č inizializzato lo stato del server. Definizione alla linea 36 del file Proxy_i.cc. 00037 : prefs(p), orb(o), dir(p.get("cachedir","data")), nsclient(o, p, "", "") {} |
|
Invocato alla chiusura del server.
Definizione alla linea 60 del file Proxy_i.h. 00060 {} |
|
Preleva un oggetto dal repository. Consente di reperire un'oggetto nel repository, risalendo alla sua locazione attraverso i NameServer (i cui indirizzi sono specificati nel file di configurazione letto dal server alla partenza). Qualora sia presente un oggetto nella cache locale, col voluto Obj_id, viene valutata la consistenza dell'oggetto locale con quello nel repository confrontandone le strutture Obj_ts. Se esse coincidono, viene restituita copia dell'oggetto locale. Altrimenti l'oggetto locale viene rimosso e si procede alla lettura dallo storage remoto ed all'inserimento dell'oggetto remoto nella cache locale.
Definizione alla linea 39 del file Proxy_i.cc. 00040 { 00041 fbfs::Storage_var storage; 00042 string storage_name; 00043 Obj_ts rem_ts; 00044 string ident(id.name); 00045 00046 // Accesso shared, in principio. Se poi non c'č il file e devo 00047 // prelevarlo dal server, allora ottengo un accesso exclusive 00048 lock.lock(ident); 00049 00050 int level=0; 00051 try { 00052 string strobj = File::read(ident, dir); 00053 level = 1; 00054 00055 string strobj_ts = File::read(ident+".ts", dir ); 00056 Obj_ts loc_ts = Object::string2Obj_ts(strobj_ts); 00057 level = 2; 00058 00059 storage_name = File::read(ident+".server", dir); 00060 level = 3; 00061 00062 utils::URI uri(storage_name); 00063 00064 CORBA::Object_ptr obj = utils::NameServer::get_object(orb, uri); 00065 storage = fbfs::Storage::_narrow(obj); 00066 if(CORBA::is_nil(storage)) { 00067 lock.unlock(ident); 00068 throw InternalError(); 00069 } 00070 level = 4; 00071 00072 rem_ts = storage->get_ts(cert, id); 00073 00074 if( Object::cmp_ts(loc_ts, rem_ts) ) { 00075 lock.unlock(ident); 00076 return Object::string2Obj(strobj); 00077 } 00078 } catch (...) {}; 00079 00080 // Da qui accesso esclusivo al file 00081 lock.unlock(ident); 00082 lock.lock(ident, true); 00083 00084 // In ogni altro caso: file non trovato sul server remoto, errore del server 00085 // remoto, differenza di ts, etc, rimuovo l'oggetto dalla cache e tento di 00086 // prelevarlo dal server remoto, aggiornando la cache. 00087 try { 00088 switch(level) { 00089 case 4: 00090 case 3: 00091 File::remove(ident+".server", dir); 00092 case 2: 00093 File::remove(ident+".ts", dir); 00094 case 1: 00095 File::remove(ident, dir); 00096 } 00097 } catch (...) { 00098 lock.unlock(ident); 00099 throw InternalError(); 00100 }; 00101 00102 // In caso di mancanza di file, fino ad ora non č ancora stato 00103 // contattato il server remoto. Devo risolvere il nome 00104 // dell'ObjectManager che gestisce l'oggetto e ricercare in esso 00105 // l'indirizzo di uno Storage. 00106 00107 try { 00108 if(level==0) { 00109 utils::URI uri(nsclient.lookup(id)); 00110 if(!uri.isValid()) 00111 throw NotFound(); 00112 00113 CORBA::Object_ptr obj = utils::NameServer::get_object(orb, uri); 00114 fbfs::ObjectManager_var om = fbfs::ObjectManager::_narrow(obj); 00115 if(CORBA::is_nil(om)) 00116 throw NotFound(); 00117 00118 // Qui ricerco l'indirizzo del server nell'Object Manager 00119 try { 00120 CORBA::String_var s = om->lookup(cert, id); 00121 storage_name = string(s); 00122 00123 CORBA::Object_ptr obj = utils::NameServer::get_object( orb, utils::URI(storage_name) ); 00124 storage = fbfs::Storage::_narrow(obj); 00125 if(CORBA::is_nil(storage)) 00126 throw InternalError(); 00127 00128 rem_ts = storage->get_ts(cert, id); 00129 } catch(NotFound) { 00130 throw NotFound(); 00131 } catch (...) { 00132 throw InternalError(); 00133 }; 00134 }; 00135 // Ora il server č contattato. Qualora non abbia prima ricevuto giā 00136 // rem_ts, lo leggo ora. 00137 if(level!=4) 00138 rem_ts = storage->get_ts(cert, id); 00139 00140 // Prelevo il file. 00141 Obj *o = storage->get(cert, id); 00142 00143 // Decido se metterlo in cache 00144 00145 // Lo metto in cache, se ci riesco, senza sollevare polveroni in caso 00146 // di mancanza di riuscita. 00147 level = 0; 00148 try { 00149 File::write( Object::Obj2string(*o), ident, dir, true); 00150 level = 1; 00151 File::write( Object::Obj_ts2string(rem_ts), ident+".ts", dir, true); 00152 level = 2; 00153 File::write( storage_name, ident+".server", dir, true); 00154 level = 3; 00155 } catch (...) { 00156 // Se ci sono problemi, cerco di rimuovere i file rimasti. 00157 try{ 00158 switch(level) { 00159 case 3: 00160 File::remove( ident+".server", dir ); 00161 case 2: 00162 File::remove( ident+".ts", dir ); 00163 case 1: 00164 File::remove( ident, dir ); 00165 } 00166 } catch (...) {}; 00167 }; 00168 00169 // Restituisco un riferimento all'oggetto. 00170 // Si noti che qualora si decida di introdurre delle eccezioni che possano 00171 // capitare tra il o = storage-get() e qui, bisogna provvedere alla rimozione 00172 // dell'area di memoria associata all'oggetto o. 00173 lock.unlock(ident); 00174 return o; 00175 } catch (NotFound) { 00176 lock.unlock(ident); 00177 throw NotFound(); 00178 } catch (SecurityException) { 00179 lock.unlock(ident); 00180 throw SecurityException(); 00181 } catch (...) { 00182 lock.unlock(ident); 00183 throw InternalError(); 00184 }; 00185 } |
|
Inserisce un oggetto nel repository. L'inserimento consta delle seguenti fasi:
Definizione alla linea 187 del file Proxy_i.cc. 00188 { 00189 // - Cerco di mettere l'oggetto nel repository. 00190 // - Se ci riesco aggiorno la cache col nuovo oggetto 00191 // (eventualmente cancellando l'oggetto precedente), 00192 // prelevando il suo Obj_ts dall'ObjectManager opportuno. 00193 // - Altrimenti lascio la cache come prima. 00194 00195 utils::URI uri(nsclient.lookup(id)); 00196 if(!uri.isValid()) 00197 throw NotFound(); 00198 00199 fbfs::ObjectManager_var om; 00200 try { 00201 CORBA::Object_ptr obj = utils::NameServer::get_object(orb, uri); 00202 om = fbfs::ObjectManager::_narrow(obj); 00203 } catch (...) { throw NotFound(); }; 00204 if(CORBA::is_nil(om)) 00205 throw NotFound(); 00206 00207 // Qui c'č il riferimento all'ObjectManager. 00208 om->put(cert, id, obj, props); 00209 00210 // Contattando l'ObjectManager, ottengo l'indirizzo di uno Storage, 00211 // che metto in storage_name. Poi contattando lo Storage recupero 00212 // la struttura Obj_ts. 00213 string ident(id.name); 00214 Obj_ts rem_ts; 00215 00216 string storage_name; 00217 try { 00218 CORBA::String_var s = om->lookup(cert, id); 00219 storage_name = string(s); 00220 00221 CORBA::Object_ptr obj = utils::NameServer::get_object( orb, utils::URI(storage_name) ); 00222 fbfs::Storage_var storage = fbfs::Storage::_narrow(obj); 00223 if(CORBA::is_nil(storage)) 00224 throw InternalError(); 00225 00226 rem_ts = storage->get_ts(cert, id); 00227 } catch (...) { 00228 // Qui andrebbe _molto_ codice per capire cosa fare in questa eventualitā 00229 // rara. Facciamo finta di niente: 00230 // "Never test for an error condition you don't know how to handle." 00231 return; 00232 }; 00233 00234 // Ottengo un accesso esclusivo all'oggetto. 00235 lock.lock(ident, true); 00236 00237 // Lo metto in cache, se ci riesco, senza sollevare polveroni in caso 00238 // di mancanza di riuscita. 00239 int level = 0; 00240 try { 00241 File::write( Object::Obj2string(obj), ident, dir, true); 00242 level = 1; 00243 File::write( Object::Obj_ts2string(rem_ts), ident+".ts", dir, true); 00244 level = 2; 00245 File::write( storage_name, ident+".server", dir, true); 00246 level = 3; 00247 } catch (...) { 00248 // Se ci sono problemi, cerco di rimuovere i file rimasti. 00249 try{ 00250 switch(level) { 00251 case 3: 00252 File::remove( ident+".server", dir ); 00253 case 2: 00254 File::remove( ident+".ts", dir ); 00255 case 1: 00256 File::remove( ident, dir ); 00257 } 00258 } catch (...) {}; 00259 }; 00260 lock.unlock(ident); 00261 } |
|
Rimuove un oggetto dal repository. La rimozione consta delle seguenti fasi:
Definizione alla linea 263 del file Proxy_i.cc. 00264 { 00265 // - Cerco di rimuovere l'oggetto dal repository. 00266 // - Se ci riesco cancello l'eventuale copia in cache. 00267 00268 utils::URI uri(nsclient.lookup(id)); 00269 if(!uri.isValid()) 00270 throw NotFound(); 00271 00272 string ident(id.name); 00273 00274 CORBA::Object_ptr obj = utils::NameServer::get_object(orb, uri); 00275 fbfs::ObjectManager_var om = fbfs::ObjectManager::_narrow(obj); 00276 if(CORBA::is_nil(om)) 00277 throw NotFound(); 00278 00279 lock.lock(ident, true); 00280 try { 00281 om->remove(cert, id); 00282 } catch (...) { 00283 lock.unlock(ident); 00284 throw; 00285 }; 00286 00287 // Se il flusso arriva qui, l'oggetto esisteva nel repository remoto 00288 // ed č stato rimosso con successo. 00289 // Ora lo rimuovo dalla cache, se c'č. 00290 // Approccio ottimista qualora non riesca a rimuoverlo. Anche se rimane, 00291 // infatti non fa danno. 00292 try { File::remove(ident, dir); } catch (...) {}; 00293 try { File::remove(ident+".ts", dir); } catch (...) {}; 00294 try { File::remove(ident+".server", dir); } catch (...) {}; 00295 lock.unlock(ident); 00296 } |