io.github.icodegarden.nutrient.lang.NamesCachedObjectReader Maven / Gradle / Ivy
package io.github.icodegarden.nutrient.lang;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.github.icodegarden.nutrient.lang.util.ThreadUtils;
/**
* 只关注给定的names
* 定时获取实时数据,listNamedObjects返回的是缓存数据
* 允许外部通过add remove增删元素,目的是为了保障数据近实时性
* listNamedObjects的name 要在 构造参数names 中
*
* @author Fangfang.Xu
*
*/
public class NamesCachedObjectReader implements NamedObjectReader, Closeable {
private static final Logger log = LoggerFactory.getLogger(NamesCachedObjectReader.class);
private static final long DEFAULT_CACHE_REFRESH_INTERVAL_MILLIS = 10000;
/**
* 每个对象独占1线程
*/
private final ScheduledThreadPoolExecutor scheduleRefreshCacheThreadPool = ThreadUtils
.newSingleScheduledThreadPool("NamesCachedObjectReader-refreshCache");
private final Map> name_objects;
private final Collection names;
private final NamedObjectReader extends NamedObject> delegator;
public NamesCachedObjectReader(Collection names, NamedObjectReader extends NamedObject> delegator) {
this(names, delegator, DEFAULT_CACHE_REFRESH_INTERVAL_MILLIS);
}
public NamesCachedObjectReader(Collection names, NamedObjectReader extends NamedObject> delegator,
long cacheRefreshIntervalMillis) {
if (names == null || names.isEmpty()) {
throw new IllegalArgumentException("names must not empty");
}
if (delegator == null) {
throw new IllegalArgumentException("delegator must not null");
}
this.names = names;
this.delegator = delegator;
name_objects = new HashMap>(names.size(), 1);
for (String name : names) {
name_objects.put(name, new LinkedList());// 允许添加元素
}
scheduleRefreshCacheThreadPool.scheduleWithFixedDelay(() -> {
try {
refreshCache();
} catch (Exception e) {
log.error("WARNING ex on refreshCache", e);
}
}, 0, cacheRefreshIntervalMillis, TimeUnit.MILLISECONDS);
}
void refreshCache() {
for (String name : this.names) {
try {
List extends NamedObject> listNamedObjects = delegator.listNamedObjects(name);
if (!listNamedObjects.isEmpty()) {
name_objects.put(name, listNamedObjects);// 全新替换
}
} catch (Exception e) {
log.error("WARNING ex on refreshCache, name:{}", name, e);
}
}
}
/**
* copy一份保障返回结果线程安全
*/
@Override
public List listNamedObjects(String name) {
if (!names.contains(name)) {
throw new IllegalArgumentException(
String.format("name [%s] not supported, support names were [%s]", name, names));
}
List extends NamedObject> list = name_objects.get(name);
if (list.isEmpty()) {
return Collections.emptyList();
}
return new ArrayList(list);
}
public boolean addObject(NamedObject object) {
List list = (List) name_objects.get(object.name());
if (list != null) {
return list.add(object);
}
return false;
}
public boolean removeObject(NamedObject object) {
List extends NamedObject> list = name_objects.get(object.name());
if (list != null) {
return list.remove(object);
}
return false;
}
/**
* 停止调度
*/
@Override
public void close() throws IOException {
scheduleRefreshCacheThreadPool.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
scheduleRefreshCacheThreadPool.shutdown();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy