NightOwl888 commented on code in PR #1138:
URL: https://github.com/apache/lucenenet/pull/1138#discussion_r1988416139


##########
src/Lucene.Net/Store/MMapDirectory.cs:
##########
@@ -314,7 +314,7 @@ internal virtual ByteBuffer[] Map(MMapIndexInput input, 
FileStream fc, long offs
                 input.memoryMappedFile = MemoryMappedFile.CreateFromFile(
                     fileStream: fc,
                     mapName: null,
-                    capacity: length,
+                    capacity: fc.Length, // use the full length of the file

Review Comment:
   I reviewed #1090 and there are a few things that could be contributing to 
the failure. It is specifically testing the file locking functionality and in 
this case there was a failure on Linux.
   
   1. Technically, Linux supports `FileStream.Lock()` which could be changed 
[here](https://github.com/apache/lucenenet/blob/54505e8964c112119b83adf8bf9163d687765cbe/src/Lucene.Net/Store/NativeFSLockFactory.cs#L100-L107),
 however after reading about it on dotnet/runtime and how it is possible to 
bypass the CLR to change it, we went with using the same approach we used on 
macOS, which is to use `SharingNativeFSLock`. We probably could have used 
`FileStream.Lock()` (with `NativeFSLock`) at the time, however, it seems that 
they have changed the native call in .NET 6 so it no longer gets an exclusive 
lock on Linux: https://github.com/dotnet/runtime/issues/64634.
   2. On Windows, the HResult values of IOException are known. However, on all 
other platforms, these values depend on the underlying OS. We determine what 
the value is for the current OS by provoking the exception during static 
initialization and recording the value. There is a non-zero chance that this 
logic could fail to get a value and be set to `null`. When that happens, the 
implementation uses the `FallbackNativeFSLock`, which just does a best effort, 
but is known to have concurrency problems. Note there is some debug code to 
determine the HResult value that was found 
[here](https://github.com/apache/lucenenet/blob/54505e8964c112119b83adf8bf9163d687765cbe/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs#L3184-L3234).
   3. We added a ["hole" in the locking 
implementation](https://github.com/apache/lucenenet/blob/54505e8964c112119b83adf8bf9163d687765cbe/src/Lucene.Net/Store/NativeFSLockFactory.cs#L496-L498)
 specifically so `RAMDirectory` can copy the lock file. This "hole" could cause 
the `SharingNativeFSLock` to fail. Ideally, the `share` setting would always be 
set to `Share.None` to ensure the lock functions properly in all cases. 
However, we would need to find some alternative for `RAMDirectory` to be able 
to copy the contents of the file while there is a lock held on it. This test 
failure could have occurred because the lock failed to throw its exception due 
to using `Share.Read` instead of `Share.None`. It might be worth a try to see 
if `RAMDirectory` can function without the lock file or with a fake lock file 
when copying the contents of the directory.
   
   Detecting the HResult code by provoking the exception is not ideal. Also, 
due to the fact that MS changed the underlying native method for 
`FileStream.Lock()` in .NET 6, it doesn't sound like that is a viable 
alternative any longer on Linux. It may be that dropping to native code is the 
only way to properly solve it on Linux 100% of the time. Note that RavenDB 
changed the implementation to do all index file access using native code 
(including the memory mapped bit and file locking bit). I suspect that we could 
do the file locking in isolation without dropping to native code on everything, 
though.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@lucenenet.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to