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

com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService Maven / Gradle / Ivy

There is a newer version: 2.4.2
Show newest version
/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.nacos.client.naming.remote.gprc.redo;

import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.client.env.NacosClientProperties;
import com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy;
import com.alibaba.nacos.client.naming.remote.gprc.redo.data.BatchInstanceRedoData;
import com.alibaba.nacos.client.naming.remote.gprc.redo.data.InstanceRedoData;
import com.alibaba.nacos.client.naming.remote.gprc.redo.data.SubscriberRedoData;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.common.executor.NameThreadFactory;
import com.alibaba.nacos.common.remote.client.Connection;
import com.alibaba.nacos.common.remote.client.ConnectionEventListener;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Naming client gprc redo service.
 *
 * 

When connection reconnect to server, redo the register and subscribe. * * @author xiweng.yy */ public class NamingGrpcRedoService implements ConnectionEventListener { private static final String REDO_THREAD_NAME = "com.alibaba.nacos.client.naming.grpc.redo"; private int redoThreadCount; private long redoDelayTime; private final ConcurrentMap registeredInstances = new ConcurrentHashMap<>(); private final ConcurrentMap subscribes = new ConcurrentHashMap<>(); private final ScheduledExecutorService redoExecutor; private volatile boolean connected = false; public NamingGrpcRedoService(NamingGrpcClientProxy clientProxy, NacosClientProperties properties) { setProperties(properties); this.redoExecutor = new ScheduledThreadPoolExecutor(redoThreadCount, new NameThreadFactory(REDO_THREAD_NAME)); this.redoExecutor.scheduleWithFixedDelay(new RedoScheduledTask(clientProxy, this), redoDelayTime, redoDelayTime, TimeUnit.MILLISECONDS); } private void setProperties(NacosClientProperties properties) { redoDelayTime = properties.getLong(PropertyKeyConst.REDO_DELAY_TIME, Constants.DEFAULT_REDO_DELAY_TIME); redoThreadCount = properties.getInteger(PropertyKeyConst.REDO_DELAY_THREAD_COUNT, Constants.DEFAULT_REDO_THREAD_COUNT); } public ConcurrentMap getRegisteredInstances() { return registeredInstances; } public boolean isConnected() { return connected; } @Override public void onConnected(Connection connection) { connected = true; LogUtils.NAMING_LOGGER.info("Grpc connection connect"); } @Override public void onDisConnect(Connection connection) { connected = false; LogUtils.NAMING_LOGGER.warn("Grpc connection disconnect, mark to redo"); synchronized (registeredInstances) { registeredInstances.values().forEach(instanceRedoData -> instanceRedoData.setRegistered(false)); } synchronized (subscribes) { subscribes.values().forEach(subscriberRedoData -> subscriberRedoData.setRegistered(false)); } LogUtils.NAMING_LOGGER.warn("mark to redo completed"); } /** * Cache registered instance for redo. * * @param serviceName service name * @param groupName group name * @param instance registered instance */ public void cacheInstanceForRedo(String serviceName, String groupName, Instance instance) { String key = NamingUtils.getGroupedName(serviceName, groupName); InstanceRedoData redoData = InstanceRedoData.build(serviceName, groupName, instance); synchronized (registeredInstances) { registeredInstances.put(key, redoData); } } /** * Cache registered instance for redo. * * @param serviceName service name * @param groupName group name * @param instances batch registered instance */ public void cacheInstanceForRedo(String serviceName, String groupName, List instances) { String key = NamingUtils.getGroupedName(serviceName, groupName); BatchInstanceRedoData redoData = BatchInstanceRedoData.build(serviceName, groupName, instances); synchronized (registeredInstances) { registeredInstances.put(key, redoData); } } /** * Instance register successfully, mark registered status as {@code true}. * * @param serviceName service name * @param groupName group name */ public void instanceRegistered(String serviceName, String groupName) { String key = NamingUtils.getGroupedName(serviceName, groupName); synchronized (registeredInstances) { InstanceRedoData redoData = registeredInstances.get(key); if (null != redoData) { redoData.registered(); } } } /** * Instance deregister, mark unregistering status as {@code true}. * * @param serviceName service name * @param groupName group name */ public void instanceDeregister(String serviceName, String groupName) { String key = NamingUtils.getGroupedName(serviceName, groupName); synchronized (registeredInstances) { InstanceRedoData redoData = registeredInstances.get(key); if (null != redoData) { redoData.setUnregistering(true); redoData.setExpectedRegistered(false); } } } /** * Instance deregister finished, mark unregistered status. * * @param serviceName service name * @param groupName group name */ public void instanceDeregistered(String serviceName, String groupName) { String key = NamingUtils.getGroupedName(serviceName, groupName); synchronized (registeredInstances) { InstanceRedoData redoData = registeredInstances.get(key); if (null != redoData) { redoData.unregistered(); } } } /** * Remove registered instance for redo. * * @param serviceName service name * @param groupName group name */ public void removeInstanceForRedo(String serviceName, String groupName) { String key = NamingUtils.getGroupedName(serviceName, groupName); synchronized (registeredInstances) { InstanceRedoData redoData = registeredInstances.get(key); if (null != redoData && !redoData.isExpectedRegistered()) { registeredInstances.remove(key); } } } /** * Find all instance redo data which need do redo. * * @return set of {@code InstanceRedoData} need to do redo. */ public Set findInstanceRedoData() { Set result = new HashSet<>(); synchronized (registeredInstances) { for (InstanceRedoData each : registeredInstances.values()) { if (each.isNeedRedo()) { result.add(each); } } } return result; } /** * Cache subscriber for redo. * * @param serviceName service name * @param groupName group name * @param cluster cluster */ public void cacheSubscriberForRedo(String serviceName, String groupName, String cluster) { String key = ServiceInfo.getKey(NamingUtils.getGroupedName(serviceName, groupName), cluster); SubscriberRedoData redoData = SubscriberRedoData.build(serviceName, groupName, cluster); synchronized (subscribes) { subscribes.put(key, redoData); } } /** * Subscriber register successfully, mark registered status as {@code true}. * * @param serviceName service name * @param groupName group name * @param cluster cluster */ public void subscriberRegistered(String serviceName, String groupName, String cluster) { String key = ServiceInfo.getKey(NamingUtils.getGroupedName(serviceName, groupName), cluster); synchronized (subscribes) { SubscriberRedoData redoData = subscribes.get(key); if (null != redoData) { redoData.setRegistered(true); } } } /** * Subscriber deregister, mark unregistering status as {@code true}. * * @param serviceName service name * @param groupName group name * @param cluster cluster */ public void subscriberDeregister(String serviceName, String groupName, String cluster) { String key = ServiceInfo.getKey(NamingUtils.getGroupedName(serviceName, groupName), cluster); synchronized (subscribes) { SubscriberRedoData redoData = subscribes.get(key); if (null != redoData) { redoData.setUnregistering(true); redoData.setExpectedRegistered(false); } } } /** * Judge subscriber has registered to server. * * @param serviceName service name * @param groupName group name * @param cluster cluster * @return {@code true} if subscribed, otherwise {@code false} */ public boolean isSubscriberRegistered(String serviceName, String groupName, String cluster) { String key = ServiceInfo.getKey(NamingUtils.getGroupedName(serviceName, groupName), cluster); synchronized (subscribes) { SubscriberRedoData redoData = subscribes.get(key); return null != redoData && redoData.isRegistered(); } } /** * Remove subscriber for redo. * * @param serviceName service name * @param groupName group name * @param cluster cluster */ public void removeSubscriberForRedo(String serviceName, String groupName, String cluster) { String key = ServiceInfo.getKey(NamingUtils.getGroupedName(serviceName, groupName), cluster); synchronized (subscribes) { SubscriberRedoData redoData = subscribes.get(key); if (null != redoData && !redoData.isExpectedRegistered()) { subscribes.remove(key); } } } /** * Find all subscriber redo data which need do redo. * * @return set of {@code SubscriberRedoData} need to do redo. */ public Set findSubscriberRedoData() { Set result = new HashSet<>(); synchronized (subscribes) { for (SubscriberRedoData each : subscribes.values()) { if (each.isNeedRedo()) { result.add(each); } } } return result; } /** * get Cache service. * * @return cache service */ public InstanceRedoData getRegisteredInstancesByKey(String combinedServiceName) { return registeredInstances.get(combinedServiceName); } /** * Shutdown redo service. */ public void shutdown() { LogUtils.NAMING_LOGGER.info("Shutdown grpc redo service executor " + redoExecutor); registeredInstances.clear(); subscribes.clear(); redoExecutor.shutdownNow(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy