Search in sources :

Example 11 with CachedFileInfo

use of org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo in project bookkeeper by apache.

the class TestFileInfoBackingCache method testForDeadlocks.

/**
 * Of course this can't prove they don't exist, but
 * try to shake them out none the less.
 */
@Test
public void testForDeadlocks() throws Exception {
    int numRunners = 20;
    int maxLedgerId = 10;
    AtomicBoolean done = new AtomicBoolean(false);
    FileInfoBackingCache cache = new FileInfoBackingCache((ledgerId, createIfNotFound) -> {
        File f = new File(baseDir, String.valueOf(ledgerId));
        f.deleteOnExit();
        return f;
    });
    Iterable<Future<Set<CachedFileInfo>>> futures = IntStream.range(0, numRunners).mapToObj((i) -> {
        Callable<Set<CachedFileInfo>> c = () -> {
            Random r = new Random();
            List<CachedFileInfo> fileInfos = new ArrayList<>();
            Set<CachedFileInfo> allFileInfos = new HashSet<>();
            while (!done.get()) {
                if (r.nextBoolean() && fileInfos.size() < 5) {
                    // take a reference
                    CachedFileInfo fi = cache.loadFileInfo(r.nextInt(maxLedgerId), masterKey);
                    Assert.assertFalse(fi.isClosed());
                    allFileInfos.add(fi);
                    fileInfos.add(fi);
                } else {
                    // release a reference
                    Collections.shuffle(fileInfos);
                    if (!fileInfos.isEmpty()) {
                        fileInfos.remove(0).release();
                    }
                }
            }
            for (CachedFileInfo fi : fileInfos) {
                Assert.assertFalse(fi.isClosed());
                fi.release();
            }
            return allFileInfos;
        };
        return executor.submit(c);
    }).collect(Collectors.toList());
    Thread.sleep(TimeUnit.SECONDS.toMillis(10));
    done.set(true);
    // ensure all threads are finished operating on cache, before checking any
    for (Future<Set<CachedFileInfo>> f : futures) {
        f.get();
    }
    for (Future<Set<CachedFileInfo>> f : futures) {
        for (CachedFileInfo fi : f.get()) {
            Assert.assertTrue(fi.isClosed());
            Assert.assertEquals(FileInfoBackingCache.DEAD_REF, fi.getRefCount());
        }
    }
    // They should be loaded fresh (i.e. this load should be only reference)
    for (int i = 0; i < maxLedgerId; i++) {
        Assert.assertEquals(1, cache.loadFileInfo(i, masterKey).getRefCount());
    }
}
Also used : ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) IntStream(java.util.stream.IntStream) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Random(java.util.Random) Callable(java.util.concurrent.Callable) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Future(java.util.concurrent.Future) After(org.junit.After) ThreadFactory(java.util.concurrent.ThreadFactory) ExecutorService(java.util.concurrent.ExecutorService) Before(org.junit.Before) RemovalNotification(com.google.common.cache.RemovalNotification) LongStream(java.util.stream.LongStream) Set(java.util.Set) IOException(java.io.IOException) Test(org.junit.Test) Collectors(java.util.stream.Collectors) File(java.io.File) Executors(java.util.concurrent.Executors) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) CacheBuilder(com.google.common.cache.CacheBuilder) Cache(com.google.common.cache.Cache) Assert(org.junit.Assert) Collections(java.util.Collections) CachedFileInfo(org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo) HashSet(java.util.HashSet) Set(java.util.Set) ArrayList(java.util.ArrayList) Callable(java.util.concurrent.Callable) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CachedFileInfo(org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo) Random(java.util.Random) Future(java.util.concurrent.Future) File(java.io.File) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 12 with CachedFileInfo

use of org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo in project bookkeeper by apache.

the class TestFileInfoBackingCache method testRaceGuavaEvictAndReleaseBeforeRetain.

@Test
public void testRaceGuavaEvictAndReleaseBeforeRetain() throws Exception {
    AtomicBoolean done = new AtomicBoolean(false);
    FileInfoBackingCache cache = new FileInfoBackingCache((ledgerId, createIfNotFound) -> {
        File f = new File(baseDir, String.valueOf(ledgerId));
        f.deleteOnExit();
        return f;
    });
    Cache<Long, CachedFileInfo> guavaCache = CacheBuilder.newBuilder().maximumSize(1).removalListener(this::guavaEvictionListener).build();
    Iterable<Future<Set<CachedFileInfo>>> futures = LongStream.range(0L, 2L).mapToObj((i) -> {
        Callable<Set<CachedFileInfo>> c = () -> {
            Set<CachedFileInfo> allFileInfos = new HashSet<>();
            while (!done.get()) {
                CachedFileInfo fi = null;
                do {
                    fi = guavaCache.get(i, () -> cache.loadFileInfo(i, masterKey));
                    allFileInfos.add(fi);
                    Thread.sleep(100);
                } while (!fi.tryRetain());
                Assert.assertFalse(fi.isClosed());
                fi.release();
            }
            return allFileInfos;
        };
        return executor.submit(c);
    }).collect(Collectors.toList());
    Thread.sleep(TimeUnit.SECONDS.toMillis(10));
    done.set(true);
    // ensure all threads are finished operating on cache, before checking any
    for (Future<Set<CachedFileInfo>> f : futures) {
        f.get();
    }
    guavaCache.invalidateAll();
    for (Future<Set<CachedFileInfo>> f : futures) {
        for (CachedFileInfo fi : f.get()) {
            Assert.assertTrue(fi.isClosed());
            Assert.assertEquals(FileInfoBackingCache.DEAD_REF, fi.getRefCount());
        }
    }
}
Also used : ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) IntStream(java.util.stream.IntStream) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Random(java.util.Random) Callable(java.util.concurrent.Callable) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Future(java.util.concurrent.Future) After(org.junit.After) ThreadFactory(java.util.concurrent.ThreadFactory) ExecutorService(java.util.concurrent.ExecutorService) Before(org.junit.Before) RemovalNotification(com.google.common.cache.RemovalNotification) LongStream(java.util.stream.LongStream) Set(java.util.Set) IOException(java.io.IOException) Test(org.junit.Test) Collectors(java.util.stream.Collectors) File(java.io.File) Executors(java.util.concurrent.Executors) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) CacheBuilder(com.google.common.cache.CacheBuilder) Cache(com.google.common.cache.Cache) Assert(org.junit.Assert) Collections(java.util.Collections) CachedFileInfo(org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo) HashSet(java.util.HashSet) Set(java.util.Set) Callable(java.util.concurrent.Callable) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CachedFileInfo(org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo) Future(java.util.concurrent.Future) File(java.io.File) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 13 with CachedFileInfo

use of org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo in project bookkeeper by apache.

the class TestFileInfoBackingCache method basicTest.

@Test
public void basicTest() throws Exception {
    FileInfoBackingCache cache = new FileInfoBackingCache((ledgerId, createIfNotFound) -> {
        File f = new File(baseDir, String.valueOf(ledgerId));
        f.deleteOnExit();
        return f;
    });
    CachedFileInfo fi = cache.loadFileInfo(1, masterKey);
    Assert.assertEquals(fi.getRefCount(), 1);
    CachedFileInfo fi2 = cache.loadFileInfo(2, masterKey);
    Assert.assertEquals(fi2.getRefCount(), 1);
    CachedFileInfo fi3 = cache.loadFileInfo(1, null);
    Assert.assertEquals(fi, fi3);
    Assert.assertEquals(fi3.getRefCount(), 2);
    // check that it expires correctly
    fi.release();
    fi3.release();
    Assert.assertEquals(fi.getRefCount(), FileInfoBackingCache.DEAD_REF);
    CachedFileInfo fi4 = cache.loadFileInfo(1, null);
    Assert.assertFalse(fi4 == fi);
    Assert.assertEquals(fi.getRefCount(), FileInfoBackingCache.DEAD_REF);
    Assert.assertEquals(fi4.getRefCount(), 1);
    Assert.assertEquals(fi.getLf(), fi4.getLf());
}
Also used : CachedFileInfo(org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo) File(java.io.File) Test(org.junit.Test)

Example 14 with CachedFileInfo

use of org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo in project bookkeeper by apache.

the class IndexPersistenceMgr method updatePage.

/**
 * Update the ledger entry page.
 *
 * @param lep
 *          ledger entry page
 * @return true if it is a new page, otherwise false.
 * @throws IOException
 */
boolean updatePage(LedgerEntryPage lep) throws IOException {
    if (!lep.isClean()) {
        throw new IOException("Trying to update a dirty page");
    }
    CachedFileInfo fi = null;
    try {
        fi = getFileInfo(lep.getLedger(), null);
        long pos = lep.getFirstEntryPosition();
        if (pos >= fi.size()) {
            lep.zeroPage();
            return true;
        } else {
            lep.readPage(fi);
            return false;
        }
    } finally {
        if (fi != null) {
            fi.release();
        }
    }
}
Also used : CachedFileInfo(org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo) IOException(java.io.IOException)

Example 15 with CachedFileInfo

use of org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo in project bookkeeper by apache.

the class IndexPersistenceMgr method removeLedger.

/**
 * This method is called whenever a ledger is deleted by the BookKeeper Client
 * and we want to remove all relevant data for it stored in the LedgerCache.
 */
void removeLedger(Long ledgerId) throws IOException {
    // Delete the ledger's index file and close the FileInfo
    CachedFileInfo fi = null;
    try {
        fi = getFileInfo(ledgerId, null);
        // Don't force flush. There's no need since we're deleting the ledger
        // anyway, and recreating the file at this point, although safe, will
        // force the garbage collector to do more work later.
        fi.close(false);
        fi.delete();
    } finally {
        if (fi != null) {
            // should release use count
            fi.release();
            // Remove it from the active ledger manager
            activeLedgers.remove(ledgerId);
            // Now remove it from cache
            writeFileInfoCache.invalidate(ledgerId);
            readFileInfoCache.invalidate(ledgerId);
        }
    }
}
Also used : CachedFileInfo(org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo)

Aggregations

CachedFileInfo (org.apache.bookkeeper.bookie.FileInfoBackingCache.CachedFileInfo)17 Test (org.junit.Test)9 File (java.io.File)6 IOException (java.io.IOException)5 After (org.junit.After)4 Before (org.junit.Before)4 Cache (com.google.common.cache.Cache)3 CacheBuilder (com.google.common.cache.CacheBuilder)3 RemovalNotification (com.google.common.cache.RemovalNotification)3 ThreadFactoryBuilder (com.google.common.util.concurrent.ThreadFactoryBuilder)3 ArrayList (java.util.ArrayList)3 Collections (java.util.Collections)3 HashSet (java.util.HashSet)3 List (java.util.List)3 Random (java.util.Random)3 Set (java.util.Set)3 Callable (java.util.concurrent.Callable)3 ExecutorService (java.util.concurrent.ExecutorService)3 Executors (java.util.concurrent.Executors)3 Future (java.util.concurrent.Future)3