jgroups-extras / jgroups-raft

Implementation of the RAFT consensus protocol in JGroups
https://jgroups-extras.github.io/jgroups-raft/
Apache License 2.0
266 stars 84 forks source link

FileBasedLog can't clear VotedFor on Windows OS #295

Closed yfei-z closed 2 months ago

yfei-z commented 3 months ago

On Windows, calling FileChannel.truncate(long) will throw IOException when there is MappedByteBuffer for the same file. I try it in the docker container of Linux(ubi9), seems no problem at all. Here is the test

    @Test
    @EnabledOnOs(OS.WINDOWS)
    void fileLogWin(@TempDir File tmp) throws Exception {
        MetadataStorage storage = new MetadataStorage(tmp, true);
        try {
            storage.open();
            final ExtendedUUID id = new ExtendedUUID();
            storage.setVotedFor(id);
            assertEquals(id, storage.getVotedFor());
            assertThrows(IOException.class, () -> storage.setVotedFor(null)).printStackTrace();
            assertEquals(id, storage.getVotedFor());
        } finally {
            storage.close();
        }
    }

    @Test
    @DisabledOnOs(OS.WINDOWS)
    void fileLog(@TempDir File tmp) throws Exception {
        MetadataStorage storage = new MetadataStorage(tmp, true);
        try {
            storage.open();
            final ExtendedUUID id = new ExtendedUUID();
            storage.setVotedFor(id);
            assertEquals(id, storage.getVotedFor());
            storage.setVotedFor(null);
            assertNull(storage.getVotedFor());
        } finally {
            storage.close();
        }
    }
jabolina commented 3 months ago

This will be a little trickier for me to test. I'll try to set an environment on Windows to check this out (I assume #281 is also something on Windows). Thanks for reporting!

jabolina commented 3 months ago

I was able to run this yesterday. It seems Java in Windows has some safeguards that prevent some operations over files with multiple handles. For example, in truncate, we can't copy the truncated file to the same position as the current file to overwrite it or delete the files at the end of tests because of the mmap in the metadata holding a descriptor.

I have some ideas I'll try to implement next week.