All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.icodegarden.commons.lang.query.TableDataCountManager Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
package io.github.icodegarden.commons.lang.query;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.github.icodegarden.commons.lang.util.SystemUtils;
import io.github.icodegarden.commons.lang.util.ThreadPoolUtils;

/**
 * 允许任意组合 Collector 和 Storage
* * 使用 {@link #allowCount(String)} 前需要先调用 {@link #start()}开启调度,否则出异常
* * 如需停止需要调用{@link #stop()}
* * @author Fangfang.Xu * */ public class TableDataCountManager { private static final Logger log = LoggerFactory.getLogger(TableDataCountManager.class); public static final int DEFAULT_ALLOW_COUNT_THRESHOLD = 500000; private Map cache; private final TableDataCountCollector tableCountCollector; private final TableDataCountStorage tableCountStorage; private long allowCountThreshold; private ScheduledFuture future; public TableDataCountManager(TableDataCountCollector tableCountCollector, TableDataCountStorage tableCountStorage) { this(tableCountCollector, tableCountStorage, DEFAULT_ALLOW_COUNT_THRESHOLD); } public TableDataCountManager(TableDataCountCollector tableCountCollector, TableDataCountStorage tableCountStorage, long allowCountThreshold) { this.tableCountCollector = tableCountCollector; this.tableCountStorage = tableCountStorage; this.allowCountThreshold = allowCountThreshold; } public boolean allowCount(String tableName) { if (future == null) { throw new IllegalStateException("schedule is not start, please start it before this."); } refreshCacheIfNull(); Long count = cache.get(tableName); if (count == null) { return true; } return count < allowCountThreshold; } public void start(long initialDelayMillis, long scheduleMillis) { ScheduledThreadPoolExecutor scheduledThreadPool = ThreadPoolUtils .newSingleScheduledThreadPool("TableDataCount-Schedule"); this.future = scheduledThreadPool.scheduleWithFixedDelay(() -> { try { doSchedule(); } catch (Exception e) { log.error("WARN ex on refreshCache", e); } }, initialDelayMillis, scheduleMillis, TimeUnit.MILLISECONDS); } public void stop() { future.cancel(false); future = null; } /** * 缓存中的表缺少,则补充
* 缓存中的count已超过,不再处理;否则更新count值 */ private void doSchedule() { List tables = tableCountCollector.listTables(); refreshCacheIfNull(); for (String table : tables) { Long tableCount = cache.get(table); if (tableCount == null) { // 新增,可能并发 try { create(table); } catch (io.github.icodegarden.commons.lang.query.DuplicateKeyException ignore) { log.info("duplicate table name:{} on table", table); } tableCount = 0L; } if (tableCount < allowCountThreshold) { long count = tableCountCollector.countTable(table); tableCountStorage.updateCount(table, count); cache.put(table, count); } } } private void refreshCacheIfNull() { if (cache == null) { List list = tableCountStorage.findAll(); cache = list.stream() .collect(Collectors.toMap(TableDataCountPO::getTableName, TableDataCountPO::getDataCount)); } } private void create(String tableName) { TableDataCountPO po = new TableDataCountPO(); po.setTableName(tableName); po.setUpdatedAt(SystemUtils.now()); po.setDataCount(0L); tableCountStorage.add(po); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy