package com.dianping.puma.portal.db; import com.dianping.lion.client.ConfigCache; import com.google.common.collect.Lists; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @Service public class CommandTableService implements TableService { private final Logger logger = LoggerFactory.getLogger(CommandTableService.class); private final long timeout = 60 * 1000; // 60s. ConfigCache configManager = ConfigCache.getInstance(); @Autowired DatabaseService databaseService; private ConcurrentMap<String, List<String>> tableCache = new ConcurrentHashMap<String, List<String>>(); private ConcurrentMap<String, Date> tableCacheTimes = new ConcurrentHashMap<String, Date>(); @Override public List<String> getTables(String database) { List<String> tables = tableCache.get(database); if (tables != null && !isTimeout(database)) { logger.info("Get cached table infos: {}.", tables); return tables; } else { try { tables = getTablesWithoutCache(database); logger.info("Get real time table infos: {}.", tables); tableCache.put(database, tables); tableCacheTimes.put(database, new Date()); return tables; } catch (SQLException e) { return Lists.newArrayList(); } } } protected List<String> getTablesWithoutCache(String database) throws SQLException { return newQueryRunner(database).query("show tables", new ResultSetHandler<List<String>>() { @Override public List<String> handle(ResultSet rs) throws SQLException { List<String> result = new ArrayList<String>(); while (rs.next()) { String table = rs.getString(1); result.add(table); } return result; } }); } protected QueryRunner newQueryRunner(String database) { ComboPooledDataSource ds = new ComboPooledDataSource(); ds.setJdbcUrl(databaseService.findWriteJdbcUrl(database)); ds.setUser(configManager.getProperty("puma.server.binlog.username")); ds.setPassword(configManager.getProperty("puma.server.binlog.password")); return new QueryRunner(ds); } protected boolean isTimeout(String jdbcUrl) { Date date = tableCacheTimes.get(jdbcUrl); return date == null || new Date().getTime() - date.getTime() > timeout; } }