mirror of https://github.com/longtai-cn/hippo4j
parent
3cf2bbc988
commit
5cf3009db9
@ -0,0 +1,135 @@
|
||||
package com.github.dynamic.threadpool.common.model;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Instance Info.
|
||||
*
|
||||
* @author chen.ma
|
||||
* @date 2021/7/13 22:10
|
||||
*/
|
||||
@Slf4j
|
||||
@Getter
|
||||
@Setter
|
||||
public class InstanceInfo {
|
||||
|
||||
private static final String UNKNOWN = "unknown";
|
||||
|
||||
private String appName = UNKNOWN;
|
||||
|
||||
private String hostName;
|
||||
|
||||
private String instanceId;
|
||||
|
||||
private volatile String vipAddress;
|
||||
|
||||
private volatile String secureVipAddress;
|
||||
|
||||
private volatile ActionType actionType;
|
||||
|
||||
private volatile boolean isInstanceInfoDirty = false;
|
||||
|
||||
private volatile Long lastUpdatedTimestamp;
|
||||
|
||||
private volatile Long lastDirtyTimestamp;
|
||||
|
||||
private volatile InstanceStatus status = InstanceStatus.UP;
|
||||
|
||||
private volatile InstanceStatus overriddenStatus = InstanceStatus.UNKNOWN;
|
||||
|
||||
public InstanceInfo() {
|
||||
this.lastUpdatedTimestamp = System.currentTimeMillis();
|
||||
this.lastDirtyTimestamp = lastUpdatedTimestamp;
|
||||
}
|
||||
|
||||
public void setLastUpdatedTimestamp() {
|
||||
this.lastUpdatedTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public Long getLastDirtyTimestamp() {
|
||||
return lastDirtyTimestamp;
|
||||
}
|
||||
|
||||
public synchronized void setOverriddenStatus(InstanceStatus status) {
|
||||
if (this.overriddenStatus != status) {
|
||||
this.overriddenStatus = status;
|
||||
}
|
||||
}
|
||||
|
||||
public InstanceStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public synchronized void setIsDirty() {
|
||||
isInstanceInfoDirty = true;
|
||||
lastDirtyTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public synchronized long setIsDirtyWithTime() {
|
||||
setIsDirty();
|
||||
return lastDirtyTimestamp;
|
||||
}
|
||||
|
||||
public synchronized void unsetIsDirty(long unsetDirtyTimestamp) {
|
||||
if (lastDirtyTimestamp <= unsetDirtyTimestamp) {
|
||||
isInstanceInfoDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setActionType(ActionType actionType) {
|
||||
this.actionType = actionType;
|
||||
}
|
||||
|
||||
public enum InstanceStatus {
|
||||
|
||||
UP,
|
||||
|
||||
DOWN,
|
||||
|
||||
STARTING,
|
||||
|
||||
OUT_OF_SERVICE,
|
||||
|
||||
UNKNOWN;
|
||||
|
||||
public static InstanceStatus toEnum(String s) {
|
||||
if (s != null) {
|
||||
try {
|
||||
return InstanceStatus.valueOf(s.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
// ignore and fall through to unknown
|
||||
log.debug("illegal argument supplied to InstanceStatus.valueOf: {}, defaulting to {}", s, UNKNOWN);
|
||||
}
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ActionType {
|
||||
ADDED,
|
||||
|
||||
MODIFIED,
|
||||
|
||||
DELETED
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class InstanceRenew {
|
||||
|
||||
private String appName;
|
||||
|
||||
private String instanceId;
|
||||
|
||||
private String lastDirtyTimestamp;
|
||||
|
||||
private String status;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package com.github.dynamic.threadpool.registry.config;
|
||||
|
||||
import com.github.dynamic.threadpool.registry.core.BaseInstanceRegistry;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* Registry Configuration.
|
||||
*
|
||||
* @author chen.ma
|
||||
* @date 2021/8/12 21:48
|
||||
*/
|
||||
@Configuration
|
||||
public class RegistryConfiguration {
|
||||
|
||||
@Autowired
|
||||
private BaseInstanceRegistry baseInstanceRegistry;
|
||||
|
||||
@PostConstruct
|
||||
public void registryInit() {
|
||||
baseInstanceRegistry.postInit();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.github.dynamic.threadpool.registry.controller;
|
||||
|
||||
import com.github.dynamic.threadpool.common.model.InstanceInfo;
|
||||
import com.github.dynamic.threadpool.common.web.base.Result;
|
||||
import com.github.dynamic.threadpool.common.web.base.Results;
|
||||
import com.github.dynamic.threadpool.common.web.exception.ErrorCodeEnum;
|
||||
import com.github.dynamic.threadpool.registry.core.InstanceRegistry;
|
||||
import com.github.dynamic.threadpool.registry.core.Lease;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.github.dynamic.threadpool.common.constant.Constants.BASE_PATH;
|
||||
|
||||
/**
|
||||
* Application Controller.
|
||||
*
|
||||
* @author chen.ma
|
||||
* @date 2021/8/8 22:24
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping(BASE_PATH + "/apps")
|
||||
public class ApplicationController {
|
||||
|
||||
@NonNull
|
||||
private final InstanceRegistry instanceRegistry;
|
||||
|
||||
@GetMapping("/{appName}")
|
||||
public Result applications(@PathVariable String appName) {
|
||||
List<Lease<InstanceInfo>> resultInstanceList = instanceRegistry.listInstance(appName);
|
||||
return Results.success(resultInstanceList);
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
public Result addInstance(@RequestBody InstanceInfo instanceInfo) {
|
||||
instanceRegistry.register(instanceInfo);
|
||||
return Results.success();
|
||||
}
|
||||
|
||||
@PostMapping("/renew")
|
||||
public Result renew(@RequestBody InstanceInfo.InstanceRenew instanceRenew) {
|
||||
boolean isSuccess = instanceRegistry.renew(instanceRenew);
|
||||
if (!isSuccess) {
|
||||
log.warn("Not Found (Renew) :: {} - {}", instanceRenew.getAppName(), instanceRenew.getInstanceId());
|
||||
return Results.failure(ErrorCodeEnum.NOT_FOUND);
|
||||
}
|
||||
return Results.success();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,289 @@
|
||||
package com.github.dynamic.threadpool.registry.core;
|
||||
|
||||
import com.github.dynamic.threadpool.common.model.InstanceInfo;
|
||||
import com.github.dynamic.threadpool.common.model.InstanceInfo.InstanceStatus;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import static com.github.dynamic.threadpool.common.constant.Constants.EVICTION_INTERVAL_TIMER_IN_MS;
|
||||
import static com.github.dynamic.threadpool.common.constant.Constants.SCHEDULED_THREAD_CORE_NUM;
|
||||
|
||||
/**
|
||||
* Base Instance Registry.
|
||||
*
|
||||
* @author chen.ma
|
||||
* @date 2021/8/8 22:46
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class BaseInstanceRegistry implements InstanceRegistry<InstanceInfo> {
|
||||
|
||||
private final int CONTAINER_SIZE = 1024;
|
||||
|
||||
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
|
||||
|
||||
private final Lock read = readWriteLock.readLock();
|
||||
|
||||
protected final Object lock = new Object();
|
||||
|
||||
private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry = new ConcurrentHashMap(CONTAINER_SIZE);
|
||||
|
||||
protected volatile int expectedNumberOfClientsSendingRenews;
|
||||
|
||||
private final CircularQueue<Pair<Long, String>> recentRegisteredQueue;
|
||||
|
||||
private final CircularQueue<Pair<Long, String>> recentCanceledQueue;
|
||||
|
||||
private ConcurrentLinkedQueue<RecentlyChangedItem> recentlyChangedQueue = new ConcurrentLinkedQueue();
|
||||
|
||||
protected final ConcurrentMap<String, InstanceStatus> overriddenInstanceStatusMap = CacheBuilder
|
||||
.newBuilder().initialCapacity(512)
|
||||
.expireAfterAccess(1, TimeUnit.HOURS)
|
||||
.<String, InstanceStatus>build().asMap();
|
||||
|
||||
public BaseInstanceRegistry() {
|
||||
this.recentRegisteredQueue = new CircularQueue(CONTAINER_SIZE);
|
||||
this.recentCanceledQueue = new CircularQueue(CONTAINER_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Lease<InstanceInfo>> listInstance(String appName) {
|
||||
Map<String, Lease<InstanceInfo>> appNameLeaseMap = registry.get(appName);
|
||||
if (CollectionUtils.isEmpty(appNameLeaseMap)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
|
||||
List<Lease<InstanceInfo>> appNameLeaseList = Lists.newArrayList();
|
||||
appNameLeaseMap.values().forEach(each -> appNameLeaseList.add(each));
|
||||
return appNameLeaseList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(InstanceInfo registrant) {
|
||||
read.lock();
|
||||
try {
|
||||
Map<String, Lease<InstanceInfo>> registerMap = registry.get(registrant.getAppName());
|
||||
if (registerMap == null) {
|
||||
ConcurrentHashMap<String, Lease<InstanceInfo>> registerNewMap = new ConcurrentHashMap(12);
|
||||
registerMap = registry.putIfAbsent(registrant.getAppName(), registerNewMap);
|
||||
if (registerMap == null) {
|
||||
registerMap = registerNewMap;
|
||||
}
|
||||
}
|
||||
|
||||
Lease<InstanceInfo> existingLease = registerMap.get(registrant.getInstanceId());
|
||||
if (existingLease != null && (existingLease.getHolder() != null)) {
|
||||
Long existingLastDirtyTimestamp = existingLease.getHolder().getLastDirtyTimestamp();
|
||||
Long registrationLastDirtyTimestamp = registrant.getLastDirtyTimestamp();
|
||||
|
||||
if (existingLastDirtyTimestamp > registrationLastDirtyTimestamp) {
|
||||
registrant = existingLease.getHolder();
|
||||
}
|
||||
}
|
||||
|
||||
Lease<InstanceInfo> lease = new Lease(registrant);
|
||||
if (existingLease != null) {
|
||||
lease.setServiceUpTimestamp(existingLease.getServiceUpTimestamp());
|
||||
}
|
||||
registerMap.put(registrant.getInstanceId(), lease);
|
||||
|
||||
recentRegisteredQueue.add(new Pair(
|
||||
System.currentTimeMillis(),
|
||||
registrant.getAppName() + "(" + registrant.getInstanceId() + ")"));
|
||||
|
||||
InstanceStatus overriddenStatusFromMap = overriddenInstanceStatusMap.get(registrant.getInstanceId());
|
||||
if (overriddenStatusFromMap != null) {
|
||||
log.info("Storing overridden status :: {} from map", overriddenStatusFromMap);
|
||||
registrant.setOverriddenStatus(overriddenStatusFromMap);
|
||||
}
|
||||
|
||||
if (InstanceStatus.UP.equals(registrant.getStatus())) {
|
||||
lease.serviceUp();
|
||||
}
|
||||
|
||||
registrant.setActionType(InstanceInfo.ActionType.ADDED);
|
||||
recentlyChangedQueue.add(new RecentlyChangedItem(lease));
|
||||
registrant.setLastUpdatedTimestamp();
|
||||
} finally {
|
||||
read.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renew(InstanceInfo.InstanceRenew instanceRenew) {
|
||||
String appName = instanceRenew.getAppName();
|
||||
String instanceId = instanceRenew.getInstanceId();
|
||||
|
||||
Map<String, Lease<InstanceInfo>> registryMap = registry.get(appName);
|
||||
Lease<InstanceInfo> leaseToRenew = null;
|
||||
if (registryMap == null || (leaseToRenew = registryMap.get(instanceId)) == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
leaseToRenew.renew();
|
||||
return true;
|
||||
}
|
||||
|
||||
static class CircularQueue<E> extends AbstractQueue<E> {
|
||||
|
||||
private final ArrayBlockingQueue<E> delegate;
|
||||
|
||||
public CircularQueue(int capacity) {
|
||||
this.delegate = new ArrayBlockingQueue(capacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return delegate.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return delegate.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offer(E e) {
|
||||
while (!delegate.offer(e)) {
|
||||
delegate.poll();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E poll() {
|
||||
return delegate.poll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peek() {
|
||||
return delegate.peek();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
delegate.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return delegate.toArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class RecentlyChangedItem {
|
||||
private long lastUpdateTime;
|
||||
|
||||
private Lease<InstanceInfo> leaseInfo;
|
||||
|
||||
public RecentlyChangedItem(Lease<InstanceInfo> lease) {
|
||||
this.leaseInfo = lease;
|
||||
lastUpdateTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public long getLastUpdateTime() {
|
||||
return this.lastUpdateTime;
|
||||
}
|
||||
|
||||
public Lease<InstanceInfo> getLeaseInfo() {
|
||||
return this.leaseInfo;
|
||||
}
|
||||
}
|
||||
|
||||
public void evict(long additionalLeaseMs) {
|
||||
List<Lease<InstanceInfo>> expiredLeases = new ArrayList();
|
||||
for (Map.Entry<String, Map<String, Lease<InstanceInfo>>> groupEntry : registry.entrySet()) {
|
||||
Map<String, Lease<InstanceInfo>> leaseMap = groupEntry.getValue();
|
||||
if (leaseMap != null) {
|
||||
for (Map.Entry<String, Lease<InstanceInfo>> leaseEntry : leaseMap.entrySet()) {
|
||||
Lease<InstanceInfo> lease = leaseEntry.getValue();
|
||||
if (lease.isExpired(additionalLeaseMs) && lease.getHolder() != null) {
|
||||
expiredLeases.add(lease);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Lease<InstanceInfo> expiredLease : expiredLeases) {
|
||||
String appName = expiredLease.getHolder().getAppName();
|
||||
String id = expiredLease.getHolder().getInstanceId();
|
||||
internalCancel(appName, id, false);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean internalCancel(String appName, String id, boolean isReplication) {
|
||||
read.lock();
|
||||
try {
|
||||
Map<String, Lease<InstanceInfo>> registerMap = registry.get(appName);
|
||||
if (!CollectionUtils.isEmpty(registerMap)) {
|
||||
registerMap.remove(id);
|
||||
}
|
||||
} finally {
|
||||
read.unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public class EvictionTask extends TimerTask {
|
||||
|
||||
private final AtomicLong lastExecutionNanosRef = new AtomicLong(0L);
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
long compensationTimeMs = getCompensationTimeMs();
|
||||
log.info("Running the evict task with compensationTime {} ms", compensationTimeMs);
|
||||
evict(compensationTimeMs);
|
||||
} catch (Throwable e) {
|
||||
log.error("Could not run the evict task", e);
|
||||
}
|
||||
}
|
||||
|
||||
long getCompensationTimeMs() {
|
||||
long currNanos = getCurrentTimeNano();
|
||||
long lastNanos = lastExecutionNanosRef.getAndSet(currNanos);
|
||||
if (lastNanos == 0L) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
long elapsedMs = TimeUnit.NANOSECONDS.toMillis(currNanos - lastNanos);
|
||||
long compensationTime = elapsedMs - EVICTION_INTERVAL_TIMER_IN_MS;
|
||||
return compensationTime <= 0L ? 0L : compensationTime;
|
||||
}
|
||||
|
||||
long getCurrentTimeNano() {
|
||||
return System.nanoTime();
|
||||
}
|
||||
}
|
||||
|
||||
private final ScheduledExecutorService scheduledExecutorService =
|
||||
new ScheduledThreadPoolExecutor(
|
||||
SCHEDULED_THREAD_CORE_NUM,
|
||||
new ThreadFactoryBuilder()
|
||||
.setNameFormat("registry-eviction")
|
||||
.setDaemon(true)
|
||||
.build()
|
||||
);
|
||||
|
||||
private final AtomicReference<EvictionTask> evictionTaskRef = new AtomicReference();
|
||||
|
||||
public void postInit() {
|
||||
evictionTaskRef.set(new BaseInstanceRegistry.EvictionTask());
|
||||
scheduledExecutorService.scheduleWithFixedDelay(evictionTaskRef.get(),
|
||||
EVICTION_INTERVAL_TIMER_IN_MS, EVICTION_INTERVAL_TIMER_IN_MS, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.github.dynamic.threadpool.registry.core;
|
||||
|
||||
import com.github.dynamic.threadpool.common.model.InstanceInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Instance Registry.
|
||||
*
|
||||
* @author chen.ma
|
||||
* @date 2021/8/8 22:31
|
||||
*/
|
||||
public interface InstanceRegistry<T> {
|
||||
|
||||
/**
|
||||
* list Instance.
|
||||
*
|
||||
* @param appName
|
||||
* @return
|
||||
*/
|
||||
List<Lease<T>> listInstance(String appName);
|
||||
|
||||
/**
|
||||
* register.
|
||||
*
|
||||
* @param info
|
||||
*/
|
||||
void register(T info);
|
||||
|
||||
/**
|
||||
* renew.
|
||||
*
|
||||
* @param instanceRenew
|
||||
* @return
|
||||
*/
|
||||
boolean renew(InstanceInfo.InstanceRenew instanceRenew);
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.github.dynamic.threadpool.registry.core;
|
||||
|
||||
/**
|
||||
* Lease.
|
||||
*
|
||||
* @author chen.ma
|
||||
* @date 2021/8/8 22:49
|
||||
*/
|
||||
public class Lease<T> {
|
||||
|
||||
enum Action {
|
||||
REGISTER, CANCEL, RENEW
|
||||
}
|
||||
|
||||
private T holder;
|
||||
|
||||
private long evictionTimestamp;
|
||||
|
||||
private long registrationTimestamp;
|
||||
|
||||
private long serviceUpTimestamp;
|
||||
|
||||
/**
|
||||
* Make it volatile so that the expiration task would see this quicker
|
||||
*/
|
||||
private volatile long lastUpdateTimestamp;
|
||||
|
||||
private long duration;
|
||||
|
||||
public static final int DEFAULT_DURATION_IN_SECS = 90;
|
||||
|
||||
public Lease(T r) {
|
||||
holder = r;
|
||||
registrationTimestamp = System.currentTimeMillis();
|
||||
lastUpdateTimestamp = registrationTimestamp;
|
||||
duration = DEFAULT_DURATION_IN_SECS * 1000;
|
||||
}
|
||||
|
||||
public void renew() {
|
||||
lastUpdateTimestamp = System.currentTimeMillis() + duration;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
if (evictionTimestamp <= 0) {
|
||||
evictionTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
public void serviceUp() {
|
||||
if (serviceUpTimestamp == 0) {
|
||||
serviceUpTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
public void setServiceUpTimestamp(long serviceUpTimestamp) {
|
||||
this.serviceUpTimestamp = serviceUpTimestamp;
|
||||
}
|
||||
|
||||
public boolean isExpired() {
|
||||
return isExpired(0L);
|
||||
}
|
||||
|
||||
public boolean isExpired(long additionalLeaseMs) {
|
||||
return (evictionTimestamp > 0 || System.currentTimeMillis() > (lastUpdateTimestamp + duration + additionalLeaseMs));
|
||||
}
|
||||
|
||||
public long getRegistrationTimestamp() {
|
||||
return registrationTimestamp;
|
||||
}
|
||||
|
||||
public long getLastRenewalTimestamp() {
|
||||
return lastUpdateTimestamp;
|
||||
}
|
||||
|
||||
public long getEvictionTimestamp() {
|
||||
return evictionTimestamp;
|
||||
}
|
||||
|
||||
public long getServiceUpTimestamp() {
|
||||
return serviceUpTimestamp;
|
||||
}
|
||||
|
||||
public T getHolder() {
|
||||
return holder;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.github.dynamic.threadpool.registry.core;
|
||||
|
||||
/**
|
||||
* Pair.
|
||||
*
|
||||
* @author chen.ma
|
||||
* @date 2021/8/8 23:04
|
||||
*/
|
||||
public class Pair<E1, E2> {
|
||||
|
||||
public E1 first() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public void setFirst(E1 first) {
|
||||
this.first = first;
|
||||
}
|
||||
|
||||
public E2 second() {
|
||||
return second;
|
||||
}
|
||||
|
||||
public void setSecond(E2 second) {
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
private E1 first;
|
||||
|
||||
private E2 second;
|
||||
|
||||
public Pair(E1 first, E2 second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.github.dynamic.threadpool.registry.core;
|
||||
|
||||
import com.github.dynamic.threadpool.common.model.InstanceInfo.InstanceStatus;
|
||||
|
||||
/**
|
||||
* Status Override Result.
|
||||
*
|
||||
* @author chen.ma
|
||||
* @date 2021/8/8 23:11
|
||||
*/
|
||||
public class StatusOverrideResult {
|
||||
|
||||
public static StatusOverrideResult NO_MATCH = new StatusOverrideResult(false, null);
|
||||
|
||||
public static StatusOverrideResult matchingStatus(InstanceStatus status) {
|
||||
return new StatusOverrideResult(true, status);
|
||||
}
|
||||
|
||||
private final boolean matches;
|
||||
|
||||
private final InstanceStatus status;
|
||||
|
||||
private StatusOverrideResult(boolean matches, InstanceStatus status) {
|
||||
this.matches = matches;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public boolean matches() {
|
||||
return matches;
|
||||
}
|
||||
|
||||
public InstanceStatus status() {
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package com.github.dynamic.threadpool.starter.core;
|
||||
|
||||
/**
|
||||
* Dynamic thread pool instance configuration.
|
||||
*
|
||||
* @author chen.ma
|
||||
* @date 2021/8/6 21:31
|
||||
*/
|
||||
public interface InstanceConfig {
|
||||
|
||||
/**
|
||||
* get Host Name.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getHostName();
|
||||
|
||||
/**
|
||||
* get Instance Id.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getInstanceId();
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package com.github.dynamic.threadpool.starter.core;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Instance Info.
|
||||
*
|
||||
* @author chen.ma
|
||||
* @date 2021/7/13 22:10
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class InstanceInfo implements InstanceConfig {
|
||||
|
||||
private static final String UNKNOWN = "unknown";
|
||||
|
||||
private String appName = UNKNOWN;
|
||||
|
||||
private String hostName;
|
||||
|
||||
private String instanceId;
|
||||
|
||||
}
|
||||
|
Loading…
Reference in new issue