package me.hao0.antares.server.cluster.client;
import com.google.common.collect.Maps;
import me.hao0.antares.common.support.Lifecycle;
import me.hao0.antares.common.support.Component;
import me.hao0.antares.common.util.CollectionUtil;
import me.hao0.antares.server.schedule.JobPool;
import me.hao0.antares.store.support.AntaresZkClient;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Author: haolin
* Email: haolin.h0@gmail.com
*/
@org.springframework.stereotype.Component
public class ClientCluster extends Component implements Lifecycle, InitializingBean, DisposableBean {
@Autowired
private JobPool jobPool;
@Autowired
private AntaresZkClient zk;
/**
* The apps's clients cluster: <appName, AppClientCluster>
*/
private final Map<String, AppClientCluster> appsClients = Maps.newConcurrentMap();
private final ConcurrentHashMap<String, AppClientChangedListener> listeners = new ConcurrentHashMap<>();
public void addListener(String id, AppClientChangedListener listener) {
this.listeners.putIfAbsent(id, listener);
}
public void removeListener(String id){
this.listeners.remove(id);
}
@Override
public void afterPropertiesSet() throws Exception {
start();
}
@Override
public void destroy() throws Exception {
shutdown();
}
@Override
public void doStart() {
// init client cluster
List<String> apps = jobPool.getApps();
if (!CollectionUtil.isNullOrEmpty(apps)){
for (String app : apps){
createAppClientCluster(app);
}
}
}
@Override
public void doShutdown() {
if (!appsClients.isEmpty()){
for (AppClientCluster clientCluster : appsClients.values()){
clientCluster.shutdown();
}
}
}
protected AppClientCluster createAppClientCluster(String appName) {
AppClientCluster exist = appsClients.get(appName);
if (exist == null){
exist = new AppClientCluster(zk, appName) {
@Override
public void onClientChanged(String appName, String client, Boolean join) {
if (!listeners.isEmpty()){
for (AppClientChangedListener listener : listeners.values()){
listener.onChanged(appName, client, join);
}
}
}
};
exist.start();
appsClients.put(appName, exist);
}
return exist;
}
/**
* Whether the app has alive clients or not
* @param appName the app name
* @return return true if has clients, or false
*/
public Boolean hasAliveClients(String appName){
return !CollectionUtil.isNullOrEmpty(getAliveClients(appName));
}
/**
* Get the alive clients of the app
* @param appName the app name
* @return the alive clients of the app
*/
public List<String> getAliveClients(String appName){
AppClientCluster appClientCluster = appsClients.get(appName);
if (appClientCluster == null){
appClientCluster = createAppClientCluster(appName);
}
return appClientCluster.alives();
}
}