001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.io.hfile.bucket; 019 020import java.io.IOException; 021import java.util.concurrent.atomic.AtomicBoolean; 022import org.apache.yetus.audience.InterfaceAudience; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025 026@InterfaceAudience.Private 027public class BucketCachePersister extends Thread { 028 private final BucketCache cache; 029 private final long intervalMillis; 030 private static final Logger LOG = LoggerFactory.getLogger(BucketCachePersister.class); 031 032 private AtomicBoolean shutdown = new AtomicBoolean(false); 033 034 public BucketCachePersister(BucketCache cache, long intervalMillis) { 035 super("bucket-cache-persister"); 036 this.cache = cache; 037 this.intervalMillis = intervalMillis; 038 LOG.info("BucketCachePersister started with interval: " + intervalMillis); 039 } 040 041 public void run() { 042 try { 043 while (true) { 044 try { 045 Thread.sleep(intervalMillis); 046 if (cache.isCacheInconsistent()) { 047 LOG.debug("Cache is inconsistent, persisting to disk"); 048 cache.persistToFile(); 049 cache.setCacheInconsistent(false); 050 } 051 // Thread.interrupt may cause an InterruptException inside util method used for checksum 052 // calculation in persistToFile. This util currently swallows the exception, causing this 053 // thread to net get interrupt, so we added this flag to indicate the persister thread 054 // should stop. 055 if (shutdown.get()) { 056 break; 057 } 058 } catch (IOException e) { 059 LOG.warn("Exception in BucketCachePersister.", e); 060 } 061 } 062 LOG.info("Finishing cache persister thread."); 063 } catch (InterruptedException e) { 064 LOG.warn("Interrupting BucketCachePersister thread.", e); 065 } catch (Throwable e) { 066 LOG.error("Failed during persisting bucket cache to file: ", e); 067 } 068 } 069 070 public void shutdown() { 071 this.shutdown.set(true); 072 this.interrupt(); 073 } 074}