@@ -354,7 +354,7 @@ public void EnsureIndex(bool forceOverwrite)
354
354
//In this case we need to initialize a writer and continue as normal.
355
355
//Since we are already inside the writer lock and it is null, we are allowed to
356
356
// make this call with out using GetIndexWriter() to do the initialization.
357
- _writer ??= CreateIndexWriterInternal ( ) ;
357
+ _writer ??= CreateIndexWriterWithLockCheck ( ) ;
358
358
359
359
//We're forcing an overwrite,
360
360
// this means that we need to cancel all operations currently in place,
@@ -416,18 +416,7 @@ private void CreateNewIndex(Directory dir)
416
416
}
417
417
418
418
//create the writer (this will overwrite old index files)
419
- var writerConfig = new IndexWriterConfig ( LuceneInfo . CurrentVersion , FieldAnalyzer )
420
- {
421
- OpenMode = OpenMode . CREATE ,
422
- MergeScheduler = new ErrorLoggingConcurrentMergeScheduler ( Name ,
423
- ( s , e ) => OnIndexingError ( new IndexingErrorEventArgs ( this , s , "-1" , e ) ) )
424
- } ;
425
-
426
- // TODO: With NRT, we should apparently use this but there is no real implementation of it!?
427
- // https://stackoverflow.com/questions/12271614/lucene-net-indexwriter-setmergedsegmentwarmer
428
- //writerConfig.SetMergedSegmentWarmer(new SimpleMergedSegmentWarmer())
429
-
430
- writer = new IndexWriter ( dir , writerConfig ) ;
419
+ writer = CreateIndexWriterWithOpenMode ( dir , OpenMode . CREATE ) ;
431
420
432
421
// Required to remove old index files which can be problematic
433
422
// if they remain in the index folder when replication is attempted.
@@ -793,7 +782,7 @@ private class IndexCommiter : DisposableObjectSlim
793
782
private DateTime _timestamp ;
794
783
private Timer _timer ;
795
784
private readonly object _locker = new object ( ) ;
796
- private const int WaitMilliseconds = 2000 ;
785
+ private const int WaitMilliseconds = 1000 ;
797
786
798
787
/// <summary>
799
788
/// The maximum time period that will elapse until we must commit (5 mins)
@@ -926,20 +915,21 @@ private bool ProcessQueueItem(IndexOperation item)
926
915
/// Used to create an index writer - this is called in GetIndexWriter (and therefore, GetIndexWriter should not be overridden)
927
916
/// </summary>
928
917
/// <returns></returns>
929
- private TrackingIndexWriter CreateIndexWriterInternal ( )
918
+ private TrackingIndexWriter CreateIndexWriterWithLockCheck ( )
930
919
{
931
920
var dir = GetLuceneDirectory ( ) ;
932
921
933
- // Unfortunatley if the appdomain is taken down this will remain locked, so we can
922
+ // Unfortunately if the appdomain is taken down this will remain locked, so we can
934
923
// ensure that it's unlocked here in that case.
935
924
try
936
925
{
937
926
if ( IsLocked ( dir ) )
938
927
{
939
- if ( _logger . IsEnabled ( LogLevel . Debug ) )
928
+ if ( _logger . IsEnabled ( LogLevel . Information ) )
940
929
{
941
930
_logger . LogDebug ( "Forcing index {IndexName} to be unlocked since it was left in a locked state" , Name ) ;
942
931
}
932
+
943
933
//unlock it!
944
934
Unlock ( dir ) ;
945
935
}
@@ -962,46 +952,7 @@ private TrackingIndexWriter CreateIndexWriterInternal()
962
952
/// </summary>
963
953
/// <param name="d"></param>
964
954
/// <returns></returns>
965
- protected virtual IndexWriter CreateIndexWriter ( Directory d )
966
- {
967
- if ( d == null )
968
- {
969
- throw new ArgumentNullException ( nameof ( d ) ) ;
970
- }
971
-
972
- var writer = new IndexWriter ( d , new IndexWriterConfig ( LuceneInfo . CurrentVersion , FieldAnalyzer )
973
- {
974
- IndexDeletionPolicy = _options . IndexDeletionPolicy ?? new SnapshotDeletionPolicy ( new KeepOnlyLastCommitDeletionPolicy ( ) ) ,
975
- #if FULLDEBUG
976
-
977
- //If we want to enable logging of lucene output....
978
- //It is also possible to set a default InfoStream on the static IndexWriter class
979
- InfoStream =
980
-
981
- _logOutput ? . Close ( ) ;
982
- if ( LuceneIndexFolder != null )
983
- {
984
- try
985
- {
986
- System . IO . Directory . CreateDirectory ( LuceneIndexFolder . FullName ) ;
987
- _logOutput = new FileStream ( Path . Combine ( LuceneIndexFolder . FullName , DateTime . UtcNow . ToString ( "yyyy-MM-dd" ) + ".log" ) , FileMode . Append ) ;
988
-
989
-
990
- }
991
- catch ( Exception ex )
992
- {
993
- //if an exception is thrown here we won't worry about it, it will mean we cannot create the log file
994
- }
995
- }
996
-
997
- #endif
998
-
999
- MergeScheduler = new ErrorLoggingConcurrentMergeScheduler( Name ,
1000
- ( s , e ) => OnIndexingError ( new IndexingErrorEventArgs ( this , s , "-1" , e ) ) )
1001
- } ) ;
1002
-
1003
- return writer ;
1004
- }
955
+ protected virtual IndexWriter CreateIndexWriter ( Directory d ) => CreateIndexWriterWithOpenMode ( d , OpenMode . CREATE_OR_APPEND ) ;
1005
956
1006
957
/// <summary>
1007
958
/// Gets the TrackingIndexWriter for the current directory
@@ -1025,7 +976,7 @@ public TrackingIndexWriter IndexWriter
1025
976
Monitor . Enter ( _writerLocker ) ;
1026
977
try
1027
978
{
1028
- _writer ??= CreateIndexWriterInternal ( ) ;
979
+ _writer ??= CreateIndexWriterWithLockCheck ( ) ;
1029
980
}
1030
981
finally
1031
982
{
@@ -1042,6 +993,65 @@ public TrackingIndexWriter IndexWriter
1042
993
1043
994
#region Private
1044
995
996
+ private IndexWriter CreateIndexWriterWithOpenMode ( Directory d , OpenMode openMode )
997
+ {
998
+ if ( d == null )
999
+ {
1000
+ throw new ArgumentNullException ( nameof ( d ) ) ;
1001
+ }
1002
+ var writerConfig = new IndexWriterConfig ( LuceneInfo . CurrentVersion , FieldAnalyzer )
1003
+ {
1004
+ IndexDeletionPolicy = _options . IndexDeletionPolicy ?? new SnapshotDeletionPolicy ( new KeepOnlyLastCommitDeletionPolicy ( ) ) ,
1005
+ OpenMode = openMode ,
1006
+
1007
+ //https://solr.apache.org/guide/solr/latest/configuration-guide/index-segments-merging.html#mergepolicyfactory
1008
+ MergePolicy = new TieredMergePolicy
1009
+ {
1010
+ MaxMergeAtOnce = 10 ,
1011
+ SegmentsPerTier = 10 ,
1012
+ ForceMergeDeletesPctAllowed = 10.0f ,
1013
+ MaxMergedSegmentMB = 5000
1014
+ } ,
1015
+ #if FULLDEBUG
1016
+
1017
+ //If we want to enable logging of lucene output....
1018
+ //It is also possible to set a default InfoStream on the static IndexWriter class
1019
+ InfoStream =
1020
+
1021
+ _logOutput ? . Close ( ) ;
1022
+ if ( LuceneIndexFolder != null )
1023
+ {
1024
+ try
1025
+ {
1026
+ System . IO . Directory . CreateDirectory ( LuceneIndexFolder . FullName ) ;
1027
+ _logOutput = new FileStream ( Path . Combine ( LuceneIndexFolder . FullName , DateTime . UtcNow . ToString ( "yyyy-MM-dd" ) + ".log" ) , FileMode . Append ) ;
1028
+
1029
+
1030
+ }
1031
+ catch ( Exception ex )
1032
+ {
1033
+ //if an exception is thrown here we won't worry about it, it will mean we cannot create the log file
1034
+ }
1035
+ }
1036
+
1037
+ #endif
1038
+
1039
+ MergeScheduler = new ErrorLoggingConcurrentMergeScheduler( Name ,
1040
+ ( s , e ) => OnIndexingError ( new IndexingErrorEventArgs ( this , s , "-1" , e ) ) )
1041
+ } ;
1042
+
1043
+ if ( _options . NrtEnabled )
1044
+ {
1045
+ // With NRT, we should apparently use this but there is no real implementation of it!?
1046
+ // https://stackoverflow.com/questions/12271614/lucene-net-indexwriter-setmergedsegmentwarmer
1047
+ writerConfig . MergedSegmentWarmer = new SimpleMergedSegmentWarmer ( new LoggingInfoStream < LuceneIndex > ( _logger ) ) ;
1048
+ }
1049
+
1050
+ var writer = new IndexWriter ( d , writerConfig ) ;
1051
+
1052
+ return writer ;
1053
+ }
1054
+
1045
1055
private LuceneSearcher CreateSearcher ( )
1046
1056
{
1047
1057
var name = Name ;
0 commit comments