2024-12-02 Meta disaster recovery
La Novitade
Section titled “La Novitade”-
Lo script di merge aggregava correttamente le entità correlate presenti all’interno di un file, minimizzando il numero di query al triplestore. Tuttavia, la funzione di merge cercava ancora le entità correlate per ogni coppia di entità (sopravvissuta ed entità da fondere), introducendo una ridondanza. Ho corretto questo bug di performance.
-
Test sulle performance
Performance Test Results:--------------------------------------------------Total Entities: 1000Runs per configuration: 3Distribution Type: single_row------------------------------Efficiency Metrics:Batch Size 1: 1.00x speedupBatch Size 5: 1.01x speedupBatch Size 10: 1.01x speedupBatch Size 20: 1.04x speedupBatch Size 50: 1.02x speedupExecution Times (seconds):Batch Size: 1Average: 35.399sStd Dev: 1.328sRaw times: 36.876, 35.018, 34.302Batch Size: 5Average: 35.141sStd Dev: 0.582sRaw times: 34.657, 34.979, 35.787Batch Size: 10Average: 35.058sStd Dev: 0.341sRaw times: 34.926, 34.802, 35.445Batch Size: 20Average: 34.147sStd Dev: 0.273sRaw times: 34.386, 34.205, 33.849Batch Size: 50Average: 34.853sStd Dev: 0.425sRaw times: 34.789, 34.464, 35.308Optimal Batch Size: 20Distribution Type: equal_rows------------------------------Efficiency Metrics:Batch Size 1: 1.00x speedupBatch Size 5: 0.99x speedupBatch Size 10: 1.03x speedupBatch Size 20: 1.04x speedupBatch Size 50: 1.00x speedupExecution Times (seconds):Batch Size: 1Average: 16.947sStd Dev: 0.301sRaw times: 16.643, 17.244, 16.953Batch Size: 5Average: 17.196sStd Dev: 0.917sRaw times: 16.262, 18.094, 17.232Batch Size: 10Average: 16.431sStd Dev: 1.025sRaw times: 15.633, 16.074, 17.587Batch Size: 20Average: 16.313sStd Dev: 1.085sRaw times: 15.782, 15.597, 17.561Batch Size: 50Average: 16.990sStd Dev: 0.896sRaw times: 16.042, 17.105, 17.822Optimal Batch Size: 20Distribution Type: mixed------------------------------Efficiency Metrics:Batch Size 1: 1.00x speedupBatch Size 5: 1.00x speedupBatch Size 10: 1.02x speedupBatch Size 20: 1.05x speedupBatch Size 50: 1.07x speedupExecution Times (seconds):Batch Size: 1Average: 22.243sStd Dev: 1.699sRaw times: 24.126, 21.780, 20.823Batch Size: 5Average: 22.235sStd Dev: 1.628sRaw times: 23.920, 22.113, 20.671Batch Size: 10Average: 21.806sStd Dev: 1.489sRaw times: 23.522, 20.857, 21.039Batch Size: 20Average: 21.261sStd Dev: 0.731sRaw times: 22.103, 20.877, 20.802Batch Size: 50Average: 20.751sStd Dev: 0.461sRaw times: 21.010, 21.024, 20.219Optimal Batch Size: 50- Il batch processing ha un impatto positivo, ma di poco.
-
Ho controllato lo stato di avanzamento attuale
Tipo di entità: br,Totale entità uniche: 4,566,013,Con 'Done'=True: 3,337,578,Percentuale completata: 73.10% -
Ho trovato un bug bruttino nella funzione di merge di oc_ocdm
[...] def merge(self, other: GraphEntity, prefer_self: bool = False) -> None:types: List[URIRef] = other.get_types()for cur_type in types:self._create_type(cur_type)# [...]def _create_type(self, res_type: URIRef) -> None:self.remove_type() # <-- It doesn't remove the main type!create_type(self.g, self.res, res_type)def remove_type(self) -> None:self.g.remove((self.res, RDF.type, None))# Restore the main type IRIiri_main_type: URIRef = self.short_name_to_type_iri[self.short_name]create_type(self.g, self.res, iri_main_type)Se fondo un entità con un tipo specifico (ad esempio un JournalArticle) con un’altra che non ha tipo specifico (solo Expression) perdo il tipo specifico
-
Il misterioso file core che pesa 347G
https://github.com/openlink/virtuoso-opensource/issues/150
Quando Virtuoso crasha fa un istantanea della RAM e la salva nel file core. Da lì è poi in grado di recuperare l’integrità.
HERITRACE
Section titled “HERITRACE”-
dcterms:description [0..n]
-
Risolto un bug per cui in caso di shape multiple come valori di una properità non venivano individuate correttamente le etichette delle varie shape (issue, volume, journal)
-
Migliorata la selezione dello snapshot appropriato da utilizzare come fonte durante il ripristino per le entità correlate. Anche le entità correlate ripristinate preservano il tempo di invalidazione dello snapshot di cancellazione preesistente.
-
Gestione degli orfani anche in caso di cancellazione di un’intera entità
-
La differenza tra i risultati delle query SPARQL sul grafo RDFLib ricostruito e sul triplestore non era dovuta a un bug di RDFLib, ma all’utilizzo di una query generica per expression invece di una specifica per la risorsa bibliografica. Questo accadeva perché i tipi dell’entità non venivano ordinati per priorità nel contesto della linea temporale e della versione.
-
Durante l’implementazione dei controlli per la paginazione, l’ordine e la ricerca nel TimeVault, ho notato di aver già sviluppato queste funzionalità per il catalogo. Ho quindi riutilizzato gli stessi componenti React. Questo approccio ha un effetto interessante: non è possibile ripristinare direttamente una classe con la proprietà
shouldBeDisplayedaFalse(come un identificatore). In realtà, questa limitazione è vantaggiosa perché impedisce il ripristino arbitrario di elementi orfani - per recuperare un identificatore, è necessario ripristinare una specifica versione della risorsa bibliografica associata.const apiEndpoint = isTimeVault ? '/api/time-vault' : '/api/catalogue'; -
Ho dockerizzato HERITRACE
- Servizi
- Python
- Node
- Redis
- I triplestore non sono gestiti tramite Docker poiché questo limiterebbe la flessibilità del sistema. Non tutti gli utenti vogliono gestire i triplestore con Docker, alcuni potrebbero già avere i propri triplestore attivi. È più flessibile permettere semplicemente di specificare l’endpoint nel file di configurazione.
- Se l’utente specifica un endpoint su localhost, esso viene automaticamente interpretato come host.docker.internal, ovvero localhost dell’host e non del docker. Ovviamente anche specificare 127.0.0.1 o 0.0.0.0 sortisce lo stesso effetto.
- Semplificata la configurazione della TimeAgnosticLibrary, che richiede un file di configurazione separato. Questo file, se non presente, viene generato automaticamente utilizzando le informazioni dal file di configurazione di HERITRACE, inclusa la conversione tra localhost e host esterno per Docker.
- Servizi
oc_ocdm
Section titled “oc_ocdm”-
Marcatore esplicito per entità ripristinate. Va indicato a manina.
Perché aggiungere un marcatore esplicito per per il ripristino di un’entità anziché derivare queste informazioni direttamente dalla provenance? Perché per derivarle direttamente dalla provenance dovrei andare a leggere la provenance, causando un grave problema di performance. Al momento, infatti, l’unica informazione di contesto che viene recuperata è quella sul contatore della provenance. Dato che la provenance è sempre in aggiunta, gli snapshot precedenti non vengono mai letti e grazie a Dio è così e deve rimanere così.
class GraphEntity(AbstractEntity):@propertydef is_restored(self) -> bool:"""Indicates if this entity was restored after being deleted."""return self._is_restoreddef mark_as_restored(self) -> None:"""Marks an entity as being restored after deletion.This state signals to the provenance system that:- No new invalidation time should be generated for the previous snapshot- The original deletion snapshot's invalidation time should be preserved- The entity should be treated as restored rather than newly created"""self._to_be_deleted = Falseself._is_restored = Truedef commit_changes(self):self.preexisting_graph = Graph(identifier=self.g.identifier)if self._to_be_deleted:self.remove_every_triple()else:for triple in self.g.triples((self.res, None, None)):self.preexisting_graph.add(triple)self._is_restored = Falseself._to_be_deleted = Falseself._was_merged = Falseself._merge_list = tuple()class ProvSet(AbstractSet):def generate_provenance(self, c_time: float = None) -> set:# [...]elif cur_subj.is_restored:# RESTORATION SNAPSHOTlast_snapshot: SnapshotEntity = self.add_se(prov_subject=cur_subj, res=last_snapshot_res)# Don't set invalidation time on previous snapshot for restorationscur_snapshot: SnapshotEntity = self._create_snapshot(cur_subj, cur_time)cur_snapshot.derives_from(last_snapshot)cur_snapshot.has_description(f"The entity '{cur_subj.res}' has been restored.")if update_query:cur_snapshot.has_update_action(update_query)modified_entities.add(cur_subj.res)Stessa cosa in rdflib_ocdm
time-agnostic-library
Section titled “time-agnostic-library”- La funzione che si occupa di parsare le query di update è ora threadsafe. Così HERITRACE può ricostruire la storia delle entità cancellate in parallelo.