/// <summary> /// Constructor with the given index directory and callback to notify when the indexes were updated. /// </summary> /// <exception cref="System.IO.IOException"></exception> public IndexAndTaxonomyReplicationHandler(Directory indexDirectory, Directory taxonomyDirectory, Func <bool?> callback) { this.indexDirectory = indexDirectory; this.taxonomyDirectory = taxonomyDirectory; this.callback = callback; currentVersion = null; currentRevisionFiles = null; bool indexExists = DirectoryReader.IndexExists(indexDirectory); bool taxonomyExists = DirectoryReader.IndexExists(taxonomyDirectory); if (indexExists != taxonomyExists) { throw new InvalidOperationException(string.Format("search and taxonomy indexes must either both exist or not: index={0} taxo={1}", indexExists, taxonomyExists)); } if (indexExists) { IndexCommit indexCommit = IndexReplicationHandler.GetLastCommit(indexDirectory); IndexCommit taxonomyCommit = IndexReplicationHandler.GetLastCommit(taxonomyDirectory); currentRevisionFiles = IndexAndTaxonomyRevision.RevisionFiles(indexCommit, taxonomyCommit); currentVersion = IndexAndTaxonomyRevision.RevisionVersion(indexCommit, taxonomyCommit); WriteToInfoStream( string.Format("constructor(): currentVersion={0} currentRevisionFiles={1}", currentVersion, currentRevisionFiles), string.Format("constructor(): indexCommit={0} taxoCommit={1}", indexCommit, taxonomyCommit)); } }
public virtual void RevisionReady(string version, IDictionary <string, IList <RevisionFile> > revisionFiles, IDictionary <string, IList <string> > copiedFiles, IDictionary <string, Directory> sourceDirectory) { Directory taxonomyClientDirectory = sourceDirectory[IndexAndTaxonomyRevision.TAXONOMY_SOURCE]; Directory indexClientDirectory = sourceDirectory[IndexAndTaxonomyRevision.INDEX_SOURCE]; IList <string> taxonomyFiles = copiedFiles[IndexAndTaxonomyRevision.TAXONOMY_SOURCE]; IList <string> indexFiles = copiedFiles[IndexAndTaxonomyRevision.INDEX_SOURCE]; string taxonomySegmentsFile = IndexReplicationHandler.GetSegmentsFile(taxonomyFiles, true); string indexSegmentsFile = IndexReplicationHandler.GetSegmentsFile(indexFiles, false); bool success = false; try { // copy taxonomy files before index files IndexReplicationHandler.CopyFiles(taxonomyClientDirectory, taxonomyDirectory, taxonomyFiles); IndexReplicationHandler.CopyFiles(indexClientDirectory, indexDirectory, indexFiles); // fsync all copied files (except segmentsFile) if (taxonomyFiles.Any()) { taxonomyDirectory.Sync(taxonomyFiles); } indexDirectory.Sync(indexFiles); // now copy and fsync segmentsFile, taxonomy first because it is ok if a // reader sees a more advanced taxonomy than the index. if (taxonomySegmentsFile != null) { taxonomyClientDirectory.Copy(taxonomyDirectory, taxonomySegmentsFile, taxonomySegmentsFile, IOContext.READ_ONCE); } indexClientDirectory.Copy(indexDirectory, indexSegmentsFile, indexSegmentsFile, IOContext.READ_ONCE); if (taxonomySegmentsFile != null) { taxonomyDirectory.Sync(new[] { taxonomySegmentsFile }); } indexDirectory.Sync(new[] { indexSegmentsFile }); success = true; } finally { if (!success) { taxonomyFiles.Add(taxonomySegmentsFile); // add it back so it gets deleted too IndexReplicationHandler.CleanupFilesOnFailure(taxonomyDirectory, taxonomyFiles); indexFiles.Add(indexSegmentsFile); // add it back so it gets deleted too IndexReplicationHandler.CleanupFilesOnFailure(indexDirectory, indexFiles); } } // all files have been successfully copied + sync'd. update the handler's state currentRevisionFiles = revisionFiles; currentVersion = version; WriteToInfoStream("revisionReady(): currentVersion=" + currentVersion + " currentRevisionFiles=" + currentRevisionFiles); // update the segments.gen file IndexReplicationHandler.WriteSegmentsGen(taxonomySegmentsFile, taxonomyDirectory); IndexReplicationHandler.WriteSegmentsGen(indexSegmentsFile, indexDirectory); // Cleanup the index directory from old and unused index files. // NOTE: we don't use IndexWriter.deleteUnusedFiles here since it may have // side-effects, e.g. if it hits sudden IO errors while opening the index // (and can end up deleting the entire index). It is not our job to protect // against those errors, app will probably hit them elsewhere. IndexReplicationHandler.CleanupOldIndexFiles(indexDirectory, indexSegmentsFile); IndexReplicationHandler.CleanupOldIndexFiles(taxonomyDirectory, taxonomySegmentsFile); // successfully updated the index, notify the callback that the index is // ready. if (callback != null) { try { callback.Invoke(); } catch (Exception e) { throw new IOException(e.Message, e); } } }