From fda3ca51825d2ba0fca65a314a8ba6a60b2348ee Mon Sep 17 00:00:00 2001 From: linxin Date: Mon, 13 Feb 2023 21:44:55 +0800 Subject: [PATCH 01/17] refactor interceptor --- .../model/wrapper/WrapperInvocation.java | 54 ------ .../InterceptorExecutionException.java} | 19 +- .../meta/cleaner/AppRevisionCleaner.java | 16 +- .../meta/cleaner/AppRevisionCleanerTest.java | 11 +- .../bootstrap/SessionServerConfiguration.java | 33 ++-- .../AccessLimitInterceptor.java} | 33 ++-- .../BlacklistInterceptor.java} | 37 ++-- .../ClientCheckInterceptor.java} | 30 +-- .../ClientOffInterceptor.java} | 41 ++--- .../session/interceptor/Interceptor.java | 51 ++++++ .../interceptor/InterceptorManager.java} | 28 +-- .../OrderedInterceptorManager.java | 81 +++++++++ .../RegisterInvokeData.java | 2 +- .../session/registry/SessionRegistry.java | 110 +++++------ .../wrapper/WrapperInterceptorManager.java | 58 ------ .../AbstractSessionServerTestBase.java | 1 + .../registry/server/session/AllTests.java | 3 +- .../server/session/WrapperInvocationTest.java | 148 --------------- .../OrderedInterceptorManagerTest.java | 171 ++++++++++++++++++ .../api/repository/AppRevisionRepository.java | 1 + .../impl/AppRevisionRaftRepository.java | 1 + 21 files changed, 467 insertions(+), 462 deletions(-) delete mode 100644 server/common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/WrapperInvocation.java rename server/common/{model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/Wrapper.java => util/src/main/java/com/alipay/sofa/registry/exception/InterceptorExecutionException.java} (66%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/{wrapper/AccessLimitWrapperInterceptor.java => interceptor/AccessLimitInterceptor.java} (57%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/{wrapper/BlacklistWrapperInterceptor.java => interceptor/BlacklistInterceptor.java} (74%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/{wrapper/ClientCheckWrapperInterceptor.java => interceptor/ClientCheckInterceptor.java} (67%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/{wrapper/ClientOffWrapperInterceptor.java => interceptor/ClientOffInterceptor.java} (75%) create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/Interceptor.java rename server/{common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/WrapperInterceptor.java => server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/InterceptorManager.java} (54%) create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/{wrapper => interceptor}/RegisterInvokeData.java (96%) delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/WrapperInterceptorManager.java delete mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/WrapperInvocationTest.java create mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManagerTest.java diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/WrapperInvocation.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/WrapperInvocation.java deleted file mode 100644 index 570b9b22d..000000000 --- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/WrapperInvocation.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.common.model.wrapper; - -import java.util.Iterator; -import java.util.List; -import java.util.function.Supplier; - -/** - * @author shangyu.wh - * @version 1.0: WrapperInvocation.java, v 0.1 2019-06-18 11:43 shangyu.wh Exp $ - */ -public class WrapperInvocation { - - private final Wrapper target; - - private Iterator iterator; - - public WrapperInvocation(Wrapper target, List interceptorChain) { - this.iterator = interceptorChain.iterator(); - this.target = target; - } - - public R proceed() throws Exception { - if (iterator.hasNext()) { - WrapperInterceptor interceptor = iterator.next(); - return interceptor.invokeCodeWrapper(this); - } - return target.call(); - } - - /** - * Getter method for property ParameterSupplier. - * - * @return property value of ParameterSupplier - */ - public Supplier getParameterSupplier() { - return target.getParameterSupplier(); - } -} diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/Wrapper.java b/server/common/util/src/main/java/com/alipay/sofa/registry/exception/InterceptorExecutionException.java similarity index 66% rename from server/common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/Wrapper.java rename to server/common/util/src/main/java/com/alipay/sofa/registry/exception/InterceptorExecutionException.java index 9abf76549..726cd7c39 100644 --- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/Wrapper.java +++ b/server/common/util/src/main/java/com/alipay/sofa/registry/exception/InterceptorExecutionException.java @@ -14,17 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.common.model.wrapper; +package com.alipay.sofa.registry.exception; -import java.util.function.Supplier; +/** Interceptor exception */ +public class InterceptorExecutionException extends RuntimeException { -/** - * @author shangyu.wh - * @version 1.0: Wrapper.java, v 0.1 2019-06-18 19:33 shangyu.wh Exp $ - */ -public interface Wrapper { + private static final long serialVersionUID = -6793552645172892864L; - R call(); + public InterceptorExecutionException(String message) { + super(message); + } - Supplier getParameterSupplier(); + public InterceptorExecutionException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/server/server/meta/src/main/java/com/alipay/sofa/registry/server/meta/cleaner/AppRevisionCleaner.java b/server/server/meta/src/main/java/com/alipay/sofa/registry/server/meta/cleaner/AppRevisionCleaner.java index e6a330f39..326270bbd 100644 --- a/server/server/meta/src/main/java/com/alipay/sofa/registry/server/meta/cleaner/AppRevisionCleaner.java +++ b/server/server/meta/src/main/java/com/alipay/sofa/registry/server/meta/cleaner/AppRevisionCleaner.java @@ -162,7 +162,7 @@ void markDeleted() { private void appRevisionSwitchRefresh() { DBResponse ret = - provideDataService.queryProvideData(ValueConstants.APP_REVISION_WRITE_SWITCH_DATA_ID); + provideDataService.queryProvideData(ValueConstants.APP_REVISION_WRITE_SWITCH_DATA_ID); AppRevisionDomainConvertor.EnableConfig enableConfig = null; if (ret.getOperationStatus() == OperationStatus.SUCCESS) { PersistenceData data = ret.getEntity(); @@ -170,7 +170,7 @@ private void appRevisionSwitchRefresh() { if (StringUtils.isNotBlank(switchString)) { try { enableConfig = - JsonUtils.read(switchString, AppRevisionDomainConvertor.EnableConfig.class); + JsonUtils.read(switchString, AppRevisionDomainConvertor.EnableConfig.class); } catch (Throwable e) { LOG.error("Decode appRevision write switch failed", e); } @@ -178,14 +178,14 @@ private void appRevisionSwitchRefresh() { } if (enableConfig != null) { LOG.info( - "appRevisionSwitch prev={}/{}", - AppRevisionDomainConvertor.getEnableConfig().isServiceParams(), - AppRevisionDomainConvertor.getEnableConfig().isServiceParamsLarge()); + "appRevisionSwitch prev={}/{}", + AppRevisionDomainConvertor.getEnableConfig().isServiceParams(), + AppRevisionDomainConvertor.getEnableConfig().isServiceParamsLarge()); AppRevisionDomainConvertor.setEnableConfig(enableConfig); LOG.info( - "appRevisionSwitch update={}/{}", - enableConfig.isServiceParams(), - enableConfig.isServiceParamsLarge()); + "appRevisionSwitch update={}/{}", + enableConfig.isServiceParams(), + enableConfig.isServiceParamsLarge()); } } diff --git a/server/server/meta/src/test/java/com/alipay/sofa/registry/server/meta/cleaner/AppRevisionCleanerTest.java b/server/server/meta/src/test/java/com/alipay/sofa/registry/server/meta/cleaner/AppRevisionCleanerTest.java index 75351fa5c..0ec2e0fe6 100644 --- a/server/server/meta/src/test/java/com/alipay/sofa/registry/server/meta/cleaner/AppRevisionCleanerTest.java +++ b/server/server/meta/src/test/java/com/alipay/sofa/registry/server/meta/cleaner/AppRevisionCleanerTest.java @@ -69,11 +69,12 @@ public void beforeTest() throws Exception { // doReturn(new DateNowDomain(new Date())).when(appRevisionCleaner.appRevisionMapper).getNow(); doReturn( new DBResponse<>( - PersistenceDataBuilder.createPersistenceData( - ValueConstants.APP_REVISION_WRITE_SWITCH_DATA_ID, "{\"serviceParams\":false,\"serviceParamsLarge\":true}"), - OperationStatus.SUCCESS)) - .when(appRevisionCleaner.provideDataService) - .queryProvideData(anyString()); + PersistenceDataBuilder.createPersistenceData( + ValueConstants.APP_REVISION_WRITE_SWITCH_DATA_ID, + "{\"serviceParams\":false,\"serviceParamsLarge\":true}"), + OperationStatus.SUCCESS)) + .when(appRevisionCleaner.provideDataService) + .queryProvideData(anyString()); } @After diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java index 00bd29432..277fb7c0b 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java @@ -16,7 +16,6 @@ */ package com.alipay.sofa.registry.server.session.bootstrap; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInterceptor; import com.alipay.sofa.registry.jdbc.config.JdbcConfiguration; import com.alipay.sofa.registry.jraft.config.RaftConfiguration; import com.alipay.sofa.registry.remoting.bolt.exchange.BoltExchange; @@ -37,6 +36,7 @@ import com.alipay.sofa.registry.server.session.filter.ProcessFilter; import com.alipay.sofa.registry.server.session.filter.blacklist.BlacklistMatchProcessFilter; import com.alipay.sofa.registry.server.session.filter.blacklist.DefaultIPMatchStrategy; +import com.alipay.sofa.registry.server.session.interceptor.*; import com.alipay.sofa.registry.server.session.limit.AccessLimitService; import com.alipay.sofa.registry.server.session.limit.AccessLimitServiceImpl; import com.alipay.sofa.registry.server.session.mapper.ConnectionMapper; @@ -61,7 +61,6 @@ import com.alipay.sofa.registry.server.session.store.*; import com.alipay.sofa.registry.server.session.strategy.*; import com.alipay.sofa.registry.server.session.strategy.impl.*; -import com.alipay.sofa.registry.server.session.wrapper.*; import com.alipay.sofa.registry.server.shared.client.manager.BaseClientManagerService; import com.alipay.sofa.registry.server.shared.client.manager.ClientManagerService; import com.alipay.sofa.registry.server.shared.meta.MetaServerManager; @@ -687,33 +686,33 @@ public ProcessFilter blacklistMatchProcessFilter() { } @Bean - public WrapperInterceptorManager wrapperInterceptorManager() { - WrapperInterceptorManager mgr = new WrapperInterceptorManager(); - mgr.addInterceptor(clientCheckWrapperInterceptor()); - mgr.addInterceptor(blacklistWrapperInterceptor()); - mgr.addInterceptor(accessLimitWrapperInterceptor()); - mgr.addInterceptor(clientOffWrapperInterceptor()); - return mgr; + public OrderedInterceptorManager orderedInterceptorManager() { + OrderedInterceptorManager orderedInterceptorManager = new OrderedInterceptorManager(); + orderedInterceptorManager.addInterceptor(clientCheckInterceptor()); + orderedInterceptorManager.addInterceptor(blacklistInterceptor()); + orderedInterceptorManager.addInterceptor(accessLimitInterceptor()); + orderedInterceptorManager.addInterceptor(clientOffInterceptor()); + return orderedInterceptorManager; } @Bean - public WrapperInterceptor clientCheckWrapperInterceptor() { - return new ClientCheckWrapperInterceptor(); + public Interceptor clientCheckInterceptor() { + return new ClientCheckInterceptor(); } @Bean - public WrapperInterceptor blacklistWrapperInterceptor() { - return new BlacklistWrapperInterceptor(); + public Interceptor blacklistInterceptor() { + return new BlacklistInterceptor(); } @Bean - public WrapperInterceptor clientOffWrapperInterceptor() { - return new ClientOffWrapperInterceptor(); + public Interceptor clientOffInterceptor() { + return new ClientOffInterceptor(); } @Bean - public WrapperInterceptor accessLimitWrapperInterceptor() { - return new AccessLimitWrapperInterceptor(); + public Interceptor accessLimitInterceptor() { + return new AccessLimitInterceptor(); } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/AccessLimitWrapperInterceptor.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/AccessLimitInterceptor.java similarity index 57% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/AccessLimitWrapperInterceptor.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/AccessLimitInterceptor.java index 480e749e0..2ca290620 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/AccessLimitWrapperInterceptor.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/AccessLimitInterceptor.java @@ -14,42 +14,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.wrapper; +package com.alipay.sofa.registry.server.session.interceptor; import com.alipay.sofa.registry.common.model.store.BaseInfo; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInterceptor; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInvocation; +import com.alipay.sofa.registry.exception.InterceptorExecutionException; import com.alipay.sofa.registry.server.session.limit.AccessLimitService; import org.springframework.beans.factory.annotation.Autowired; -/** - * @author shangyu.wh - * @version 1.0: AccessLimitWrapperInterceptor.java, v 0.1 2019-08-26 20:29 shangyu.wh Exp $ - */ -public class AccessLimitWrapperInterceptor - implements WrapperInterceptor { +/** Access limit interceptor impl. */ +public class AccessLimitInterceptor implements Interceptor { @Autowired private AccessLimitService accessLimitService; @Override - public Boolean invokeCodeWrapper(WrapperInvocation invocation) - throws Exception { - - RegisterInvokeData registerInvokeData = invocation.getParameterSupplier().get(); + public boolean process(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { BaseInfo baseInfo = (BaseInfo) registerInvokeData.getStoreData(); - if (!accessLimitService.tryAcquire()) { - throw new RuntimeException( - String.format( - "Register access limit for session server!dataInfoId=%s,connectId=%s", - baseInfo.getDataInfoId(), baseInfo.getSourceAddress())); + throw new InterceptorExecutionException( + "Register access limit for session server!dataInfoId=" + + baseInfo.getDataInfoId() + + ",connectId=" + + baseInfo.getSourceAddress()); } - return invocation.proceed(); + return true; } @Override - public int getOrder() { + public int order() { return 0; } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/BlacklistWrapperInterceptor.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/BlacklistInterceptor.java similarity index 74% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/BlacklistWrapperInterceptor.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/BlacklistInterceptor.java index c838b04bc..165e9cd26 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/BlacklistWrapperInterceptor.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/BlacklistInterceptor.java @@ -14,14 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.wrapper; +package com.alipay.sofa.registry.server.session.interceptor; import com.alipay.sofa.registry.common.model.constants.ValueConstants; import com.alipay.sofa.registry.common.model.store.BaseInfo; -import com.alipay.sofa.registry.common.model.store.StoreData.DataType; +import com.alipay.sofa.registry.common.model.store.StoreData; import com.alipay.sofa.registry.common.model.store.Subscriber; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInterceptor; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInvocation; +import com.alipay.sofa.registry.exception.InterceptorExecutionException; import com.alipay.sofa.registry.log.Logger; import com.alipay.sofa.registry.server.session.filter.ProcessFilter; import com.alipay.sofa.registry.server.session.loggers.Loggers; @@ -31,15 +30,11 @@ import org.apache.logging.log4j.util.Strings; import org.springframework.beans.factory.annotation.Autowired; -/** - * blacklist filter - * - * @author shangyu.wh - * @version 1.0: BlacklistWrapperInterceptor.java, v 0.1 2019-06-18 22:26 shangyu.wh Exp $ - */ -public class BlacklistWrapperInterceptor - implements WrapperInterceptor { +/** Blacklist interceptor impl. */ +public class BlacklistInterceptor implements Interceptor { + private static final Logger LOGGER = Loggers.BLACK_LIST_LOG; + @Autowired protected SessionRegistry sessionRegistry; @Autowired protected FirePushService firePushService; @@ -47,23 +42,21 @@ public class BlacklistWrapperInterceptor @Autowired protected ProcessFilter processFilter; @Override - public Boolean invokeCodeWrapper(WrapperInvocation invocation) - throws Exception { - - RegisterInvokeData registerInvokeData = invocation.getParameterSupplier().get(); + public boolean process(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { BaseInfo storeData = (BaseInfo) registerInvokeData.getStoreData(); if (Strings.isNotBlank(storeData.attributeOf(ValueConstants.BLOCKED_REQUEST_KEY)) || processFilter.match(storeData)) { - if (DataType.PUBLISHER == storeData.getDataType()) { + if (StoreData.DataType.PUBLISHER == storeData.getDataType()) { // match blacklist stop pub. LOGGER.info( "[pub],{},{}", storeData.getDataInfoId(), RemotingHelper.getAddressString(storeData.getSourceAddress())); - return true; + return false; } - if (DataType.SUBSCRIBER == storeData.getDataType()) { + if (StoreData.DataType.SUBSCRIBER == storeData.getDataType()) { // in some case, need to push empty to new subscriber, and stop sub // else, filter not stop sub if (sessionRegistry.isPushEmpty((Subscriber) storeData)) { @@ -73,15 +66,15 @@ public Boolean invokeCodeWrapper(WrapperInvocation "[sub],{},{}", storeData.getDataInfoId(), RemotingHelper.getAddressString(storeData.getSourceAddress())); - return true; + return false; } } } - return invocation.proceed(); + return true; } @Override - public int getOrder() { + public int order() { return 200; } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/ClientCheckWrapperInterceptor.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/ClientCheckInterceptor.java similarity index 67% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/ClientCheckWrapperInterceptor.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/ClientCheckInterceptor.java index 8995e26e0..0c856392d 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/ClientCheckWrapperInterceptor.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/ClientCheckInterceptor.java @@ -14,11 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.wrapper; +package com.alipay.sofa.registry.server.session.interceptor; import com.alipay.sofa.registry.common.model.store.BaseInfo; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInterceptor; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInvocation; +import com.alipay.sofa.registry.exception.InterceptorExecutionException; import com.alipay.sofa.registry.remoting.Channel; import com.alipay.sofa.registry.remoting.Server; import com.alipay.sofa.registry.remoting.exchange.Exchange; @@ -26,39 +25,28 @@ import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; import org.springframework.beans.factory.annotation.Autowired; -/** - * check connect already existed - * - * @author shangyu.wh - * @version 1.0: ClientCheckWrapperInterceptor.java, v 0.1 2019-06-18 13:53 shangyu.wh Exp $ - */ -public class ClientCheckWrapperInterceptor - implements WrapperInterceptor { +/** Client check interceptor impl. */ +public class ClientCheckInterceptor implements Interceptor { @Autowired private SessionServerConfig sessionServerConfig; @Autowired private Exchange boltExchange; @Override - public Boolean invokeCodeWrapper(WrapperInvocation invocation) - throws Exception { - - RegisterInvokeData registerInvokeData = invocation.getParameterSupplier().get(); + public boolean process(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { BaseInfo baseInfo = (BaseInfo) registerInvokeData.getStoreData(); - Server sessionServer = boltExchange.getServer(sessionServerConfig.getServerPort()); - Channel channel = sessionServer.getChannel(baseInfo.getSourceAddress()); - if (channel == null) { throw new RequestChannelClosedException( - String.format("Register address %s channel closed", baseInfo.getSourceAddress())); + "Register address " + baseInfo.getSourceAddress() + " channel closed"); } - return invocation.proceed(); + return true; } @Override - public int getOrder() { + public int order() { return 100; } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/ClientOffWrapperInterceptor.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/ClientOffInterceptor.java similarity index 75% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/ClientOffWrapperInterceptor.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/ClientOffInterceptor.java index da283fabd..91b7b0d0c 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/ClientOffWrapperInterceptor.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/ClientOffInterceptor.java @@ -14,15 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.wrapper; +package com.alipay.sofa.registry.server.session.interceptor; import static com.alipay.sofa.registry.common.model.constants.ValueConstants.CLIENT_OFF; -import com.alipay.sofa.registry.common.model.metaserver.ClientManagerAddress.AddressVersion; -import com.alipay.sofa.registry.common.model.store.*; -import com.alipay.sofa.registry.common.model.store.StoreData.DataType; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInterceptor; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInvocation; +import com.alipay.sofa.registry.common.model.metaserver.ClientManagerAddress; +import com.alipay.sofa.registry.common.model.store.BaseInfo; +import com.alipay.sofa.registry.common.model.store.StoreData; +import com.alipay.sofa.registry.common.model.store.Subscriber; +import com.alipay.sofa.registry.common.model.store.URL; +import com.alipay.sofa.registry.exception.InterceptorExecutionException; import com.alipay.sofa.registry.log.Logger; import com.alipay.sofa.registry.remoting.Channel; import com.alipay.sofa.registry.remoting.bolt.BoltChannel; @@ -34,12 +35,8 @@ import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; -/** - * @author xiaojian.xj - * @version $Id: ClientOffWrapperInterceptor.java, v 0.1 2021年05月28日 21:18 xiaojian.xj Exp $ - */ -public class ClientOffWrapperInterceptor - implements WrapperInterceptor { +/** Client off interceptor impl. */ +public class ClientOffInterceptor implements Interceptor { private static final Logger LOGGER = Loggers.CLIENT_OFF_LOG; @@ -49,24 +46,22 @@ public class ClientOffWrapperInterceptor @Resource private FetchClientOffAddressService fetchClientOffAddressService; - @Autowired protected SessionRegistry sessionRegistry; + @Autowired private SessionRegistry sessionRegistry; @Override - public Boolean invokeCodeWrapper(WrapperInvocation invocation) - throws Exception { - RegisterInvokeData registerInvokeData = invocation.getParameterSupplier().get(); + public boolean process(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { BaseInfo storeData = (BaseInfo) registerInvokeData.getStoreData(); - URL url = storeData.getSourceAddress(); - - AddressVersion address = fetchClientOffAddressService.getAddress(url.getIpAddress()); + ClientManagerAddress.AddressVersion address = + fetchClientOffAddressService.getAddress(url.getIpAddress()); if (address != null) { markChannel(registerInvokeData.getChannel()); LOGGER.info( "dataInfoId:{} ,url:{} match clientOff ips.", storeData.getDataInfoId(), url.getIpAddress()); - if (DataType.PUBLISHER == storeData.getDataType()) { + if (StoreData.DataType.PUBLISHER == storeData.getDataType()) { // match client off pub, do unpub to data, make sure the publisher remove try { sessionRegistry.unRegister(storeData); @@ -77,7 +72,7 @@ public Boolean invokeCodeWrapper(WrapperInvocation return true; } - if (DataType.SUBSCRIBER == storeData.getDataType()) { + if (StoreData.DataType.SUBSCRIBER == storeData.getDataType()) { // in some case, need to push empty to new subscriber, and stop sub // else, filter not stop sub if (sessionRegistry.isPushEmpty((Subscriber) storeData) && address.isSub()) { @@ -92,7 +87,7 @@ public Boolean invokeCodeWrapper(WrapperInvocation } } } - return invocation.proceed(); + return true; } private void markChannel(Channel channel) { @@ -107,7 +102,7 @@ private void markChannel(Channel channel) { } @Override - public int getOrder() { + public int order() { return 300; } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/Interceptor.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/Interceptor.java new file mode 100644 index 000000000..288109f81 --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/Interceptor.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.interceptor; + +import com.alipay.sofa.registry.exception.InterceptorExecutionException; + +/** Interceptor in the subscriber processing flow. */ +public interface Interceptor { + + /** + * Execute the target runnable impl. + * + * @param registerInvokeData data + * @return false means that the current interceptor is not passed + * @throws InterceptorExecutionException thrown when interceptor execute exception + */ + boolean process(RegisterInvokeData registerInvokeData) throws InterceptorExecutionException; + + /** + * Returns the execution order factor of the interceptor, and the interceptor with a smaller value + * is executed first. + * + * @return the execution order factor of the interceptor + */ + default int order() { + return 0; + } + + /** + * Interceptor name. + * + * @return interceptor name + */ + default String getName() { + return getClass().getSimpleName(); + } +} diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/WrapperInterceptor.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/InterceptorManager.java similarity index 54% rename from server/common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/WrapperInterceptor.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/InterceptorManager.java index ff39fea0b..8141dcea9 100644 --- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/wrapper/WrapperInterceptor.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/InterceptorManager.java @@ -14,27 +14,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.common.model.wrapper; +package com.alipay.sofa.registry.server.session.interceptor; -/** - * @author shangyu.wh - * @version 1.0: WrapperInterceptor.java, v 0.1 2019-06-18 11:45 shangyu.wh Exp $ - */ -public interface WrapperInterceptor { +import com.alipay.sofa.registry.exception.InterceptorExecutionException; + +/** Manage all interceptor. */ +public interface InterceptorManager { /** - * invoke inside function + * Add a new interceptor according to the execution priority of the interceptor. * - * @param invocation - * @return - * @throws Exception + * @param interceptor target interceptor */ - R invokeCodeWrapper(WrapperInvocation invocation) throws Exception; + void addInterceptor(Interceptor interceptor); /** - * Interceptor order + * Execute all interceptors in order. * - * @return + * @param registerInvokeData data + * @throws InterceptorExecutionException throw when any interceptor encounters an exception, and + * stop executing subsequent interceptors */ - int getOrder(); + void executeInterceptors(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException; } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java new file mode 100644 index 000000000..b3caa6277 --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.interceptor; + +import com.alipay.sofa.registry.exception.InterceptorExecutionException; +import com.alipay.sofa.registry.log.Logger; +import com.alipay.sofa.registry.log.LoggerFactory; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +/** Ordered interceptor manager. */ +public class OrderedInterceptorManager implements InterceptorManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(OrderedInterceptorManager.class); + + private final List interceptors; + + public OrderedInterceptorManager() { + // 拦截器是系统初始化阶段生成的,这里就不用考虑并发的问题了 + this.interceptors = new ArrayList<>(); + } + + @Override + public void addInterceptor(Interceptor interceptor) { + interceptors.add(interceptor); + interceptors.sort(Comparator.comparingInt(Interceptor::order)); + } + + @Override + public void executeInterceptors(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { + if (interceptors.size() == 0) { + return; + } + + for (Interceptor interceptor : interceptors) { + try { + boolean result = interceptor.process(registerInvokeData); + if (!result) { + LOGGER.info("interceptor({}) return false, skip all subsequent interceptors"); + break; + } + } catch (InterceptorExecutionException e) { + LOGGER.error( + "interceptor({}) process data(dataId={}) exception", + interceptor.getName(), + registerInvokeData.getStoreData().getId(), + e); + throw e; + } catch (Exception e) { + LOGGER.error( + "interceptor({}) process data(dataId={}) encountered an unexpected exception", + interceptor.getName(), + registerInvokeData.getStoreData().getId(), + e); + throw new InterceptorExecutionException( + "interceptor(" + + interceptor.getName() + + ") process data(dataId=" + + registerInvokeData.getStoreData().getId() + + ") encountered an unexpected exception", + e); + } + } + } +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/RegisterInvokeData.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/RegisterInvokeData.java similarity index 96% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/RegisterInvokeData.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/RegisterInvokeData.java index 02360927b..3013c96f8 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/RegisterInvokeData.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/RegisterInvokeData.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.wrapper; +package com.alipay.sofa.registry.server.session.interceptor; import com.alipay.sofa.registry.common.model.store.StoreData; import com.alipay.sofa.registry.remoting.Channel; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java index e21b0a3d8..eef2b6fa5 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java @@ -20,20 +20,19 @@ import com.alipay.sofa.registry.common.model.Tuple; import com.alipay.sofa.registry.common.model.dataserver.DatumVersion; import com.alipay.sofa.registry.common.model.store.*; -import com.alipay.sofa.registry.common.model.wrapper.Wrapper; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInvocation; import com.alipay.sofa.registry.log.Logger; import com.alipay.sofa.registry.log.LoggerFactory; import com.alipay.sofa.registry.remoting.Channel; import com.alipay.sofa.registry.remoting.Server; import com.alipay.sofa.registry.remoting.exchange.Exchange; import com.alipay.sofa.registry.remoting.exchange.ExchangeCallback; -import com.alipay.sofa.registry.remoting.exchange.RequestChannelClosedException; import com.alipay.sofa.registry.server.session.acceptor.ClientOffWriteDataRequest; import com.alipay.sofa.registry.server.session.acceptor.PublisherWriteDataRequest; import com.alipay.sofa.registry.server.session.acceptor.WriteDataAcceptor; import com.alipay.sofa.registry.server.session.acceptor.WriteDataRequest; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; +import com.alipay.sofa.registry.server.session.interceptor.OrderedInterceptorManager; +import com.alipay.sofa.registry.server.session.interceptor.RegisterInvokeData; import com.alipay.sofa.registry.server.session.loggers.Loggers; import com.alipay.sofa.registry.server.session.node.service.DataNodeService; import com.alipay.sofa.registry.server.session.providedata.ConfigProvideDataWatcher; @@ -45,8 +44,6 @@ import com.alipay.sofa.registry.server.session.store.Interests; import com.alipay.sofa.registry.server.session.store.Watchers; import com.alipay.sofa.registry.server.session.strategy.SessionRegistryStrategy; -import com.alipay.sofa.registry.server.session.wrapper.RegisterInvokeData; -import com.alipay.sofa.registry.server.session.wrapper.WrapperInterceptorManager; import com.alipay.sofa.registry.server.shared.env.ServerEnv; import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.LoopRunnable; @@ -58,7 +55,6 @@ import java.util.*; import java.util.Map.Entry; import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; import javax.annotation.PostConstruct; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -94,7 +90,7 @@ public class SessionRegistry implements Registry { @Autowired protected SessionRegistryStrategy sessionRegistryStrategy; - @Autowired protected WrapperInterceptorManager wrapperInterceptorManager; + @Autowired protected OrderedInterceptorManager orderedInterceptorManager; @Autowired protected WriteDataAcceptor writeDataAcceptor; @@ -114,63 +110,55 @@ public void init() { @Override public void register(StoreData storeData, Channel channel) { + RegisterInvokeData registerInvokeData = new RegisterInvokeData(storeData, channel); - WrapperInvocation wrapperInvocation = - new WrapperInvocation( - new Wrapper() { - @Override - public Boolean call() { - - switch (storeData.getDataType()) { - case PUBLISHER: - Publisher publisher = (Publisher) storeData; - publisher.setSessionProcessId(ServerEnv.PROCESS_ID); - if (!sessionDataStore.add(publisher)) { - break; - } - // All write operations to DataServer (pub/unPub/clientoff/renew/snapshot) - // are handed over to WriteDataAcceptor - writeDataAcceptor.accept( - new PublisherWriteDataRequest( - publisher, WriteDataRequest.WriteDataRequestType.PUBLISHER)); - - sessionRegistryStrategy.afterPublisherRegister(publisher); - break; - case SUBSCRIBER: - Subscriber subscriber = (Subscriber) storeData; - - if (!sessionInterests.add(subscriber)) { - break; - } - - sessionRegistryStrategy.afterSubscriberRegister(subscriber); - break; - case WATCHER: - Watcher watcher = (Watcher) storeData; - - if (!sessionWatchers.add(watcher)) { - break; - } - - sessionRegistryStrategy.afterWatcherRegister(watcher); - break; - default: - break; - } - return null; - } - - @Override - public Supplier getParameterSupplier() { - return () -> new RegisterInvokeData(storeData, channel); - } - }, - wrapperInterceptorManager.getInterceptorChain()); + try { + orderedInterceptorManager.executeInterceptors(registerInvokeData); + } catch (Exception e) { + LOGGER.error( + "interceptors process data(dataId={}) encountered an unexpected exception", + registerInvokeData.getStoreData().getId(), + e); + throw new RuntimeException("Proceed register error!", e); + } try { - wrapperInvocation.proceed(); - } catch (RequestChannelClosedException e) { - throw e; + switch (storeData.getDataType()) { + case PUBLISHER: + Publisher publisher = (Publisher) storeData; + publisher.setSessionProcessId(ServerEnv.PROCESS_ID); + if (!sessionDataStore.add(publisher)) { + break; + } + // All write operations to DataServer (pub/unPub/clientoff/renew/snapshot) + // are handed over to WriteDataAcceptor + writeDataAcceptor.accept( + new PublisherWriteDataRequest( + publisher, WriteDataRequest.WriteDataRequestType.PUBLISHER)); + + sessionRegistryStrategy.afterPublisherRegister(publisher); + break; + case SUBSCRIBER: + Subscriber subscriber = (Subscriber) storeData; + + if (!sessionInterests.add(subscriber)) { + break; + } + + sessionRegistryStrategy.afterSubscriberRegister(subscriber); + break; + case WATCHER: + Watcher watcher = (Watcher) storeData; + + if (!sessionWatchers.add(watcher)) { + break; + } + + sessionRegistryStrategy.afterWatcherRegister(watcher); + break; + default: + break; + } } catch (Exception e) { throw new RuntimeException("Proceed register error!", e); } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/WrapperInterceptorManager.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/WrapperInterceptorManager.java deleted file mode 100644 index 20204abf5..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/wrapper/WrapperInterceptorManager.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.wrapper; - -import com.alipay.sofa.registry.common.model.wrapper.WrapperInterceptor; -import com.alipay.sofa.registry.log.Logger; -import com.alipay.sofa.registry.log.LoggerFactory; -import com.google.common.collect.Lists; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -/** - * @author shangyu.wh - * @version 1.0: WrapperInterceptorManager.java, v 0.1 2019-06-18 14:51 shangyu.wh Exp $ - */ -public class WrapperInterceptorManager { - private static final Logger LOGGER = LoggerFactory.getLogger(WrapperInterceptorManager.class); - private volatile List interceptorChain = Collections.EMPTY_LIST; - - public void addInterceptor(WrapperInterceptor item) { - List list = Lists.newArrayListWithCapacity(interceptorChain.size() + 1); - list.addAll(interceptorChain); - list.add(item); - list.sort(new Comp()); - this.interceptorChain = list; - LOGGER.info("add interceptor:{}, now={}", item.getClass(), interceptorChain); - } - - static final class Comp implements Comparator { - @Override - public int compare(WrapperInterceptor o1, WrapperInterceptor o2) { - return o1.getOrder() - o2.getOrder(); - } - } - /** - * Getter method for property interceptorChain. - * - * @return property value of interceptorChain - */ - public List getInterceptorChain() { - return interceptorChain; - } -} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/AbstractSessionServerTestBase.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/AbstractSessionServerTestBase.java index 90c1c03a8..109b76985 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/AbstractSessionServerTestBase.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/AbstractSessionServerTestBase.java @@ -729,6 +729,7 @@ public void register(AppRevision appRevision) throws Exception { /** * check if revisionId exist + * * @param revisionId * @return */ diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/AllTests.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/AllTests.java index 36f2e2d1f..b73047fcc 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/AllTests.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/AllTests.java @@ -20,6 +20,7 @@ * @author chen.zhu *

Apr 12, 2021 */ +import com.alipay.sofa.registry.server.session.interceptor.OrderedInterceptorManagerTest; import com.alipay.sofa.registry.server.session.node.service.MetaServerServiceImplTest; import com.alipay.sofa.registry.server.session.node.service.SessionMetaServerManagerTest; import com.alipay.sofa.registry.server.session.slot.SlotTableCacheImplTest; @@ -29,7 +30,7 @@ @RunWith(Suite.class) @Suite.SuiteClasses({ - WrapperInvocationTest.class, + OrderedInterceptorManagerTest.class, DataCacheTest.class, SlotTableCacheImplTest.class, MetaServerServiceImplTest.class, diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/WrapperInvocationTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/WrapperInvocationTest.java deleted file mode 100644 index da7111c59..000000000 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/WrapperInvocationTest.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session; - -import static junit.framework.Assert.*; - -import com.alipay.sofa.registry.common.model.wrapper.Wrapper; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInterceptor; -import com.alipay.sofa.registry.common.model.wrapper.WrapperInvocation; -import com.alipay.sofa.registry.log.Logger; -import com.alipay.sofa.registry.log.LoggerFactory; -import com.alipay.sofa.registry.server.session.wrapper.WrapperInterceptorManager; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -/** - * @author shangyu.wh - * @version 1.0: WrapperInvocationTest.java, v 0.1 2019-06-18 17:41 shangyu.wh Exp $ - */ -public class WrapperInvocationTest { - - private static final Logger logger = LoggerFactory.getLogger(WrapperInvocationTest.class); - - @Rule public ExpectedException thrown = ExpectedException.none(); - - @Test - public void testWrapperInterceptorException() throws Exception { - thrown.expect(IllegalAccessException.class); - thrown.expectMessage("test exception!"); - testAll("EXP"); - } - - @Test - public void testWrapperInterceptorProceed() throws Exception { - assertEquals(testAll("Proceed"), 1); - } - - @Test - public void testWrapperInterceptorAllRun() throws Exception { - assertEquals(testAll("AllRun"), 2); - } - - private int testAll(String input) throws Exception { - - AtomicInteger ret = new AtomicInteger(0); - - WrapperInterceptorManager wrapperInterceptorManager = new WrapperInterceptorManager(); - - wrapperInterceptorManager.addInterceptor( - new WrapperInterceptor() { - - @Override - public Boolean invokeCodeWrapper(WrapperInvocation invocation) - throws Exception { - logger.info("0"); - if ("EXP".equals(invocation.getParameterSupplier().get())) { - throw new IllegalAccessException("test exception!"); - } - return invocation.proceed(); - } - - @Override - public int getOrder() { - return 0; - } - }); - - wrapperInterceptorManager.addInterceptor( - new WrapperInterceptor() { - - @Override - public Boolean invokeCodeWrapper(WrapperInvocation invocation) - throws Exception { - logger.info("1"); - if ("Proceed".equals(invocation.getParameterSupplier().get())) { - ret.set(1); - return true; - } - return invocation.proceed(); - } - - @Override - public int getOrder() { - return 1; - } - }); - - wrapperInterceptorManager.addInterceptor( - new WrapperInterceptor() { - - @Override - public Boolean invokeCodeWrapper(WrapperInvocation invocation) - throws Exception { - logger.info("2"); - if ("test".equals(invocation.getParameterSupplier().get())) { - return true; - } - return invocation.proceed(); - } - - @Override - public int getOrder() { - return 2; - } - }); - - WrapperInvocation wrapperInvocation = - new WrapperInvocation( - new Wrapper() { - @Override - public Boolean call() { - if ("AllRun".equals(getParameterSupplier().get())) { - System.out.println("success"); - ret.set(2); - return true; - } - return null; - } - - @Override - public Supplier getParameterSupplier() { - return () -> input; - } - }, - wrapperInterceptorManager.getInterceptorChain()); - - wrapperInvocation.proceed(); - - return ret.get(); - } -} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManagerTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManagerTest.java new file mode 100644 index 000000000..65348acdc --- /dev/null +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManagerTest.java @@ -0,0 +1,171 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.interceptor; + +import com.alipay.sofa.registry.common.model.store.StoreData; +import com.alipay.sofa.registry.exception.InterceptorExecutionException; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** */ +public class OrderedInterceptorManagerTest { + + private RegisterInvokeData registerInvokeData; + + @Before + public void init() { + registerInvokeData = + new RegisterInvokeData( + new StoreData() { + @Override + public DataType getDataType() { + return null; + } + + @Override + public Object getId() { + return "dataId"; + } + }, + null); + } + + @Test + public void testOrder() { + OrderedInterceptorManager orderedInterceptorManager = new OrderedInterceptorManager(); + // empty interceptors + orderedInterceptorManager.executeInterceptors(registerInvokeData); + + List result = new ArrayList<>(); + orderedInterceptorManager.addInterceptor( + new Interceptor() { + @Override + public boolean process(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { + result.add(order()); + return true; + } + + @Override + public int order() { + return 2; + } + }); + + orderedInterceptorManager.addInterceptor( + new Interceptor() { + @Override + public boolean process(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { + result.add(order()); + return true; + } + + @Override + public int order() { + return 1; + } + }); + orderedInterceptorManager.executeInterceptors(registerInvokeData); + Assert.assertEquals(1, result.get(0).intValue()); + Assert.assertEquals(2, result.get(1).intValue()); + } + + @Test + public void testEarlyTermination() { + OrderedInterceptorManager orderedInterceptorManager = new OrderedInterceptorManager(); + List result = new ArrayList<>(); + orderedInterceptorManager.addInterceptor( + new Interceptor() { + @Override + public boolean process(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { + result.add(order()); + return true; + } + + @Override + public int order() { + return 2; + } + }); + + orderedInterceptorManager.addInterceptor( + new Interceptor() { + @Override + public boolean process(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { + result.add(order()); + return false; + } + + @Override + public int order() { + return 1; + } + }); + orderedInterceptorManager.executeInterceptors(registerInvokeData); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(1, result.get(0).intValue()); + } + + @Test + public void testExceptionTermination() { + OrderedInterceptorManager orderedInterceptorManager = new OrderedInterceptorManager(); + List result = new ArrayList<>(); + orderedInterceptorManager.addInterceptor( + new Interceptor() { + @Override + public boolean process(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { + result.add(order()); + return true; + } + + @Override + public int order() { + return 2; + } + }); + + orderedInterceptorManager.addInterceptor( + new Interceptor() { + @Override + public boolean process(RegisterInvokeData registerInvokeData) + throws InterceptorExecutionException { + result.add(order()); + throw new InterceptorExecutionException("test exception"); + } + + @Override + public int order() { + return 1; + } + }); + Exception exception = null; + try { + orderedInterceptorManager.executeInterceptors(registerInvokeData); + } catch (Exception e) { + exception = e; + } + Assert.assertNotNull(exception); + Assert.assertTrue(exception instanceof InterceptorExecutionException); + } +} diff --git a/server/store/api/src/main/java/com/alipay/sofa/registry/store/api/repository/AppRevisionRepository.java b/server/store/api/src/main/java/com/alipay/sofa/registry/store/api/repository/AppRevisionRepository.java index c2b4ac257..b3f0bfdcb 100644 --- a/server/store/api/src/main/java/com/alipay/sofa/registry/store/api/repository/AppRevisionRepository.java +++ b/server/store/api/src/main/java/com/alipay/sofa/registry/store/api/repository/AppRevisionRepository.java @@ -38,6 +38,7 @@ public interface AppRevisionRepository { /** * check if revisionId exist + * * @param revisionId * @return */ diff --git a/server/store/jraft/src/main/java/com/alipay/sofa/registry/jraft/repository/impl/AppRevisionRaftRepository.java b/server/store/jraft/src/main/java/com/alipay/sofa/registry/jraft/repository/impl/AppRevisionRaftRepository.java index c9a30ec68..390920872 100644 --- a/server/store/jraft/src/main/java/com/alipay/sofa/registry/jraft/repository/impl/AppRevisionRaftRepository.java +++ b/server/store/jraft/src/main/java/com/alipay/sofa/registry/jraft/repository/impl/AppRevisionRaftRepository.java @@ -44,6 +44,7 @@ public void register(AppRevision appRevision) { /** * check if revisionId exist + * * @param revisionId * @return */ From 346f0a0210dd88a017d6af4f6048088a263c2c65 Mon Sep 17 00:00:00 2001 From: linxin Date: Wed, 15 Feb 2023 10:13:37 +0800 Subject: [PATCH 02/17] fix cr --- .../session/interceptor/OrderedInterceptorManager.java | 8 ++++---- .../registry/server/session/registry/SessionRegistry.java | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java index b3caa6277..8207358d7 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java @@ -52,7 +52,7 @@ public void executeInterceptors(RegisterInvokeData registerInvokeData) try { boolean result = interceptor.process(registerInvokeData); if (!result) { - LOGGER.info("interceptor({}) return false, skip all subsequent interceptors"); + LOGGER.warn("interceptor({}) return false, skip all subsequent interceptors"); break; } } catch (InterceptorExecutionException e) { @@ -62,19 +62,19 @@ public void executeInterceptors(RegisterInvokeData registerInvokeData) registerInvokeData.getStoreData().getId(), e); throw e; - } catch (Exception e) { + } catch (Throwable cause) { LOGGER.error( "interceptor({}) process data(dataId={}) encountered an unexpected exception", interceptor.getName(), registerInvokeData.getStoreData().getId(), - e); + cause); throw new InterceptorExecutionException( "interceptor(" + interceptor.getName() + ") process data(dataId=" + registerInvokeData.getStoreData().getId() + ") encountered an unexpected exception", - e); + cause); } } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java index eef2b6fa5..51c6b27d5 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java @@ -140,7 +140,6 @@ public void register(StoreData storeData, Channel channel) { break; case SUBSCRIBER: Subscriber subscriber = (Subscriber) storeData; - if (!sessionInterests.add(subscriber)) { break; } @@ -149,7 +148,6 @@ public void register(StoreData storeData, Channel channel) { break; case WATCHER: Watcher watcher = (Watcher) storeData; - if (!sessionWatchers.add(watcher)) { break; } From 441762103657739f0896bc62e1ea9f315dad6788 Mon Sep 17 00:00:00 2001 From: linxin Date: Wed, 15 Feb 2023 11:16:27 +0800 Subject: [PATCH 03/17] refactor session.acceptor module: 1. remove WriteDataProcessor: avoid creating unnecessary objects 2. standardize the use of generic types to avoid code warnings --- .../acceptor/PublisherWriteDataRequest.java | 49 ------------ .../session/acceptor/WriteDataProcessor.java | 77 ------------------- .../acceptor/WriteDataProcessorTest.java | 74 ------------------ 3 files changed, 200 deletions(-) delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherWriteDataRequest.java delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataProcessor.java delete mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataProcessorTest.java diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherWriteDataRequest.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherWriteDataRequest.java deleted file mode 100644 index 1e728d35b..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherWriteDataRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.acceptor; - -import com.alipay.sofa.registry.common.model.ConnectId; -import com.alipay.sofa.registry.common.model.store.Publisher; - -/** - * @author yuzhi.lyz - * @version v 0.1 2020-12-12 15:14 yuzhi.lyz Exp $ - */ -public final class PublisherWriteDataRequest implements WriteDataRequest { - private final Publisher publisher; - private final WriteDataRequestType type; - - public PublisherWriteDataRequest(Publisher publisher, WriteDataRequestType type) { - this.publisher = publisher; - this.type = type; - } - - @Override - public Publisher getRequestBody() { - return publisher; - } - - @Override - public WriteDataRequestType getRequestType() { - return type; - } - - @Override - public ConnectId getConnectId() { - return publisher.connectId(); - } -} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataProcessor.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataProcessor.java deleted file mode 100644 index d420938a5..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataProcessor.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.acceptor; - -import com.alipay.sofa.registry.common.model.ConnectId; -import com.alipay.sofa.registry.log.Logger; -import com.alipay.sofa.registry.log.LoggerFactory; -import com.alipay.sofa.registry.server.session.node.service.DataNodeService; - -/** - * @author kezhu.wukz - * @author shangyu.wh - * @version 1.0: WriteDataProcessor.java, v 0.1 2019-06-06 12:50 shangyu.wh Exp $ - */ -public class WriteDataProcessor { - - private static final Logger LOGGER = LoggerFactory.getLogger(WriteDataProcessor.class); - - private final ConnectId connectId; - - private final DataNodeService dataNodeService; - - public WriteDataProcessor(ConnectId connectId, DataNodeService dataNodeService) { - this.connectId = connectId; - this.dataNodeService = dataNodeService; - } - - public boolean process(WriteDataRequest request) { - switch (request.getRequestType()) { - case PUBLISHER: - doPublishAsync(request); - return true; - case UN_PUBLISHER: - doUnPublishAsync(request); - return true; - case CLIENT_OFF: - doClientOffAsync(request); - return true; - default: - LOGGER.error( - "Unknown request type, connectId={}, requestType={}, requestBody={}", - connectId, - request.getRequestType(), - request.getRequestBody()); - } - return false; - } - - private void doClientOffAsync(WriteDataRequest request) { - ClientOffWriteDataRequest req = (ClientOffWriteDataRequest) request; - dataNodeService.clientOff(req.getRequestBody()); - } - - private void doUnPublishAsync(WriteDataRequest request) { - PublisherWriteDataRequest req = (PublisherWriteDataRequest) request; - dataNodeService.unregister(req.getRequestBody()); - } - - private void doPublishAsync(WriteDataRequest request) { - PublisherWriteDataRequest req = (PublisherWriteDataRequest) request; - dataNodeService.register(req.getRequestBody()); - } -} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataProcessorTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataProcessorTest.java deleted file mode 100644 index fae49a486..000000000 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataProcessorTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.acceptor; - -import com.alipay.sofa.registry.common.model.ClientOffPublishers; -import com.alipay.sofa.registry.common.model.ConnectId; -import com.alipay.sofa.registry.common.model.store.Publisher; -import com.alipay.sofa.registry.server.session.TestUtils; -import com.alipay.sofa.registry.server.session.node.service.DataNodeService; -import com.google.common.collect.Lists; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; - -public class WriteDataProcessorTest { - - @Test - public void test() { - DataNodeService dataNodeService = Mockito.mock(DataNodeService.class); - Publisher p = TestUtils.createTestPublisher("testDataId"); - ConnectId connectId = p.connectId(); - WriteDataAcceptorImpl impl = new WriteDataAcceptorImpl(); - impl.dataNodeService = Mockito.mock(DataNodeService.class); - - WriteDataProcessor processor = new WriteDataProcessor(connectId, dataNodeService); - - ClientOffWriteDataRequest off = new ClientOffWriteDataRequest(connectId, Lists.newArrayList(p)); - ClientOffPublishers offPublishers = off.getRequestBody(); - Assert.assertEquals(off.getConnectId(), connectId); - Assert.assertEquals(off.getRequestType(), WriteDataRequest.WriteDataRequestType.CLIENT_OFF); - Assert.assertEquals(offPublishers.getConnectId(), connectId); - Assert.assertEquals(offPublishers.getPublishers().size(), 1); - Assert.assertEquals(offPublishers.getPublishers().get(0), p); - Assert.assertFalse(offPublishers.isEmpty()); - - Assert.assertTrue(processor.process(off)); - impl.accept(off); - Mockito.verify(dataNodeService, Mockito.times(1)).clientOff(offPublishers); - Mockito.verify(impl.dataNodeService, Mockito.times(1)).clientOff(offPublishers); - - PublisherWriteDataRequest pub = - new PublisherWriteDataRequest(p, WriteDataRequest.WriteDataRequestType.PUBLISHER); - Assert.assertEquals(pub.getConnectId(), connectId); - Assert.assertEquals(pub.getRequestType(), WriteDataRequest.WriteDataRequestType.PUBLISHER); - Assert.assertEquals(pub.getConnectId(), connectId); - Assert.assertTrue(processor.process(pub)); - impl.accept(pub); - Mockito.verify(dataNodeService, Mockito.times(1)).register(p); - Mockito.verify(impl.dataNodeService, Mockito.times(1)).register(p); - - pub = new PublisherWriteDataRequest(p, WriteDataRequest.WriteDataRequestType.UN_PUBLISHER); - Assert.assertEquals(pub.getConnectId(), connectId); - Assert.assertEquals(pub.getRequestType(), WriteDataRequest.WriteDataRequestType.UN_PUBLISHER); - Assert.assertEquals(pub.getConnectId(), connectId); - Assert.assertTrue(processor.process(pub)); - impl.accept(pub); - Mockito.verify(dataNodeService, Mockito.times(1)).unregister(p); - Mockito.verify(impl.dataNodeService, Mockito.times(1)).register(p); - } -} From 486d8d4a3947c1997c8575f37f2946d70f2d6c47 Mon Sep 17 00:00:00 2001 From: linxin Date: Wed, 15 Feb 2023 11:17:22 +0800 Subject: [PATCH 04/17] refactor session.acceptor module: 1. remove WriteDataProcessor: avoid creating unnecessary objects 2. standardize the use of generic types to avoid code warnings --- .../acceptor/ClientOffWriteDataRequest.java | 2 +- .../PublisherRegisterWriteDataRequest.java | 45 +++++++++++++ .../PublisherUnregisterWriteDataRequest.java | 45 +++++++++++++ .../session/acceptor/WriteDataAcceptor.java | 4 +- .../acceptor/WriteDataAcceptorImpl.java | 40 +++++++++++- .../session/acceptor/WriteDataRequest.java | 28 +++++--- .../session/registry/SessionRegistry.java | 12 ++-- .../acceptor/WriteDataAcceptorTest.java | 65 +++++++++++++++++++ 8 files changed, 218 insertions(+), 23 deletions(-) create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherRegisterWriteDataRequest.java create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherUnregisterWriteDataRequest.java create mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptorTest.java diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/ClientOffWriteDataRequest.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/ClientOffWriteDataRequest.java index 66f8c6f0e..686737898 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/ClientOffWriteDataRequest.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/ClientOffWriteDataRequest.java @@ -26,8 +26,8 @@ * @version v 0.1 2020-12-12 15:20 yuzhi.lyz Exp $ */ public final class ClientOffWriteDataRequest implements WriteDataRequest { - private final ConnectId connectId; + private final ConnectId connectId; private final ClientOffPublishers requestBody; public ClientOffWriteDataRequest(ConnectId connectId, List publishers) { diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherRegisterWriteDataRequest.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherRegisterWriteDataRequest.java new file mode 100644 index 000000000..7c9343bcf --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherRegisterWriteDataRequest.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.acceptor; + +import com.alipay.sofa.registry.common.model.ConnectId; +import com.alipay.sofa.registry.common.model.store.Publisher; + +/** WriteDataRequest of publisher register. */ +public final class PublisherRegisterWriteDataRequest implements WriteDataRequest { + + private final Publisher publisher; + + public PublisherRegisterWriteDataRequest(Publisher publisher) { + this.publisher = publisher; + } + + @Override + public Publisher getRequestBody() { + return publisher; + } + + @Override + public WriteDataRequestType getRequestType() { + return WriteDataRequestType.PUBLISHER; + } + + @Override + public ConnectId getConnectId() { + return publisher.connectId(); + } +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherUnregisterWriteDataRequest.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherUnregisterWriteDataRequest.java new file mode 100644 index 000000000..5dde4bf1b --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/PublisherUnregisterWriteDataRequest.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.acceptor; + +import com.alipay.sofa.registry.common.model.ConnectId; +import com.alipay.sofa.registry.common.model.store.Publisher; + +/** WriteDataRequest of publisher unregister. */ +public final class PublisherUnregisterWriteDataRequest implements WriteDataRequest { + + private final Publisher publisher; + + public PublisherUnregisterWriteDataRequest(Publisher publisher) { + this.publisher = publisher; + } + + @Override + public Publisher getRequestBody() { + return publisher; + } + + @Override + public WriteDataRequestType getRequestType() { + return WriteDataRequestType.UN_PUBLISHER; + } + + @Override + public ConnectId getConnectId() { + return publisher.connectId(); + } +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptor.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptor.java index 659a1169e..759bba167 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptor.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptor.java @@ -26,7 +26,7 @@ public interface WriteDataAcceptor { /** * accept all write data request * - * @param request + * @param request {@link WriteDataRequest} */ - void accept(WriteDataRequest request); + void accept(WriteDataRequest request); } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptorImpl.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptorImpl.java index f058e8970..8a74828fe 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptorImpl.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptorImpl.java @@ -17,6 +17,8 @@ package com.alipay.sofa.registry.server.session.acceptor; import com.alipay.sofa.registry.common.model.ConnectId; +import com.alipay.sofa.registry.log.Logger; +import com.alipay.sofa.registry.log.LoggerFactory; import com.alipay.sofa.registry.server.session.node.service.DataNodeService; import org.springframework.beans.factory.annotation.Autowired; @@ -27,11 +29,43 @@ */ public class WriteDataAcceptorImpl implements WriteDataAcceptor { + private static final Logger LOGGER = LoggerFactory.getLogger(WriteDataAcceptorImpl.class); + @Autowired DataNodeService dataNodeService; - public void accept(WriteDataRequest request) { + public void accept(WriteDataRequest request) { ConnectId connectId = request.getConnectId(); - WriteDataProcessor writeDataProcessor = new WriteDataProcessor(connectId, dataNodeService); - writeDataProcessor.process(request); + switch (request.getRequestType()) { + case PUBLISHER: + doPublishAsync(request); + return; + case UN_PUBLISHER: + doUnPublishAsync(request); + return; + case CLIENT_OFF: + doClientOffAsync(request); + return; + default: + LOGGER.error( + "Unknown request type, connectId={}, requestType={}, requestBody={}", + connectId, + request.getRequestType(), + request.getRequestBody()); + } + } + + private void doClientOffAsync(WriteDataRequest request) { + ClientOffWriteDataRequest req = (ClientOffWriteDataRequest) request; + dataNodeService.clientOff(req.getRequestBody()); + } + + private void doUnPublishAsync(WriteDataRequest request) { + PublisherUnregisterWriteDataRequest req = (PublisherUnregisterWriteDataRequest) request; + dataNodeService.unregister(req.getRequestBody()); + } + + private void doPublishAsync(WriteDataRequest request) { + PublisherRegisterWriteDataRequest req = (PublisherRegisterWriteDataRequest) request; + dataNodeService.register(req.getRequestBody()); } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataRequest.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataRequest.java index 570ff2111..734d1a567 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataRequest.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataRequest.java @@ -25,12 +25,19 @@ */ public interface WriteDataRequest { - /** The enum for request type */ - enum WriteDataRequestType { - PUBLISHER, - UN_PUBLISHER, - CLIENT_OFF - } + /** + * ConnectId. + * + * @return ConnectId + */ + ConnectId getConnectId(); + + /** + * Type of the request. + * + * @return WriteDataRequestType + */ + WriteDataRequestType getRequestType(); /** * Gets request body. @@ -39,7 +46,10 @@ enum WriteDataRequestType { */ T getRequestBody(); - WriteDataRequestType getRequestType(); - - ConnectId getConnectId(); + /** The enum for request type. */ + enum WriteDataRequestType { + PUBLISHER, + UN_PUBLISHER, + CLIENT_OFF + } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java index 51c6b27d5..652d96eff 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java @@ -27,9 +27,9 @@ import com.alipay.sofa.registry.remoting.exchange.Exchange; import com.alipay.sofa.registry.remoting.exchange.ExchangeCallback; import com.alipay.sofa.registry.server.session.acceptor.ClientOffWriteDataRequest; -import com.alipay.sofa.registry.server.session.acceptor.PublisherWriteDataRequest; +import com.alipay.sofa.registry.server.session.acceptor.PublisherRegisterWriteDataRequest; +import com.alipay.sofa.registry.server.session.acceptor.PublisherUnregisterWriteDataRequest; import com.alipay.sofa.registry.server.session.acceptor.WriteDataAcceptor; -import com.alipay.sofa.registry.server.session.acceptor.WriteDataRequest; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; import com.alipay.sofa.registry.server.session.interceptor.OrderedInterceptorManager; import com.alipay.sofa.registry.server.session.interceptor.RegisterInvokeData; @@ -132,9 +132,7 @@ public void register(StoreData storeData, Channel channel) { } // All write operations to DataServer (pub/unPub/clientoff/renew/snapshot) // are handed over to WriteDataAcceptor - writeDataAcceptor.accept( - new PublisherWriteDataRequest( - publisher, WriteDataRequest.WriteDataRequestType.PUBLISHER)); + writeDataAcceptor.accept(new PublisherRegisterWriteDataRequest(publisher)); sessionRegistryStrategy.afterPublisherRegister(publisher); break; @@ -173,9 +171,7 @@ public void unRegister(StoreData storeData) { sessionDataStore.deleteById(storeData.getId(), publisher.getDataInfoId()); // All write operations to DataServer (pub/unPub/clientoff) // are handed over to WriteDataAcceptor - writeDataAcceptor.accept( - new PublisherWriteDataRequest( - publisher, WriteDataRequest.WriteDataRequestType.UN_PUBLISHER)); + writeDataAcceptor.accept(new PublisherUnregisterWriteDataRequest(publisher)); sessionRegistryStrategy.afterPublisherUnRegister(publisher); break; diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptorTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptorTest.java new file mode 100644 index 000000000..e22bd4277 --- /dev/null +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/acceptor/WriteDataAcceptorTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.acceptor; + +import com.alipay.sofa.registry.common.model.ClientOffPublishers; +import com.alipay.sofa.registry.common.model.ConnectId; +import com.alipay.sofa.registry.common.model.store.Publisher; +import com.alipay.sofa.registry.server.session.TestUtils; +import com.alipay.sofa.registry.server.session.node.service.DataNodeService; +import com.google.common.collect.Lists; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +/** */ +public class WriteDataAcceptorTest { + + @Test + public void test() { + Publisher p = TestUtils.createTestPublisher("testDataId"); + ConnectId connectId = p.connectId(); + WriteDataAcceptorImpl impl = new WriteDataAcceptorImpl(); + impl.dataNodeService = Mockito.mock(DataNodeService.class); + + ClientOffWriteDataRequest off = new ClientOffWriteDataRequest(connectId, Lists.newArrayList(p)); + ClientOffPublishers offPublishers = off.getRequestBody(); + Assert.assertEquals(off.getConnectId(), connectId); + Assert.assertEquals(off.getRequestType(), WriteDataRequest.WriteDataRequestType.CLIENT_OFF); + Assert.assertEquals(offPublishers.getConnectId(), connectId); + Assert.assertEquals(offPublishers.getPublishers().size(), 1); + Assert.assertEquals(offPublishers.getPublishers().get(0), p); + Assert.assertFalse(offPublishers.isEmpty()); + + impl.accept(off); + Mockito.verify(impl.dataNodeService, Mockito.times(1)).clientOff(offPublishers); + + PublisherRegisterWriteDataRequest pub = new PublisherRegisterWriteDataRequest(p); + Assert.assertEquals(pub.getConnectId(), connectId); + Assert.assertEquals(pub.getRequestType(), WriteDataRequest.WriteDataRequestType.PUBLISHER); + Assert.assertEquals(pub.getConnectId(), connectId); + impl.accept(pub); + Mockito.verify(impl.dataNodeService, Mockito.times(1)).register(p); + + PublisherUnregisterWriteDataRequest unpub = new PublisherUnregisterWriteDataRequest(p); + Assert.assertEquals(unpub.getConnectId(), connectId); + Assert.assertEquals(unpub.getRequestType(), WriteDataRequest.WriteDataRequestType.UN_PUBLISHER); + Assert.assertEquals(unpub.getConnectId(), connectId); + impl.accept(unpub); + Mockito.verify(impl.dataNodeService, Mockito.times(1)).register(p); + } +} From 6ba4c0a4da93fca42cf8116fb306375268d522d3 Mon Sep 17 00:00:00 2001 From: linxin Date: Wed, 15 Feb 2023 14:59:42 +0800 Subject: [PATCH 05/17] skip SessionRegistry#process when interceptor execute fail --- .../interceptor/ClientOffInterceptor.java | 2 +- .../interceptor/InterceptorManager.java | 3 +- .../OrderedInterceptorManager.java | 7 +- .../session/registry/SessionRegistry.java | 67 ++++++++++--------- 4 files changed, 42 insertions(+), 37 deletions(-) diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/ClientOffInterceptor.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/ClientOffInterceptor.java index 91b7b0d0c..3662bb8d1 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/ClientOffInterceptor.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/ClientOffInterceptor.java @@ -69,7 +69,7 @@ public boolean process(RegisterInvokeData registerInvokeData) LOGGER.error( "failed to unRegister publisher {}, source={}", storeData.getDataInfoId(), url, e); } - return true; + return false; } if (StoreData.DataType.SUBSCRIBER == storeData.getDataType()) { diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/InterceptorManager.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/InterceptorManager.java index 8141dcea9..fc51e1eff 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/InterceptorManager.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/InterceptorManager.java @@ -32,9 +32,10 @@ public interface InterceptorManager { * Execute all interceptors in order. * * @param registerInvokeData data + * @return true if all interceptors executed successful * @throws InterceptorExecutionException throw when any interceptor encounters an exception, and * stop executing subsequent interceptors */ - void executeInterceptors(RegisterInvokeData registerInvokeData) + boolean executeInterceptors(RegisterInvokeData registerInvokeData) throws InterceptorExecutionException; } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java index 8207358d7..9f429eba9 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManager.java @@ -42,10 +42,10 @@ public void addInterceptor(Interceptor interceptor) { } @Override - public void executeInterceptors(RegisterInvokeData registerInvokeData) + public boolean executeInterceptors(RegisterInvokeData registerInvokeData) throws InterceptorExecutionException { if (interceptors.size() == 0) { - return; + return true; } for (Interceptor interceptor : interceptors) { @@ -53,7 +53,7 @@ public void executeInterceptors(RegisterInvokeData registerInvokeData) boolean result = interceptor.process(registerInvokeData); if (!result) { LOGGER.warn("interceptor({}) return false, skip all subsequent interceptors"); - break; + return false; } } catch (InterceptorExecutionException e) { LOGGER.error( @@ -77,5 +77,6 @@ public void executeInterceptors(RegisterInvokeData registerInvokeData) cause); } } + return true; } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java index 51c6b27d5..427e6a58e 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java @@ -112,8 +112,9 @@ public void init() { public void register(StoreData storeData, Channel channel) { RegisterInvokeData registerInvokeData = new RegisterInvokeData(storeData, channel); + boolean allInterceptorsSuccess = true; try { - orderedInterceptorManager.executeInterceptors(registerInvokeData); + allInterceptorsSuccess = orderedInterceptorManager.executeInterceptors(registerInvokeData); } catch (Exception e) { LOGGER.error( "interceptors process data(dataId={}) encountered an unexpected exception", @@ -122,43 +123,45 @@ public void register(StoreData storeData, Channel channel) { throw new RuntimeException("Proceed register error!", e); } - try { - switch (storeData.getDataType()) { - case PUBLISHER: - Publisher publisher = (Publisher) storeData; - publisher.setSessionProcessId(ServerEnv.PROCESS_ID); - if (!sessionDataStore.add(publisher)) { - break; - } - // All write operations to DataServer (pub/unPub/clientoff/renew/snapshot) - // are handed over to WriteDataAcceptor - writeDataAcceptor.accept( - new PublisherWriteDataRequest( - publisher, WriteDataRequest.WriteDataRequestType.PUBLISHER)); + if (allInterceptorsSuccess) { + try { + switch (storeData.getDataType()) { + case PUBLISHER: + Publisher publisher = (Publisher) storeData; + publisher.setSessionProcessId(ServerEnv.PROCESS_ID); + if (!sessionDataStore.add(publisher)) { + break; + } + // All write operations to DataServer (pub/unPub/clientoff/renew/snapshot) + // are handed over to WriteDataAcceptor + writeDataAcceptor.accept( + new PublisherWriteDataRequest( + publisher, WriteDataRequest.WriteDataRequestType.PUBLISHER)); - sessionRegistryStrategy.afterPublisherRegister(publisher); - break; - case SUBSCRIBER: - Subscriber subscriber = (Subscriber) storeData; - if (!sessionInterests.add(subscriber)) { + sessionRegistryStrategy.afterPublisherRegister(publisher); break; - } + case SUBSCRIBER: + Subscriber subscriber = (Subscriber) storeData; + if (!sessionInterests.add(subscriber)) { + break; + } - sessionRegistryStrategy.afterSubscriberRegister(subscriber); - break; - case WATCHER: - Watcher watcher = (Watcher) storeData; - if (!sessionWatchers.add(watcher)) { + sessionRegistryStrategy.afterSubscriberRegister(subscriber); break; - } + case WATCHER: + Watcher watcher = (Watcher) storeData; + if (!sessionWatchers.add(watcher)) { + break; + } - sessionRegistryStrategy.afterWatcherRegister(watcher); - break; - default: - break; + sessionRegistryStrategy.afterWatcherRegister(watcher); + break; + default: + break; + } + } catch (Exception e) { + throw new RuntimeException("Proceed register error!", e); } - } catch (Exception e) { - throw new RuntimeException("Proceed register error!", e); } } From 7f44d1174b103d4142d44bcc51e4a821fcb722dd Mon Sep 17 00:00:00 2001 From: linxin Date: Sat, 18 Feb 2023 22:17:45 +0800 Subject: [PATCH 06/17] Add BufferdDataWritingEngine and simplify DataNodeServiceImpl --- .../model/dataserver/ClientOffPublisher.java | 11 +- .../model/dataserver/DataServerReq.java | 28 ++ .../registry/common/model/store/BaseInfo.java | 3 +- .../service/BufferedDataWritingEngine.java | 310 ++++++++++++++++++ .../node/service/DataNodeServiceImpl.java | 198 +---------- .../node/service/DataWritingEngine.java | 30 ++ 6 files changed, 391 insertions(+), 189 deletions(-) create mode 100644 server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/DataServerReq.java create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataWritingEngine.java diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/ClientOffPublisher.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/ClientOffPublisher.java index ecdf971b6..bde0da550 100644 --- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/ClientOffPublisher.java +++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/ClientOffPublisher.java @@ -29,13 +29,15 @@ * @author qian.lqlq * @version $Id: ClientOffPublisher.java, v 0.1 2017-12-01 15:48 qian.lqlq Exp $ */ -public final class ClientOffPublisher implements Serializable { +public final class ClientOffPublisher implements Serializable, DataServerReq { private static final long serialVersionUID = -3547806571058756207L; + private final String dataInfoId; private final ConnectId connectId; private final Map> publisherMap = Maps.newHashMap(); - public ClientOffPublisher(ConnectId connectId) { + public ClientOffPublisher(String dataInfoId, ConnectId connectId) { + this.dataInfoId = dataInfoId; this.connectId = connectId; } @@ -61,4 +63,9 @@ public boolean isEmpty() { public String toString() { return "ClientOff{" + "connId=" + connectId + ", pubs=" + publisherMap + '}'; } + + @Override + public String getDataInfoId() { + return dataInfoId; + } } diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/DataServerReq.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/DataServerReq.java new file mode 100644 index 000000000..040c3d254 --- /dev/null +++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/DataServerReq.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.common.model.dataserver; + +/** Request to write to DataNode. */ +public interface DataServerReq { + + /** + * Info id of data. + * + * @return data info id + */ + String getDataInfoId(); +} diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/BaseInfo.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/BaseInfo.java index 28675e5e5..4becc1192 100644 --- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/BaseInfo.java +++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/BaseInfo.java @@ -18,6 +18,7 @@ import com.alipay.sofa.registry.common.model.ConnectId; import com.alipay.sofa.registry.common.model.RegisterVersion; +import com.alipay.sofa.registry.common.model.dataserver.DataServerReq; import com.fasterxml.jackson.annotation.JsonIgnore; import com.google.common.collect.Maps; import java.io.Serializable; @@ -30,7 +31,7 @@ * @author shangyu.wh * @version $Id: BaseInfo.java, v 0.1 2017-11-30 16:31 shangyu.wh Exp $ */ -public abstract class BaseInfo implements Serializable, StoreData { +public abstract class BaseInfo implements Serializable, StoreData, DataServerReq { private static final long serialVersionUID = -6263388188316303789L; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java new file mode 100644 index 000000000..f768cab05 --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java @@ -0,0 +1,310 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.node.service; + +import com.alipay.sofa.registry.common.model.CommonResponse; +import com.alipay.sofa.registry.common.model.dataserver.BatchRequest; +import com.alipay.sofa.registry.common.model.dataserver.DataServerReq; +import com.alipay.sofa.registry.common.model.slot.Slot; +import com.alipay.sofa.registry.common.model.slot.SlotAccessGenericResponse; +import com.alipay.sofa.registry.common.model.store.URL; +import com.alipay.sofa.registry.log.Logger; +import com.alipay.sofa.registry.log.LoggerFactory; +import com.alipay.sofa.registry.remoting.exchange.NodeExchanger; +import com.alipay.sofa.registry.remoting.exchange.RequestException; +import com.alipay.sofa.registry.remoting.exchange.message.Request; +import com.alipay.sofa.registry.remoting.exchange.message.Response; +import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; +import com.alipay.sofa.registry.server.session.slot.SlotTableCache; +import com.alipay.sofa.registry.server.shared.env.ServerEnv; +import com.alipay.sofa.registry.task.FastRejectedExecutionException; +import com.alipay.sofa.registry.util.ParaCheckUtil; +import com.alipay.sofa.registry.util.StringFormatter; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import org.apache.commons.lang.StringUtils; + +/** DataWritingEngine implementation that can cache write requests. */ +public class BufferedDataWritingEngine implements DataWritingEngine { + + private static final Logger LOGGER = LoggerFactory.getLogger(BufferedDataWritingEngine.class); + + private final int avgSingleQueueBufferSize; + private final int halfMaximumBufferSize; + private final SlotTableCache slotTableCache; + private final NodeExchanger dataNodeExchanger; + private final SpinyWorker[] workers; + + private final int dataNodeRetryTimes; + private final int dataNodeRetryQueueSize; + private final int dataNodeRetryBackoffMillis; + private final int dataNodePort; + + /** + * Create an {@link DataWritingEngine} with cache capability. The maximum number of cached + * requests is twice that of {@param halfMaximumBufferSize}. + * + * @param threads the total threads to execute request in the engine + * @param halfMaximumBufferSize the half of the maximum cached requests + * @param maxBatchSize the max size of requests batch + */ + public BufferedDataWritingEngine( + int threads, + int halfMaximumBufferSize, + int maxBatchSize, + SessionServerConfig sessionServerConfig, + SlotTableCache slotTableCache, + NodeExchanger dataNodeExchanger) { + ParaCheckUtil.checkIsPositive(threads, "threads"); + ParaCheckUtil.checkIsPositive(halfMaximumBufferSize, "halfMaximumBufferSize"); + + this.workers = new SpinyWorker[threads]; + for (int i = 0; i < threads; i++) { + this.workers[i] = + new SpinyWorker("req-data-worker-" + i, halfMaximumBufferSize, maxBatchSize); + } + this.avgSingleQueueBufferSize = halfMaximumBufferSize / threads; + this.halfMaximumBufferSize = halfMaximumBufferSize; + this.slotTableCache = slotTableCache; + this.dataNodeExchanger = dataNodeExchanger; + this.dataNodeRetryTimes = sessionServerConfig.getDataNodeRetryTimes(); + this.dataNodeRetryQueueSize = sessionServerConfig.getDataNodeRetryQueueSize(); + this.dataNodeRetryBackoffMillis = sessionServerConfig.getDataNodeRetryBackoffMillis(); + this.dataNodePort = sessionServerConfig.getDataServerPort(); + } + + @Override + public void submit(DataServerReq dataServerReq) { + final int slotId = slotTableCache.slotOf(dataServerReq.getDataInfoId()); + int idx = slotId % workers.length; + SpinyWorker worker = this.workers[idx]; + + int singleWorkerCachedRequest; + int totalCachedRequests = -1; + boolean failed = true; + /* + For example: avgSingleQueueBufferSize = 4 & halfMaximumBufferSize = 16 (that means we have 4 worker) + we can successfully add 16 elements to one worker, and at most add 4 elements to other 3 workers, + so in the end we totally cached 16 + 12 < 32 (two times of halfMaximumBufferSize) + */ + if ((singleWorkerCachedRequest = worker.cachedRequests()) <= avgSingleQueueBufferSize + || (totalCachedRequests = totalCachedRequests()) <= halfMaximumBufferSize) { + failed = worker.offer(new Req(slotId, dataServerReq)); + } + if (failed) { + throw new FastRejectedExecutionException( + String.format( + "BlockingQueues.put overflow, idx=%d, totalSize=%d, queueSize=%d", + idx, totalCachedRequests, singleWorkerCachedRequest)); + } + } + + private int totalCachedRequests() { + int count = 0; + for (SpinyWorker worker : workers) { + count += worker.cachedRequests(); + } + return count; + } + + private class SpinyWorker { + + private final BlockingQueue blockingQueue; + private final LinkedList retryBatches; + + public SpinyWorker(String workerName, int bufferSize, int maxBatchSize) { + this.blockingQueue = new LinkedBlockingQueue<>(bufferSize); + this.retryBatches = Lists.newLinkedList(); + + Thread thread = + new Thread( + () -> { + while (true) { + try { + Req firstReq = blockingQueue.poll(200, TimeUnit.MILLISECONDS); + if (firstReq != null) { + Map> reqs = drainReq(blockingQueue, maxBatchSize); + // send by order, firstReq.slotId is the first one + LinkedList firstBatch = reqs.remove(firstReq.slotId); + if (firstBatch == null) { + firstBatch = Lists.newLinkedList(); + } + firstBatch.addFirst(firstReq.req); + request(firstReq.slotId, firstBatch); + for (Map.Entry> batch : reqs.entrySet()) { + request(batch.getKey(), batch.getValue()); + } + } + + if (!retryBatches.isEmpty()) { + final Iterator it = retryBatches.iterator(); + List retries = Lists.newArrayList(); + while (it.hasNext()) { + RetryBatch batch = it.next(); + it.remove(); + if (!request(batch.batch)) { + retries.add(batch); + } + } + for (RetryBatch retry : retries) { + retry(retry); + } + } + } catch (Throwable cause) { + LOGGER.safeError("failed to request batch", cause); + } + } + }); + thread.setName(workerName); + thread.setDaemon(false); + thread.start(); + } + + public boolean offer(Req req) { + return this.blockingQueue.offer(req); + } + + public int cachedRequests() { + return this.blockingQueue.size(); + } + + private Map> drainReq(BlockingQueue queue, int max) { + List reqs = new ArrayList<>(max); + queue.drainTo(reqs, max); + if (reqs.isEmpty()) { + return Collections.emptyMap(); + } + Map> ret = Maps.newLinkedHashMap(); + for (Req req : reqs) { + LinkedList objects = ret.computeIfAbsent(req.slotId, k -> Lists.newLinkedList()); + objects.add(req.req); + } + return ret; + } + + private void request(int slotId, List reqs) { + final BatchRequest batch = new BatchRequest(ServerEnv.PROCESS_ID, slotId, reqs); + if (!request(batch)) { + retry(new RetryBatch(batch)); + } + } + + private boolean request(BatchRequest batch) { + try { + final Slot slot = slotTableCache.getSlot(batch.getSlotId()); + if (slot == null) { + throw new RequestException( + StringFormatter.format("slot not found, slotId={}", batch.getSlotId())); + } + batch.setSlotTableEpoch(slotTableCache.getEpoch()); + batch.setSlotLeaderEpoch(slot.getLeaderEpoch()); + sendRequest( + new Request() { + @Override + public Object getRequestBody() { + return batch; + } + + @Override + public URL getRequestUrl() { + final String dataIp = slot.getLeader(); + if (StringUtils.isBlank(dataIp)) { + throw new RequestException(String.format("slot has no leader, slotId=%s", slot)); + } + return new URL(dataIp, dataNodePort); + } + }); + return true; + } catch (Throwable e) { + LOGGER.error("failed to request batch, {}", batch, e); + return false; + } + } + + private CommonResponse sendRequest(Request request) throws RequestException { + Response response = dataNodeExchanger.request(request); + Object result = response.getResult(); + SlotAccessGenericResponse resp = (SlotAccessGenericResponse) result; + if (!resp.isSuccess()) { + throw new RuntimeException( + String.format( + "response failed, target: %s, request: %s, message: %s", + request.getRequestUrl(), request.getRequestBody(), resp.getMessage())); + } + return resp; + } + + private void retry(RetryBatch retry) { + retry.retryCount++; + if (retry.retryCount <= dataNodeRetryTimes) { + if (retryBatches.size() >= dataNodeRetryQueueSize) { + // remove the oldest + retryBatches.removeFirst(); + } + retry.expireTimestamp = System.currentTimeMillis() + dataNodeRetryBackoffMillis; + retryBatches.add(retry); + } else { + LOGGER.warn( + "RetryBatch(slotId={}, sessionProcessId={}) reach the dataNodeRetryTimes({})", + retry.batch.getSlotId(), + retry.batch.getSessionProcessId(), + dataNodeRetryTimes); + } + } + } + + private static final class Req { + final int slotId; + final DataServerReq req; + + Req(int slotId, DataServerReq req) { + this.slotId = slotId; + this.req = req; + } + } + + private static final class RetryBatch { + final BatchRequest batch; + long expireTimestamp; + int retryCount; + + RetryBatch(BatchRequest batch) { + this.batch = batch; + } + + @Override + public String toString() { + return "RetryBatch{" + + "batch=" + + batch + + ", retry=" + + retryCount + + ", expire=" + + expireTimestamp + + '}'; + } + } +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataNodeServiceImpl.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataNodeServiceImpl.java index fe542cc51..f321476e2 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataNodeServiceImpl.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataNodeServiceImpl.java @@ -17,7 +17,6 @@ package com.alipay.sofa.registry.server.session.node.service; import com.alipay.sofa.registry.common.model.ClientOffPublishers; -import com.alipay.sofa.registry.common.model.CommonResponse; import com.alipay.sofa.registry.common.model.dataserver.*; import com.alipay.sofa.registry.common.model.slot.Slot; import com.alipay.sofa.registry.common.model.slot.SlotAccessGenericResponse; @@ -26,8 +25,6 @@ import com.alipay.sofa.registry.common.model.store.URL; import com.alipay.sofa.registry.common.model.store.UnPublisher; import com.alipay.sofa.registry.compress.CompressConstants; -import com.alipay.sofa.registry.log.Logger; -import com.alipay.sofa.registry.log.LoggerFactory; import com.alipay.sofa.registry.remoting.CallbackHandler; import com.alipay.sofa.registry.remoting.Channel; import com.alipay.sofa.registry.remoting.exchange.ExchangeCallback; @@ -40,20 +37,14 @@ import com.alipay.sofa.registry.server.session.slot.SlotTableCache; import com.alipay.sofa.registry.server.shared.env.ServerEnv; import com.alipay.sofa.registry.server.shared.util.DatumUtils; -import com.alipay.sofa.registry.task.BlockingQueues; -import com.alipay.sofa.registry.task.FastRejectedExecutionException; import com.alipay.sofa.registry.task.MetricsableThreadPoolExecutor; import com.alipay.sofa.registry.task.RejectedDiscardHandler; -import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.OsUtils; import com.alipay.sofa.registry.util.StringFormatter; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import java.util.*; -import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -64,16 +55,13 @@ */ public class DataNodeServiceImpl implements DataNodeService { - private static final Logger LOGGER = LoggerFactory.getLogger(DataNodeServiceImpl.class); - @Autowired private NodeExchanger dataNodeExchanger; @Autowired private SlotTableCache slotTableCache; @Autowired private SessionServerConfig sessionServerConfig; - private Worker[] workers; - private BlockingQueues blockingQueues; + private DataWritingEngine dataWritingEngine; final RejectedDiscardHandler discardHandler = new RejectedDiscardHandler(); private final ThreadPoolExecutor callbackExecutor = @@ -82,39 +70,25 @@ public class DataNodeServiceImpl implements DataNodeService { @PostConstruct public void init() { - this.workers = new Worker[sessionServerConfig.getDataNodeExecutorWorkerSize()]; - blockingQueues = - new BlockingQueues<>( + this.dataWritingEngine = + new BufferedDataWritingEngine( sessionServerConfig.getDataNodeExecutorWorkerSize(), sessionServerConfig.getDataNodeExecutorQueueSize(), - false); - for (int i = 0; i < workers.length; i++) { - workers[i] = new Worker(blockingQueues.getQueue(i)); - ConcurrentUtils.createDaemonThread("req-data-worker-" + i, workers[i]).start(); - } - } - - private void commitReq(int slotId, Req req) { - int idx = slotId % blockingQueues.queueNum(); - try { - blockingQueues.put(idx, req); - } catch (FastRejectedExecutionException e) { - throw new FastRejectedExecutionException( - String.format("commit req overflow, slotId=%d, %s", slotId, e.getMessage())); - } + sessionServerConfig.getDataNodeMaxBatchSize(), + sessionServerConfig, + slotTableCache, + dataNodeExchanger); } @Override public void register(final Publisher publisher) { - final int slotId = slotTableCache.slotOf(publisher.getDataInfoId()); - commitReq(slotId, new Req(slotId, publisher)); + dataWritingEngine.submit(publisher); } @Override public void unregister(final Publisher publisher) { - final int slotId = slotTableCache.slotOf(publisher.getDataInfoId()); UnPublisher unPublisher = UnPublisher.of(publisher); - commitReq(slotId, new Req(slotId, unPublisher)); + dataWritingEngine.submit(unPublisher); } @Override @@ -124,9 +98,8 @@ public void clientOff(ClientOffPublishers clientOffPublishers) { } Map groups = groupBySlot(clientOffPublishers); for (Map.Entry group : groups.entrySet()) { - final int slotId = group.getKey(); - final ClientOffPublisher clientOff = group.getValue(); - commitReq(slotId, new Req(slotId, clientOff)); + ClientOffPublisher clientOff = group.getValue(); + dataWritingEngine.submit(clientOff); } } @@ -262,19 +235,6 @@ public Integer getTimeout() { } } - private CommonResponse sendRequest(Request request) throws RequestException { - Response response = dataNodeExchanger.request(request); - Object result = response.getResult(); - SlotAccessGenericResponse resp = (SlotAccessGenericResponse) result; - if (!resp.isSuccess()) { - throw new RuntimeException( - String.format( - "response failed, target: %s, request: %s, message: %s", - request.getRequestUrl(), request.getRequestBody(), resp.getMessage())); - } - return resp; - } - private Slot getSlot(String dataInfoId) { final int slotId = slotTableCache.slotOf(dataInfoId); Slot slot = slotTableCache.getSlot(slotId); @@ -309,7 +269,7 @@ private Map groupBySlot(ClientOffPublishers clientO int slotId = slotTableCache.slotOf(dataInfoId); ClientOffPublisher request = ret.computeIfAbsent( - slotId, k -> new ClientOffPublisher(clientOffPublishers.getConnectId())); + slotId, k -> new ClientOffPublisher(dataInfoId, clientOffPublishers.getConnectId())); request.addPublisher(publisher); } return ret; @@ -324,138 +284,4 @@ private static final class Req { this.req = req; } } - - private static final class RetryBatch { - final BatchRequest batch; - long expireTimestamp; - int retryCount; - - RetryBatch(BatchRequest batch) { - this.batch = batch; - } - - @Override - public String toString() { - return "RetryBatch{" - + "batch=" - + batch - + ", retry=" - + retryCount - + ", expire=" - + expireTimestamp - + '}'; - } - } - - private final class Worker implements Runnable { - final BlockingQueue queue; - final LinkedList retryBatches = Lists.newLinkedList(); - - Worker(BlockingQueue queue) { - this.queue = queue; - } - - @Override - public void run() { - for (; ; ) { - try { - final Req firstReq = queue.poll(200, TimeUnit.MILLISECONDS); - if (firstReq != null) { - // TODO config max - Map> reqs = - drainReq(queue, sessionServerConfig.getDataNodeMaxBatchSize()); - // send by order, firstReq.slotId is the first one - LinkedList firstBatch = reqs.remove(firstReq.slotId); - if (firstBatch == null) { - firstBatch = Lists.newLinkedList(); - } - firstBatch.addFirst(firstReq.req); - request(firstReq.slotId, firstBatch); - for (Map.Entry> batch : reqs.entrySet()) { - request(batch.getKey(), batch.getValue()); - } - } - // check the retry - if (!retryBatches.isEmpty()) { - final Iterator it = retryBatches.iterator(); - List retries = Lists.newArrayList(); - while (it.hasNext()) { - RetryBatch batch = it.next(); - it.remove(); - if (!DataNodeServiceImpl.this.request(batch.batch)) { - retries.add(batch); - } - } - for (RetryBatch retry : retries) { - retry(retry); - } - } - } catch (Throwable e) { - LOGGER.safeError("failed to request batch", e); - } - } - } - - private boolean retry(RetryBatch retry) { - retry.retryCount++; - if (retry.retryCount <= sessionServerConfig.getDataNodeRetryTimes()) { - if (retryBatches.size() >= sessionServerConfig.getDataNodeRetryQueueSize()) { - // remove the oldest - retryBatches.removeFirst(); - } - retry.expireTimestamp = - System.currentTimeMillis() + sessionServerConfig.getDataNodeRetryBackoffMillis(); - retryBatches.add(retry); - return true; - } - return false; - } - - private boolean request(int slotId, List reqs) { - final BatchRequest batch = new BatchRequest(ServerEnv.PROCESS_ID, slotId, reqs); - if (!DataNodeServiceImpl.this.request(batch)) { - retry(new RetryBatch(batch)); - return false; - } - return true; - } - } - - private boolean request(BatchRequest batch) { - try { - final Slot slot = getSlot(batch.getSlotId()); - batch.setSlotTableEpoch(slotTableCache.getEpoch()); - batch.setSlotLeaderEpoch(slot.getLeaderEpoch()); - sendRequest( - new Request() { - @Override - public Object getRequestBody() { - return batch; - } - - @Override - public URL getRequestUrl() { - return getUrl(slot); - } - }); - return true; - } catch (Throwable e) { - LOGGER.error("failed to request batch, {}", batch, e); - return false; - } - } - - private Map> drainReq(BlockingQueue queue, int max) { - List reqs = new ArrayList<>(max); - queue.drainTo(reqs, max); - if (reqs.isEmpty()) { - return Collections.emptyMap(); - } - Map> ret = Maps.newLinkedHashMap(); - for (Req req : reqs) { - LinkedList objects = ret.computeIfAbsent(req.slotId, k -> Lists.newLinkedList()); - objects.add(req.req); - } - return ret; - } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataWritingEngine.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataWritingEngine.java new file mode 100644 index 000000000..3d2364758 --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataWritingEngine.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.node.service; + +import com.alipay.sofa.registry.common.model.dataserver.DataServerReq; + +/** Responsible for executing write data requests to DataNode. */ +public interface DataWritingEngine { + + /** + * Submit pending request. + * + * @param dataServerReq data request to write to DataNode + */ + void submit(DataServerReq dataServerReq); +} From 9731b806121496f59f8422646b3947100698c1f7 Mon Sep 17 00:00:00 2001 From: linxin Date: Sun, 19 Feb 2023 15:25:58 +0800 Subject: [PATCH 07/17] remove Req --- .../session/node/service/DataNodeServiceImpl.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataNodeServiceImpl.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataNodeServiceImpl.java index f321476e2..23b1110c2 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataNodeServiceImpl.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/DataNodeServiceImpl.java @@ -274,14 +274,4 @@ private Map groupBySlot(ClientOffPublishers clientO } return ret; } - - private static final class Req { - final int slotId; - final Object req; - - Req(int slotId, Object req) { - this.slotId = slotId; - this.req = req; - } - } } From 4d3923d2cd70f910dd59239351a2dd6a21ed5d5b Mon Sep 17 00:00:00 2001 From: linxin Date: Mon, 20 Feb 2023 10:51:15 +0800 Subject: [PATCH 08/17] fix code --- .../registry/server/session/registry/SessionRegistry.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java index ffb7c4049..b4edc7667 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java @@ -134,9 +134,7 @@ public void register(StoreData storeData, Channel channel) { } // All write operations to DataServer (pub/unPub/clientoff/renew/snapshot) // are handed over to WriteDataAcceptor - writeDataAcceptor.accept( - new PublisherWriteDataRequest( - publisher, WriteDataRequest.WriteDataRequestType.PUBLISHER)); + writeDataAcceptor.accept(new PublisherRegisterWriteDataRequest(publisher)); sessionRegistryStrategy.afterPublisherRegister(publisher); break; From f361afa5309ea886dfccd54ebfafd72ad113c563 Mon Sep 17 00:00:00 2001 From: linxin Date: Mon, 6 Mar 2023 19:30:00 +0800 Subject: [PATCH 09/17] fix cr --- .../node/service/BufferedDataWritingEngine.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java index f768cab05..89852a4d6 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java @@ -32,6 +32,7 @@ import com.alipay.sofa.registry.server.session.slot.SlotTableCache; import com.alipay.sofa.registry.server.shared.env.ServerEnv; import com.alipay.sofa.registry.task.FastRejectedExecutionException; +import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.ParaCheckUtil; import com.alipay.sofa.registry.util.StringFormatter; import com.google.common.collect.Lists; @@ -139,8 +140,8 @@ public SpinyWorker(String workerName, int bufferSize, int maxBatchSize) { this.blockingQueue = new LinkedBlockingQueue<>(bufferSize); this.retryBatches = Lists.newLinkedList(); - Thread thread = - new Thread( + ConcurrentUtils.createDaemonThread( + workerName, () -> { while (true) { try { @@ -177,10 +178,8 @@ public SpinyWorker(String workerName, int bufferSize, int maxBatchSize) { LOGGER.safeError("failed to request batch", cause); } } - }); - thread.setName(workerName); - thread.setDaemon(false); - thread.start(); + }) + .start(); } public boolean offer(Req req) { From e1d9d5bb3c46c9b7d2d29ad6ef8aca3b3fddc793 Mon Sep 17 00:00:00 2001 From: linxin Date: Thu, 9 Mar 2023 11:37:44 +0800 Subject: [PATCH 10/17] SessionRegistryStrategy->ClientRegistrationHook --- .../bootstrap/SessionServerBootstrap.java | 4 - .../bootstrap/SessionServerConfiguration.java | 5 - .../session/registry/SessionRegistry.java | 34 +-- ...ategy.java => ClientRegistrationHook.java} | 41 ++-- ...ava => DefaultClientRegistrationHook.java} | 154 +++++++------- .../DefaultClientRegistrationHookTest.java | 195 ++++++++++++++++++ .../DefaultSessionRegistryStrategyTest.java | 140 ------------- 7 files changed, 313 insertions(+), 260 deletions(-) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/{SessionRegistryStrategy.java => ClientRegistrationHook.java} (58%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/{DefaultSessionRegistryStrategy.java => DefaultClientRegistrationHook.java} (64%) create mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java delete mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSessionRegistryStrategyTest.java diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerBootstrap.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerBootstrap.java index b1befa1d5..72dd3e716 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerBootstrap.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerBootstrap.java @@ -36,7 +36,6 @@ import com.alipay.sofa.registry.server.session.providedata.ConfigProvideDataWatcher; import com.alipay.sofa.registry.server.session.remoting.handler.ClientNodeConnectionHandler; import com.alipay.sofa.registry.server.session.slot.SlotTableCache; -import com.alipay.sofa.registry.server.session.strategy.SessionRegistryStrategy; import com.alipay.sofa.registry.server.shared.env.ServerEnv; import com.alipay.sofa.registry.server.shared.meta.MetaServerService; import com.alipay.sofa.registry.server.shared.providedata.SystemPropertyProcessorManager; @@ -95,8 +94,6 @@ public class SessionServerBootstrap { @Autowired private ConfigProvideDataWatcher configProvideDataWatcher; - @Autowired private SessionRegistryStrategy sessionRegistryStrategy; - @Autowired private ClientManagerAddressRepository clientManagerAddressRepository; @Autowired private RecoverConfigRepository recoverConfigRepository; @@ -186,7 +183,6 @@ public void start() { return true; }); - sessionRegistryStrategy.start(); configProvideDataWatcher.start(); registerSerializer(); openConsoleServer(); diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java index 277fb7c0b..fa53a9f18 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java @@ -626,11 +626,6 @@ public CacheCountTask cacheCountTask() { @Configuration public static class SessionStrategyConfiguration { - @Bean - @ConditionalOnMissingBean - public SessionRegistryStrategy sessionRegistryStrategy() { - return new DefaultSessionRegistryStrategy(); - } @Bean @ConditionalOnMissingBean diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java index b4edc7667..6d079c5a1 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java @@ -43,7 +43,8 @@ import com.alipay.sofa.registry.server.session.store.DataStore; import com.alipay.sofa.registry.server.session.store.Interests; import com.alipay.sofa.registry.server.session.store.Watchers; -import com.alipay.sofa.registry.server.session.strategy.SessionRegistryStrategy; +import com.alipay.sofa.registry.server.session.strategy.ClientRegistrationHook; +import com.alipay.sofa.registry.server.session.strategy.impl.DefaultClientRegistrationHook; import com.alipay.sofa.registry.server.shared.env.ServerEnv; import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.LoopRunnable; @@ -88,8 +89,6 @@ public class SessionRegistry implements Registry { @Autowired protected Exchange boltExchange; - @Autowired protected SessionRegistryStrategy sessionRegistryStrategy; - @Autowired protected OrderedInterceptorManager orderedInterceptorManager; @Autowired protected WriteDataAcceptor writeDataAcceptor; @@ -101,9 +100,18 @@ public class SessionRegistry implements Registry { @Autowired protected ConfigProvideDataWatcher configProvideDataWatcher; private final VersionWatchDog versionWatchDog = new VersionWatchDog(); + private ClientRegistrationHook clientRegistrationHook; @PostConstruct public void init() { + this.clientRegistrationHook = + new DefaultClientRegistrationHook( + sessionServerConfig, + firePushService, + pushSwitchService, + configProvideDataWatcher, + sessionWatchers); + ConcurrentUtils.createDaemonThread("SessionVerWatchDog", versionWatchDog).start(); ConcurrentUtils.createDaemonThread("SessionClientWatchDog", new ClientWatchDog()).start(); } @@ -112,7 +120,7 @@ public void init() { public void register(StoreData storeData, Channel channel) { RegisterInvokeData registerInvokeData = new RegisterInvokeData(storeData, channel); - boolean allInterceptorsSuccess = true; + boolean allInterceptorsSuccess; try { allInterceptorsSuccess = orderedInterceptorManager.executeInterceptors(registerInvokeData); } catch (Exception e) { @@ -135,24 +143,21 @@ public void register(StoreData storeData, Channel channel) { // All write operations to DataServer (pub/unPub/clientoff/renew/snapshot) // are handed over to WriteDataAcceptor writeDataAcceptor.accept(new PublisherRegisterWriteDataRequest(publisher)); - - sessionRegistryStrategy.afterPublisherRegister(publisher); + clientRegistrationHook.afterClientRegister(storeData); break; case SUBSCRIBER: Subscriber subscriber = (Subscriber) storeData; if (!sessionInterests.add(subscriber)) { break; } - - sessionRegistryStrategy.afterSubscriberRegister(subscriber); + clientRegistrationHook.afterClientRegister(storeData); break; case WATCHER: Watcher watcher = (Watcher) storeData; if (!sessionWatchers.add(watcher)) { break; } - - sessionRegistryStrategy.afterWatcherRegister(watcher); + clientRegistrationHook.afterClientRegister(storeData); break; default: break; @@ -176,24 +181,21 @@ public void unRegister(StoreData storeData) { // are handed over to WriteDataAcceptor writeDataAcceptor.accept(new PublisherUnregisterWriteDataRequest(publisher)); - sessionRegistryStrategy.afterPublisherUnRegister(publisher); + clientRegistrationHook.afterClientUnregister(storeData); break; - case SUBSCRIBER: Subscriber subscriber = (Subscriber) storeData; if (sessionInterests.deleteById(storeData.getId(), subscriber.getDataInfoId()) == null) { break; } - sessionRegistryStrategy.afterSubscriberUnRegister(subscriber); + clientRegistrationHook.afterClientUnregister(storeData); break; - case WATCHER: Watcher watcher = (Watcher) storeData; - if (sessionWatchers.deleteById(watcher.getId(), watcher.getDataInfoId()) == null) { break; } - sessionRegistryStrategy.afterWatcherUnRegister(watcher); + clientRegistrationHook.afterClientUnregister(storeData); break; default: break; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/SessionRegistryStrategy.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/ClientRegistrationHook.java similarity index 58% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/SessionRegistryStrategy.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/ClientRegistrationHook.java index 38f197190..852a1e214 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/SessionRegistryStrategy.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/ClientRegistrationHook.java @@ -16,27 +16,22 @@ */ package com.alipay.sofa.registry.server.session.strategy; -import com.alipay.sofa.registry.common.model.store.Publisher; -import com.alipay.sofa.registry.common.model.store.Subscriber; -import com.alipay.sofa.registry.common.model.store.Watcher; - -/** - * @author xuanbei - * @since 2019/2/15 - */ -public interface SessionRegistryStrategy { - - void start(); - - void afterPublisherRegister(Publisher publisher); - - void afterSubscriberRegister(Subscriber subscriber); - - void afterWatcherRegister(Watcher watcher); - - void afterPublisherUnRegister(Publisher publisher); - - void afterSubscriberUnRegister(Subscriber subscriber); - - void afterWatcherUnRegister(Watcher watcher); +import com.alipay.sofa.registry.common.model.store.StoreData; + +/** Hook interfaces that are called back after client registration and unregistration. */ +public interface ClientRegistrationHook { + + /** + * Invoked after client register. + * + * @param storeData client + */ + void afterClientRegister(StoreData storeData); + + /** + * Invoked after client unregister. + * + * @param storeData client + */ + void afterClientUnregister(StoreData storeData); } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSessionRegistryStrategy.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHook.java similarity index 64% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSessionRegistryStrategy.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHook.java index c45066f1b..11e31073f 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSessionRegistryStrategy.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHook.java @@ -19,19 +19,17 @@ import com.alipay.sofa.registry.common.model.Tuple; import com.alipay.sofa.registry.common.model.metaserver.ProvideData; import com.alipay.sofa.registry.common.model.store.BaseInfo; -import com.alipay.sofa.registry.common.model.store.Publisher; +import com.alipay.sofa.registry.common.model.store.StoreData; import com.alipay.sofa.registry.common.model.store.Subscriber; import com.alipay.sofa.registry.common.model.store.Watcher; import com.alipay.sofa.registry.core.model.ReceivedConfigData; -import com.alipay.sofa.registry.log.Logger; -import com.alipay.sofa.registry.log.LoggerFactory; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; import com.alipay.sofa.registry.server.session.converter.ReceivedDataConverter; import com.alipay.sofa.registry.server.session.providedata.ConfigProvideDataWatcher; import com.alipay.sofa.registry.server.session.push.FirePushService; import com.alipay.sofa.registry.server.session.push.PushSwitchService; import com.alipay.sofa.registry.server.session.store.Watchers; -import com.alipay.sofa.registry.server.session.strategy.SessionRegistryStrategy; +import com.alipay.sofa.registry.server.session.strategy.ClientRegistrationHook; import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.LoopRunnable; import com.google.common.collect.Lists; @@ -41,51 +39,78 @@ import java.util.concurrent.TimeUnit; import org.apache.commons.collections.CollectionUtils; import org.glassfish.jersey.internal.guava.Sets; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * @author kezhu.wukz - * @author xuanbei - * @since 2019/2/15 - */ -public class DefaultSessionRegistryStrategy implements SessionRegistryStrategy { - private static final Logger LOGGER = - LoggerFactory.getLogger(DefaultSessionRegistryStrategy.class); - - @Autowired protected FirePushService firePushService; - - @Autowired protected SessionServerConfig sessionServerConfig; - - @Autowired protected PushSwitchService pushSwitchService; - - @Autowired protected ConfigProvideDataWatcher configProvideDataWatcher; - - @Autowired protected Watchers sessionWatchers; - - protected final WatcherScanDog watcherScanDog = new WatcherScanDog(); - private final Thread t = ConcurrentUtils.createDaemonThread("watcher-scan-dog", watcherScanDog); +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** Default implementation of {@link ClientRegistrationHook}. */ +public class DefaultClientRegistrationHook implements ClientRegistrationHook { + + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClientRegistrationHook.class); + + private final SessionServerConfig sessionServerConfig; + private final FirePushService firePushService; + private final PushSwitchService pushSwitchService; + private final ConfigProvideDataWatcher configProvideDataWatcher; + private final Watchers sessionWatchers; + + public DefaultClientRegistrationHook( + SessionServerConfig sessionServerConfig, + FirePushService firePushService, + PushSwitchService pushSwitchService, + ConfigProvideDataWatcher configProvideDataWatcher, + Watchers sessionWatchers) { + this.sessionServerConfig = sessionServerConfig; + this.firePushService = firePushService; + this.pushSwitchService = pushSwitchService; + this.configProvideDataWatcher = configProvideDataWatcher; + this.sessionWatchers = sessionWatchers; + ConcurrentUtils.createDaemonThread( + "watcher-scan-dog", + new LoopRunnable() { + @Override + public void runUnthrowable() { + processWatch(); + } + + @Override + public void waitingUnthrowable() { + ConcurrentUtils.sleepUninterruptibly( + sessionServerConfig.getScanWatcherIntervalMillis(), TimeUnit.MILLISECONDS); + } + }) + .start(); + } @Override - public void start() { - t.start(); + public void afterClientRegister(StoreData storeData) { + switch (storeData.getDataType()) { + case PUBLISHER: + // NOOP + break; + case SUBSCRIBER: + afterSubscriberRegister((Subscriber) storeData); + break; + case WATCHER: + afterWatcherRegister((Watcher) storeData); + break; + default: + throw new IllegalArgumentException( + "unsupported data type: " + storeData.getDataType().name()); + } } @Override - public void afterPublisherRegister(Publisher publisher) {} + public void afterClientUnregister(StoreData storeData) { + // NOOP + } - @Override - public void afterSubscriberRegister(Subscriber subscriber) { + private void afterSubscriberRegister(Subscriber subscriber) { if (pushSwitchService.canIpPush(subscriber.getSourceAddress().getIpAddress())) { firePushService.fireOnRegister(subscriber); } } - private boolean checkWatcherVersion(Watcher watcher) { - return watcher.getClientVersion() == BaseInfo.ClientVersion.StoreData; - } - - @Override - public void afterWatcherRegister(Watcher watcher) { + private void afterWatcherRegister(Watcher watcher) { if (!checkWatcherVersion(watcher)) { LOGGER.warn( "unsupported watch:{}, clientVersion={}", @@ -99,7 +124,7 @@ public void afterWatcherRegister(Watcher watcher) { if (!pushSwitchService.canIpPush(watcher.getSourceAddress().getIpAddress())) { return; } - ProvideData provideData = null; + ProvideData provideData; if (sessionServerConfig.isWatchConfigEnable()) { // the provideData maybe exist provideData = configProvideDataWatcher.get(watcher.getDataInfoId()); @@ -114,6 +139,10 @@ public void afterWatcherRegister(Watcher watcher) { } } + private boolean checkWatcherVersion(Watcher watcher) { + return watcher.getClientVersion() == BaseInfo.ClientVersion.StoreData; + } + boolean processWatchWhenWatchConfigDisable(Watcher w) { if (w.hasPushed()) { return false; @@ -172,41 +201,22 @@ Tuple, List> filter() { return Tuple.of(dataInfoIds, watchers); } - final class WatcherScanDog extends LoopRunnable { - - @Override - public void runUnthrowable() { - Tuple, List> filtered = filter(); - if (filtered == null) { - return; - } - final boolean watchConfigEnable = sessionServerConfig.isWatchConfigEnable(); - if (watchConfigEnable) { - configProvideDataWatcher.refreshWatch(filtered.o1); - } - - int count = 0; - for (Watcher w : filtered.o2) { - if (processWatch(w, watchConfigEnable)) { - count++; - } - } - LOGGER.info("fire watchers:{}", count); + void processWatch() { + Tuple, List> filtered = filter(); + if (filtered == null) { + return; + } + final boolean watchConfigEnable = sessionServerConfig.isWatchConfigEnable(); + if (watchConfigEnable) { + configProvideDataWatcher.refreshWatch(filtered.o1); } - @Override - public void waitingUnthrowable() { - ConcurrentUtils.sleepUninterruptibly( - sessionServerConfig.getScanWatcherIntervalMillis(), TimeUnit.MILLISECONDS); + int count = 0; + for (Watcher w : filtered.o2) { + if (processWatch(w, watchConfigEnable)) { + count++; + } } + LOGGER.info("fire watchers:{}", count); } - - @Override - public void afterPublisherUnRegister(Publisher publisher) {} - - @Override - public void afterSubscriberUnRegister(Subscriber subscriber) {} - - @Override - public void afterWatcherUnRegister(Watcher watcher) {} } diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java new file mode 100644 index 000000000..1f46e6500 --- /dev/null +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.strategy.impl; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.alipay.sofa.registry.common.model.Tuple; +import com.alipay.sofa.registry.common.model.metaserver.ProvideData; +import com.alipay.sofa.registry.common.model.store.BaseInfo; +import com.alipay.sofa.registry.common.model.store.Publisher; +import com.alipay.sofa.registry.common.model.store.Watcher; +import com.alipay.sofa.registry.server.session.AbstractSessionServerTestBase; +import com.alipay.sofa.registry.server.session.TestUtils; +import com.alipay.sofa.registry.server.session.providedata.ConfigProvideDataWatcher; +import com.alipay.sofa.registry.server.session.push.FirePushService; +import com.alipay.sofa.registry.server.session.push.PushSwitchService; +import com.alipay.sofa.registry.server.session.store.Watchers; +import com.google.common.collect.Sets; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** */ +public class DefaultClientRegistrationHookTest extends AbstractSessionServerTestBase { + + private final String dataId = "testWatcherDataId"; + + @Before + public void before() { + sessionServerConfig.setWatchConfigEnable(false); + sessionServerConfig.setScanWatcherIntervalMillis(10); + } + + @Test + public void testAfterPublisherRegister() { + DefaultClientRegistrationHook clientRegistrationHook = + new DefaultClientRegistrationHook( + sessionServerConfig, + mock(FirePushService.class), + mock(PushSwitchService.class), + mock(ConfigProvideDataWatcher.class), + mock(Watchers.class)); + clientRegistrationHook.afterClientRegister(new Publisher()); + } + + @Test + public void testAfterWatcherRegisterDisable() { + FirePushService firePushService = mock(FirePushService.class); + PushSwitchService pushSwitchService = mock(PushSwitchService.class); + Watchers sessionWatchers = mock(Watchers.class); + ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); + DefaultClientRegistrationHook clientRegistrationHook = + new DefaultClientRegistrationHook( + sessionServerConfig, + firePushService, + pushSwitchService, + configProvideDataWatcher, + sessionWatchers); + + Watcher w = TestUtils.newWatcher(dataId); + clientRegistrationHook.afterClientRegister(w); + + verify(firePushService, times(0)).fireOnWatcher(any(), any()); + + when(pushSwitchService.canIpPush(anyString())).thenReturn(true); + clientRegistrationHook.afterClientRegister(w); + verify(firePushService, times(1)).fireOnWatcher(any(), any()); + verify(configProvideDataWatcher, times(0)).watch(any()); + } + + @Test + public void testAfterWatcherRegisterEnable() { + sessionServerConfig.setWatchConfigEnable(true); + FirePushService firePushService = mock(FirePushService.class); + PushSwitchService pushSwitchService = mock(PushSwitchService.class); + Watchers sessionWatchers = mock(Watchers.class); + ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); + DefaultClientRegistrationHook clientRegistrationHook = + new DefaultClientRegistrationHook( + sessionServerConfig, + firePushService, + pushSwitchService, + configProvideDataWatcher, + sessionWatchers); + + Watcher w = TestUtils.newWatcher(dataId); + clientRegistrationHook.afterClientRegister(w); + verify(configProvideDataWatcher, times(1)).watch(any()); + verify(firePushService, times(0)).fireOnWatcher(any(), any()); + + when(pushSwitchService.canIpPush(anyString())).thenReturn(true); + clientRegistrationHook.afterClientRegister(w); + verify(firePushService, times(0)).fireOnWatcher(any(), any()); + + when(configProvideDataWatcher.get(anyString())) + .thenReturn(new ProvideData(null, "dataId", 100L)); + clientRegistrationHook.afterClientRegister(w); + verify(firePushService, times(1)).fireOnWatcher(any(), any()); + } + + @Test + public void testFilter() { + FirePushService firePushService = mock(FirePushService.class); + PushSwitchService pushSwitchService = mock(PushSwitchService.class); + Watchers sessionWatchers = mock(Watchers.class); + ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); + DefaultClientRegistrationHook clientRegistrationHook = + new DefaultClientRegistrationHook( + sessionServerConfig, + firePushService, + pushSwitchService, + configProvideDataWatcher, + sessionWatchers); + + Assert.assertNull(clientRegistrationHook.filter()); + Watcher w = TestUtils.newWatcher(dataId); + when(sessionWatchers.getDataList()).thenReturn(Collections.singletonList(w)); + Tuple, List> t = clientRegistrationHook.filter(); + Assert.assertEquals(t.o1, Sets.newHashSet(w.getDataInfoId())); + Assert.assertEquals(t.o2.get(0), w); + sessionServerConfig.setWatchConfigEnable(true); + clientRegistrationHook.processWatch(); + + w.setClientVersion(BaseInfo.ClientVersion.MProtocolpackage); + t = clientRegistrationHook.filter(); + Assert.assertEquals(0, t.o1.size()); + Assert.assertEquals(0, t.o2.size()); + + clientRegistrationHook.processWatch(); + clientRegistrationHook.afterClientRegister(w); + } + + @Test + public void testProcess() { + FirePushService firePushService = mock(FirePushService.class); + PushSwitchService pushSwitchService = mock(PushSwitchService.class); + Watchers sessionWatchers = mock(Watchers.class); + ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); + DefaultClientRegistrationHook clientRegistrationHook = + new DefaultClientRegistrationHook( + sessionServerConfig, + firePushService, + pushSwitchService, + configProvideDataWatcher, + sessionWatchers); + + Watcher w = TestUtils.newWatcher(dataId); + Assert.assertTrue(clientRegistrationHook.processWatchWhenWatchConfigDisable(w)); + verify(firePushService, times(1)).fireOnWatcher(any(), any()); + w.updatePushedVersion(10); + Assert.assertFalse(clientRegistrationHook.processWatchWhenWatchConfigDisable(w)); + + // reset watcher + w = TestUtils.newWatcher(dataId); + Assert.assertFalse(clientRegistrationHook.processWatchWhenWatchConfigEnable(w)); + ProvideData data = new ProvideData(null, dataId, 10L); + when(configProvideDataWatcher.get(anyString())).thenReturn(data); + Assert.assertTrue(clientRegistrationHook.processWatchWhenWatchConfigEnable(w)); + verify(firePushService, times(2)).fireOnWatcher(any(), any()); + w.updatePushedVersion(10); + + Assert.assertFalse(clientRegistrationHook.processWatchWhenWatchConfigEnable(w)); + verify(firePushService, times(2)).fireOnWatcher(any(), any()); + + data = new ProvideData(null, dataId, 20L); + when(configProvideDataWatcher.get(anyString())).thenReturn(data); + Assert.assertTrue(clientRegistrationHook.processWatchWhenWatchConfigEnable(w)); + verify(firePushService, times(3)).fireOnWatcher(any(), any()); + w.updatePushedVersion(20); + Assert.assertFalse(clientRegistrationHook.processWatch(w, false)); + Assert.assertFalse(clientRegistrationHook.processWatch(w, true)); + } +} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSessionRegistryStrategyTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSessionRegistryStrategyTest.java deleted file mode 100644 index 2c7c1a57d..000000000 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSessionRegistryStrategyTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.strategy.impl; - -import static org.mockito.Mockito.*; - -import com.alipay.sofa.registry.common.model.Tuple; -import com.alipay.sofa.registry.common.model.metaserver.ProvideData; -import com.alipay.sofa.registry.common.model.store.BaseInfo; -import com.alipay.sofa.registry.common.model.store.Publisher; -import com.alipay.sofa.registry.common.model.store.Watcher; -import com.alipay.sofa.registry.server.session.AbstractSessionServerTestBase; -import com.alipay.sofa.registry.server.session.TestUtils; -import com.alipay.sofa.registry.server.session.providedata.ConfigProvideDataWatcher; -import com.alipay.sofa.registry.server.session.push.FirePushService; -import com.alipay.sofa.registry.server.session.push.PushSwitchService; -import com.alipay.sofa.registry.server.session.store.Watchers; -import com.google.common.collect.Sets; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class DefaultSessionRegistryStrategyTest extends AbstractSessionServerTestBase { - - private DefaultSessionRegistryStrategy strategy = new DefaultSessionRegistryStrategy(); - private final String dataId = "testWatcherDataId"; - - @Before - public void beoforeDefaultSessionRegistryStrategyTest() { - sessionServerConfig.setWatchConfigEnable(false); - sessionServerConfig.setScanWatcherIntervalMillis(10); - strategy.sessionServerConfig = sessionServerConfig; - strategy.firePushService = mock(FirePushService.class); - strategy.pushSwitchService = mock(PushSwitchService.class); - strategy.sessionWatchers = mock(Watchers.class); - strategy.configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); - } - - @Test - public void testAfterPublisherRegister() { - strategy.afterPublisherRegister(new Publisher()); - } - - @Test - public void testAfterWatcherRegisterDisable() { - sessionServerConfig.setWatchConfigEnable(false); - Watcher w = TestUtils.newWatcher(dataId); - strategy.afterWatcherRegister(w); - verify(strategy.firePushService, times(0)).fireOnWatcher(any(), any()); - - when(strategy.pushSwitchService.canIpPush(anyString())).thenReturn(true); - strategy.afterWatcherRegister(w); - verify(strategy.firePushService, times(1)).fireOnWatcher(any(), any()); - verify(strategy.configProvideDataWatcher, times(0)).watch(any()); - } - - @Test - public void testAfterWatcherRegisterEnable() { - sessionServerConfig.setWatchConfigEnable(true); - Watcher w = TestUtils.newWatcher(dataId); - strategy.afterWatcherRegister(w); - verify(strategy.configProvideDataWatcher, times(1)).watch(any()); - verify(strategy.firePushService, times(0)).fireOnWatcher(any(), any()); - - when(strategy.pushSwitchService.canIpPush(anyString())).thenReturn(true); - strategy.afterWatcherRegister(w); - verify(strategy.firePushService, times(0)).fireOnWatcher(any(), any()); - - when(strategy.configProvideDataWatcher.get(anyString())) - .thenReturn(new ProvideData(null, "dataId", 100L)); - strategy.afterWatcherRegister(w); - verify(strategy.firePushService, times(1)).fireOnWatcher(any(), any()); - } - - @Test - public void testFilter() { - Assert.assertNull(strategy.filter()); - Watcher w = TestUtils.newWatcher(dataId); - when(strategy.sessionWatchers.getDataList()).thenReturn(Collections.singletonList(w)); - Tuple, List> t = strategy.filter(); - Assert.assertEquals(t.o1, Sets.newHashSet(w.getDataInfoId())); - Assert.assertEquals(t.o2.get(0), w); - sessionServerConfig.setWatchConfigEnable(true); - strategy.watcherScanDog.runUnthrowable(); - - w.setClientVersion(BaseInfo.ClientVersion.MProtocolpackage); - t = strategy.filter(); - Assert.assertEquals(0, t.o1.size()); - Assert.assertEquals(0, t.o2.size()); - - strategy.watcherScanDog.runUnthrowable(); - strategy.afterWatcherRegister(w); - } - - @Test - public void testProcess() { - Watcher w = TestUtils.newWatcher(dataId); - Assert.assertTrue(strategy.processWatchWhenWatchConfigDisable(w)); - verify(strategy.firePushService, times(1)).fireOnWatcher(any(), any()); - w.updatePushedVersion(10); - Assert.assertFalse(strategy.processWatchWhenWatchConfigDisable(w)); - - // reset watcher - w = TestUtils.newWatcher(dataId); - Assert.assertFalse(strategy.processWatchWhenWatchConfigEnable(w)); - ProvideData data = new ProvideData(null, dataId, 10L); - when(strategy.configProvideDataWatcher.get(anyString())).thenReturn(data); - Assert.assertTrue(strategy.processWatchWhenWatchConfigEnable(w)); - verify(strategy.firePushService, times(2)).fireOnWatcher(any(), any()); - w.updatePushedVersion(10); - - Assert.assertFalse(strategy.processWatchWhenWatchConfigEnable(w)); - verify(strategy.firePushService, times(2)).fireOnWatcher(any(), any()); - - data = new ProvideData(null, dataId, 20L); - when(strategy.configProvideDataWatcher.get(anyString())).thenReturn(data); - Assert.assertTrue(strategy.processWatchWhenWatchConfigEnable(w)); - verify(strategy.firePushService, times(3)).fireOnWatcher(any(), any()); - w.updatePushedVersion(20); - Assert.assertFalse(strategy.processWatch(w, false)); - Assert.assertFalse(strategy.processWatch(w, true)); - } -} From b0998c48893407a781a0ec137166c53eb52a5bf3 Mon Sep 17 00:00:00 2001 From: linxin Date: Thu, 9 Mar 2023 15:13:51 +0800 Subject: [PATCH 11/17] remove SyncConfigHandlerStrategy --- .../bootstrap/SessionServerConfiguration.java | 6 ---- .../remoting/handler/SyncConfigHandler.java | 7 ++-- .../strategy/SyncConfigHandlerStrategy.java | 27 -------------- .../DefaultSyncConfigHandlerStrategy.java | 35 ------------------- 4 files changed, 3 insertions(+), 72 deletions(-) delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/SyncConfigHandlerStrategy.java delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSyncConfigHandlerStrategy.java diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java index fa53a9f18..1933c445e 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java @@ -627,12 +627,6 @@ public CacheCountTask cacheCountTask() { @Configuration public static class SessionStrategyConfiguration { - @Bean - @ConditionalOnMissingBean - public SyncConfigHandlerStrategy syncConfigHandlerStrategy() { - return new DefaultSyncConfigHandlerStrategy(); - } - @Bean @ConditionalOnMissingBean public PublisherHandlerStrategy publisherHandlerStrategy() { diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/SyncConfigHandler.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/SyncConfigHandler.java index a5c3feeab..408575d99 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/SyncConfigHandler.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/SyncConfigHandler.java @@ -16,25 +16,24 @@ */ package com.alipay.sofa.registry.server.session.remoting.handler; +import com.alipay.sofa.registry.common.model.constants.ValueConstants; import com.alipay.sofa.registry.core.model.SyncConfigRequest; import com.alipay.sofa.registry.core.model.SyncConfigResponse; import com.alipay.sofa.registry.remoting.Channel; -import com.alipay.sofa.registry.server.session.strategy.SyncConfigHandlerStrategy; +import com.google.common.collect.Lists; import java.util.concurrent.Executor; -import org.springframework.beans.factory.annotation.Autowired; /** * @author zhuoyu.sjw * @version $Id: SyncConfigHandler.java, v 0.1 2018-03-14 23:15 zhuoyu.sjw Exp $$ */ public class SyncConfigHandler extends AbstractClientDataRequestHandler { - @Autowired SyncConfigHandlerStrategy syncConfigHandlerStrategy; @Override public Object doHandle(Channel channel, SyncConfigRequest request) { SyncConfigResponse response = new SyncConfigResponse(); response.setSuccess(true); - syncConfigHandlerStrategy.handleSyncConfigResponse(response); + response.setAvailableSegments(Lists.newArrayList(ValueConstants.DEFAULT_DATA_CENTER)); return response; } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/SyncConfigHandlerStrategy.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/SyncConfigHandlerStrategy.java deleted file mode 100644 index d8862f4e7..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/SyncConfigHandlerStrategy.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.strategy; - -import com.alipay.sofa.registry.core.model.SyncConfigResponse; - -/** - * @author xuanbei - * @since 2019/2/15 - */ -public interface SyncConfigHandlerStrategy { - void handleSyncConfigResponse(SyncConfigResponse syncConfigResponse); -} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSyncConfigHandlerStrategy.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSyncConfigHandlerStrategy.java deleted file mode 100644 index 0503d636b..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSyncConfigHandlerStrategy.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.strategy.impl; - -import com.alipay.sofa.registry.common.model.constants.ValueConstants; -import com.alipay.sofa.registry.core.model.SyncConfigResponse; -import com.alipay.sofa.registry.server.session.strategy.SyncConfigHandlerStrategy; -import com.google.common.collect.Lists; -import java.util.List; - -/** - * @author xuanbei - * @since 2019/2/15 - */ -public class DefaultSyncConfigHandlerStrategy implements SyncConfigHandlerStrategy { - @Override - public void handleSyncConfigResponse(SyncConfigResponse syncConfigResponse) { - List list = Lists.newArrayList(ValueConstants.DEFAULT_DATA_CENTER); - syncConfigResponse.setAvailableSegments(list); - } -} From e69c90c19968c800dd2e05d084c1c041af5d0036 Mon Sep 17 00:00:00 2001 From: linxin Date: Thu, 9 Mar 2023 15:46:48 +0800 Subject: [PATCH 12/17] move Hook to registry package --- .../session/{strategy => registry}/ClientRegistrationHook.java | 2 +- .../impl => registry}/DefaultClientRegistrationHook.java | 3 +-- .../sofa/registry/server/session/registry/SessionRegistry.java | 2 -- .../strategy/impl/DefaultClientRegistrationHookTest.java | 1 + 4 files changed, 3 insertions(+), 5 deletions(-) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/{strategy => registry}/ClientRegistrationHook.java (95%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/{strategy/impl => registry}/DefaultClientRegistrationHook.java (98%) diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/ClientRegistrationHook.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/ClientRegistrationHook.java similarity index 95% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/ClientRegistrationHook.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/ClientRegistrationHook.java index 852a1e214..6c4494736 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/ClientRegistrationHook.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/ClientRegistrationHook.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.strategy; +package com.alipay.sofa.registry.server.session.registry; import com.alipay.sofa.registry.common.model.store.StoreData; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHook.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java similarity index 98% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHook.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java index 11e31073f..ee195b151 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHook.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.strategy.impl; +package com.alipay.sofa.registry.server.session.registry; import com.alipay.sofa.registry.common.model.Tuple; import com.alipay.sofa.registry.common.model.metaserver.ProvideData; @@ -29,7 +29,6 @@ import com.alipay.sofa.registry.server.session.push.FirePushService; import com.alipay.sofa.registry.server.session.push.PushSwitchService; import com.alipay.sofa.registry.server.session.store.Watchers; -import com.alipay.sofa.registry.server.session.strategy.ClientRegistrationHook; import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.LoopRunnable; import com.google.common.collect.Lists; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java index 6d079c5a1..28104109c 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java @@ -43,8 +43,6 @@ import com.alipay.sofa.registry.server.session.store.DataStore; import com.alipay.sofa.registry.server.session.store.Interests; import com.alipay.sofa.registry.server.session.store.Watchers; -import com.alipay.sofa.registry.server.session.strategy.ClientRegistrationHook; -import com.alipay.sofa.registry.server.session.strategy.impl.DefaultClientRegistrationHook; import com.alipay.sofa.registry.server.shared.env.ServerEnv; import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.LoopRunnable; diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java index 1f46e6500..7b91dbabf 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java @@ -33,6 +33,7 @@ import com.alipay.sofa.registry.server.session.providedata.ConfigProvideDataWatcher; import com.alipay.sofa.registry.server.session.push.FirePushService; import com.alipay.sofa.registry.server.session.push.PushSwitchService; +import com.alipay.sofa.registry.server.session.registry.DefaultClientRegistrationHook; import com.alipay.sofa.registry.server.session.store.Watchers; import com.google.common.collect.Sets; import java.util.Collections; From 3dd67f03693b56a4a066755f9e8a812a4afb09af Mon Sep 17 00:00:00 2001 From: linxin Date: Fri, 10 Mar 2023 11:57:32 +0800 Subject: [PATCH 13/17] fix testcase --- .../common/model/dataserver/ClientOffPublisher.java | 2 +- .../sessionserver/handler/BatchPutDataHandlerTest.java | 2 +- .../server/session/connections/ConnectionsService.java | 9 --------- .../registry/DefaultClientRegistrationHook.java | 10 +++++----- .../server/session/resource/ClientManagerResource.java | 4 ++-- .../session/connections/ConnectionsServiceTest.java | 9 --------- .../remoting/handler/SyncConfigHandlerTest.java | 2 -- 7 files changed, 9 insertions(+), 29 deletions(-) diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/ClientOffPublisher.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/ClientOffPublisher.java index bde0da550..012fb08e4 100644 --- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/ClientOffPublisher.java +++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/ClientOffPublisher.java @@ -32,7 +32,7 @@ public final class ClientOffPublisher implements Serializable, DataServerReq { private static final long serialVersionUID = -3547806571058756207L; - private final String dataInfoId; + private final String dataInfoId; // use to cal slot id private final ConnectId connectId; private final Map> publisherMap = Maps.newHashMap(); diff --git a/server/server/data/src/test/java/com/alipay/sofa/registry/server/data/remoting/sessionserver/handler/BatchPutDataHandlerTest.java b/server/server/data/src/test/java/com/alipay/sofa/registry/server/data/remoting/sessionserver/handler/BatchPutDataHandlerTest.java index 354873e6f..3c35f8db9 100644 --- a/server/server/data/src/test/java/com/alipay/sofa/registry/server/data/remoting/sessionserver/handler/BatchPutDataHandlerTest.java +++ b/server/server/data/src/test/java/com/alipay/sofa/registry/server/data/remoting/sessionserver/handler/BatchPutDataHandlerTest.java @@ -127,7 +127,7 @@ private static BatchRequest request(ConnectId connectId, boolean illegalArg) { Publisher pub1 = TestBaseUtils.createTestPublisher("testDataId"); Publisher pub2 = TestBaseUtils.createTestPublisher("testDataId"); - ClientOffPublisher off = new ClientOffPublisher(connectId); + ClientOffPublisher off = new ClientOffPublisher(pub2.getDataInfoId(), connectId); off.addPublisher(pub2); Assert.assertFalse(off.isEmpty()); Assert.assertEquals(off.getConnectId(), connectId); diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/connections/ConnectionsService.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/connections/ConnectionsService.java index d0cf32372..1fb6f211a 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/connections/ConnectionsService.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/connections/ConnectionsService.java @@ -25,9 +25,6 @@ import com.alipay.sofa.registry.remoting.exchange.Exchange; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; import com.alipay.sofa.registry.server.session.mapper.ConnectionMapper; -import com.alipay.sofa.registry.server.session.store.DataStore; -import com.alipay.sofa.registry.server.session.store.Interests; -import com.alipay.sofa.registry.server.session.store.Watchers; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import java.util.*; @@ -40,12 +37,6 @@ public class ConnectionsService { @Autowired Exchange boltExchange; - @Autowired DataStore sessionDataStore; - - @Autowired Interests sessionInterests; - - @Autowired Watchers sessionWatchers; - @Autowired SessionServerConfig sessionServerConfig; @Autowired ConnectionMapper connectionMapper; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java index ee195b151..a2c3a5a57 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java @@ -142,7 +142,7 @@ private boolean checkWatcherVersion(Watcher watcher) { return watcher.getClientVersion() == BaseInfo.ClientVersion.StoreData; } - boolean processWatchWhenWatchConfigDisable(Watcher w) { + public boolean processWatchWhenWatchConfigDisable(Watcher w) { if (w.hasPushed()) { return false; } @@ -152,7 +152,7 @@ boolean processWatchWhenWatchConfigDisable(Watcher w) { return true; } - boolean processWatchWhenWatchConfigEnable(Watcher w) { + public boolean processWatchWhenWatchConfigEnable(Watcher w) { final String dataInfoId = w.getDataInfoId(); final ProvideData provideData = configProvideDataWatcher.get(dataInfoId); if (provideData == null) { @@ -176,13 +176,13 @@ boolean processWatchWhenWatchConfigEnable(Watcher w) { return false; } - boolean processWatch(Watcher w, boolean watchEnable) { + public boolean processWatch(Watcher w, boolean watchEnable) { return watchEnable ? processWatchWhenWatchConfigEnable(w) : processWatchWhenWatchConfigDisable(w); } - Tuple, List> filter() { + public Tuple, List> filter() { List watchers = Lists.newLinkedList(sessionWatchers.getDataList()); if (CollectionUtils.isEmpty(watchers)) { return null; @@ -200,7 +200,7 @@ Tuple, List> filter() { return Tuple.of(dataInfoIds, watchers); } - void processWatch() { + public void processWatch() { Tuple, List> filtered = filter(); if (filtered == null) { return; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/resource/ClientManagerResource.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/resource/ClientManagerResource.java index 065112f94..1067575ee 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/resource/ClientManagerResource.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/resource/ClientManagerResource.java @@ -34,7 +34,7 @@ import com.alipay.sofa.registry.server.session.connections.ConnectionsService; import com.alipay.sofa.registry.server.session.mapper.ConnectionMapper; import com.alipay.sofa.registry.server.session.providedata.FetchClientOffAddressService; -import com.alipay.sofa.registry.server.session.registry.SessionRegistry; +import com.alipay.sofa.registry.server.session.registry.Registry; import com.alipay.sofa.registry.server.shared.env.ServerEnv; import com.alipay.sofa.registry.server.shared.meta.MetaServerService; import com.google.common.collect.Maps; @@ -64,7 +64,7 @@ public class ClientManagerResource { private static final Logger LOGGER = LoggerFactory.getLogger(ClientManagerResource.class); - @Autowired private SessionRegistry sessionRegistry; + @Autowired private Registry sessionRegistry; @Autowired private SessionServerConfig sessionServerConfig; @Autowired private MetaServerService metaServerService; diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/connections/ConnectionsServiceTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/connections/ConnectionsServiceTest.java index e36415bd9..e9124e98a 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/connections/ConnectionsServiceTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/connections/ConnectionsServiceTest.java @@ -22,9 +22,6 @@ import com.alipay.sofa.registry.server.session.TestUtils; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfigBean; import com.alipay.sofa.registry.server.session.mapper.ConnectionMapper; -import com.alipay.sofa.registry.server.session.store.DataStore; -import com.alipay.sofa.registry.server.session.store.SessionInterests; -import com.alipay.sofa.registry.server.session.store.SessionWatchers; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import java.util.List; @@ -39,10 +36,6 @@ public void test() { ConnectionsService connectionsService = new ConnectionsService(); connectionsService.sessionServerConfig = configBean; connectionsService.connectionMapper = new ConnectionMapper(); - connectionsService.sessionDataStore = Mockito.mock(DataStore.class); - - connectionsService.sessionInterests = new SessionInterests(); - connectionsService.sessionWatchers = new SessionWatchers(); connectionsService.boltExchange = Mockito.mock(Exchange.class); String remoteIp = "192.168.8.8"; @@ -55,8 +48,6 @@ public void test() { TestUtils.MockBlotChannel channel = TestUtils.newChannel(9600, remoteIp, 1234); Mockito.when(server.getChannels()).thenReturn(Lists.newArrayList(channel)); ConnectId connectId = ConnectId.of(channel.getRemoteAddress(), channel.getLocalAddress()); - Mockito.when(connectionsService.sessionDataStore.getConnectIds()) - .thenReturn(Sets.newHashSet(connectId)); List list = connectionsService.getConnections(); Assert.assertEquals(list, Lists.newArrayList(remoteIp + ":1234")); diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/SyncConfigHandlerTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/SyncConfigHandlerTest.java index b177d0dfc..273eca4be 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/SyncConfigHandlerTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/SyncConfigHandlerTest.java @@ -24,7 +24,6 @@ import com.alipay.sofa.registry.remoting.ChannelHandler; import com.alipay.sofa.registry.server.session.TestUtils; import com.alipay.sofa.registry.server.session.bootstrap.ExecutorManager; -import com.alipay.sofa.registry.server.session.strategy.impl.DefaultSyncConfigHandlerStrategy; import org.junit.Assert; import org.junit.Test; @@ -38,7 +37,6 @@ private SyncConfigHandler newHandler() { Assert.assertEquals(handler.getConnectNodeType(), Node.NodeType.CLIENT); Assert.assertEquals(handler.getType(), ChannelHandler.HandlerType.PROCESSER); Assert.assertEquals(handler.getInvokeType(), ChannelHandler.InvokeType.SYNC); - handler.syncConfigHandlerStrategy = new DefaultSyncConfigHandlerStrategy(); return handler; } From 52f5e238b468066bb2eab2aa1e3c0693dc54486a Mon Sep 17 00:00:00 2001 From: linxin Date: Fri, 10 Mar 2023 13:11:48 +0800 Subject: [PATCH 14/17] fix testcase --- .../server/session/node/service/BufferedDataWritingEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java index 89852a4d6..0fff75d6e 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java @@ -113,7 +113,7 @@ public void submit(DataServerReq dataServerReq) { */ if ((singleWorkerCachedRequest = worker.cachedRequests()) <= avgSingleQueueBufferSize || (totalCachedRequests = totalCachedRequests()) <= halfMaximumBufferSize) { - failed = worker.offer(new Req(slotId, dataServerReq)); + failed = !worker.offer(new Req(slotId, dataServerReq)); } if (failed) { throw new FastRejectedExecutionException( From 6528963df94a0d41f328875271f2a326bcdb5325 Mon Sep 17 00:00:00 2001 From: linxin Date: Wed, 15 Mar 2023 20:42:17 +0800 Subject: [PATCH 15/17] refactor session store module --- .../common/model/ClientOffPublishers.java | 3 +- .../common/model/store/StoreData.java | 11 + .../common/model/store/Subscriber.java | 25 +- .../registry/common/model/store/Watcher.java | 24 +- .../acceptor/ClientOffWriteDataRequest.java | 4 +- .../bootstrap/SessionServerConfiguration.java | 18 +- .../service/BufferedDataWritingEngine.java | 10 +- .../server/session/push/FirePushService.java | 9 +- .../DefaultClientRegistrationHook.java | 17 +- .../session/registry/SessionRegistry.java | 92 +++--- .../handler/FilterSubscriberIPsHandler.java | 27 +- .../QuerySubscriberRequestHandler.java | 6 +- .../handler/DataChangeRequestHandler.java | 10 +- .../DataSlotDiffDigestRequestHandler.java | 21 +- .../DataSlotDiffPublisherRequestHandler.java | 20 +- .../resource/SessionDigestResource.java | 50 ++-- .../scheduler/timertask/CacheCountTask.java | 22 +- .../timertask/SessionCacheDigestTask.java | 16 +- .../timertask/SyncClientsHeartbeatTask.java | 43 ++- .../session/store/AbstractClientStore.java | 121 ++++++++ .../session/store/AbstractDataManager.java | 256 ----------------- .../server/session/store/ClientStore.java | 104 +++++++ .../server/session/store/ClientsGroup.java | 102 +++++++ .../server/session/store/DataManager.java | 101 ------- .../store/FetchPubSubDataInfoIdService.java | 31 ++- .../{DataStore.java => PublisherStore.java} | 18 +- ...nWatchers.java => PublisherStoreImpl.java} | 35 +-- .../session/store/SessionDataStore.java | 74 ----- .../session/store/SessionInterests.java | 141 ---------- .../server/session/store/SimpleStore.java | 89 ------ .../server/session/store/SlotStore.java | 99 ------- .../{Interests.java => SubscriberStore.java} | 39 +-- .../session/store/SubscriberStoreImpl.java | 102 +++++++ .../{Watchers.java => WatcherStore.java} | 7 +- .../{Store.java => WatcherStoreImpl.java} | 22 +- .../store/engine/SimpleMemoryStoreEngine.java | 142 ++++++++++ .../store/engine/SlotMemoryStoreEngine.java | 133 +++++++++ .../session/store/engine/SlotStoreEngine.java | 32 +++ .../session/store/engine/StoreEngine.java | 127 +++++++++ .../OrderedInterceptorManagerTest.java | 22 ++ .../session/push/FirePushServiceTest.java | 10 +- .../FilterSubscriberIPsHandlerTest.java | 4 +- .../QuerySubscriberRequestHandlerTest.java | 4 +- .../handler/DataChangeRequestHandlerTest.java | 12 +- .../DataSlotDiffDigestRequestHandlerTest.java | 7 +- ...taSlotDiffPublisherRequestHandlerTest.java | 7 +- .../scheduler/timertask/CacheTaskTest.java | 70 ++--- .../server/session/store/DataCacheTest.java | 215 +++++---------- .../session/store/PublisherStoreTest.java | 68 +++++ .../session/store/SessionDataStoreTest.java | 261 ------------------ .../session/store/SessionInterestsTest.java | 117 -------- .../session/store/StorePerformanceTest.java | 235 ---------------- .../session/store/SubscriberStoreTest.java | 160 +++++++++++ .../session/store/WatcherStoreTest.java | 99 +++++++ .../engine/SimpleMemoryStoreEngineTest.java | 97 +++++++ .../engine/SlotMemoryStoreEngineTest.java | 102 +++++++ .../DefaultClientRegistrationHookTest.java | 29 +- .../registry/test/BaseIntegrationTest.java | 12 +- .../test/client/ClientManagerTest.java | 27 +- .../SessionPersistenceClientManagerTest.java | 27 +- .../ClientsManagerOpenResourceTest.java | 15 +- 61 files changed, 1886 insertions(+), 1917 deletions(-) create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/AbstractClientStore.java delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/AbstractDataManager.java create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/ClientStore.java create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/ClientsGroup.java delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/DataManager.java rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/{DataStore.java => PublisherStore.java} (74%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/{SessionWatchers.java => PublisherStoreImpl.java} (51%) delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionDataStore.java delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionInterests.java delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SimpleStore.java delete mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SlotStore.java rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/{Interests.java => SubscriberStore.java} (66%) create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SubscriberStoreImpl.java rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/{Watchers.java => WatcherStore.java} (83%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/{Store.java => WatcherStoreImpl.java} (66%) create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngine.java create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SlotMemoryStoreEngine.java create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SlotStoreEngine.java create mode 100644 server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/StoreEngine.java create mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/PublisherStoreTest.java delete mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SessionDataStoreTest.java delete mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SessionInterestsTest.java delete mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/StorePerformanceTest.java create mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SubscriberStoreTest.java create mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/WatcherStoreTest.java create mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngineTest.java create mode 100644 server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/engine/SlotMemoryStoreEngineTest.java diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/ClientOffPublishers.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/ClientOffPublishers.java index 104409471..505b81ffa 100644 --- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/ClientOffPublishers.java +++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/ClientOffPublishers.java @@ -18,6 +18,7 @@ import com.alipay.sofa.registry.common.model.store.Publisher; import com.google.common.collect.Lists; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -25,7 +26,7 @@ public class ClientOffPublishers { private final ConnectId connectId; private final List publishers; - public ClientOffPublishers(ConnectId connectId, List publishers) { + public ClientOffPublishers(ConnectId connectId, Collection publishers) { this.connectId = connectId; this.publishers = Collections.unmodifiableList(Lists.newArrayList(publishers)); } diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/StoreData.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/StoreData.java index 7884b89e0..5aad20035 100644 --- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/StoreData.java +++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/StoreData.java @@ -16,6 +16,9 @@ */ package com.alipay.sofa.registry.common.model.store; +import com.alipay.sofa.registry.common.model.ConnectId; +import com.alipay.sofa.registry.common.model.RegisterVersion; + /** * @author shangyu.wh * @version $Id: StoreData.java, v 0.1 2017-11-30 19:48 shangyu.wh Exp $ @@ -43,4 +46,12 @@ enum DataType { * @return */ ID getId(); + + String getDataInfoId(); + + RegisterVersion registerVersion(); + + long getRegisterTimestamp(); + + ConnectId connectId(); } diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Subscriber.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Subscriber.java index cefa75522..6a113bce9 100644 --- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Subscriber.java +++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Subscriber.java @@ -69,7 +69,7 @@ public ElementType getElementType() { } private PushContext getPushContext(String dataCenter) { - PushContext ctx = null; + PushContext ctx; if (lastPushContexts == null) { ctx = new PushContext(); this.lastPushContexts = Collections.singletonMap(dataCenter, ctx); @@ -223,7 +223,6 @@ public synchronized long markPushEmpty(String dataCenter, long emptyVersion) { return emptyVersion; } - /** @return */ public synchronized CircuitBreakerStatistic getStatistic(String dataCenter) { final PushContext ctx = getPushContext(dataCenter); return new CircuitBreakerStatistic( @@ -234,28 +233,6 @@ public synchronized CircuitBreakerStatistic getStatistic(String dataCenter) { ctx.lastPushedFailTimeStamp); } - /** - * change subscriber word cache - * - * @param subscriber - * @return - */ - public static Subscriber internSubscriber(Subscriber subscriber) { - subscriber.setDataInfoId(subscriber.getDataInfoId()); - subscriber.setInstanceId(subscriber.getInstanceId()); - subscriber.setGroup(subscriber.getGroup()); - subscriber.setDataId(subscriber.getDataId()); - subscriber.setCell(subscriber.getCell()); - subscriber.setProcessId(subscriber.getProcessId()); - subscriber.setAppName(subscriber.getAppName()); - - subscriber.setSourceAddress(URL.internURL(subscriber.getSourceAddress())); - subscriber.setTargetAddress(URL.internURL(subscriber.getTargetAddress())); - subscriber.setAttributes(subscriber.getAttributes()); - - return subscriber; - } - protected Map internAttributes(Map attributes) { Map intern = super.internAttributes(attributes); return com.alipay.sofa.registry.collections.Maps.trimMap(intern); diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Watcher.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Watcher.java index d12862199..9c75d9dcd 100644 --- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Watcher.java +++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Watcher.java @@ -22,6 +22,7 @@ */ public class Watcher extends BaseInfo { + private static final long serialVersionUID = -2122505760402915804L; private volatile long pushedVersion; @Override @@ -53,27 +54,4 @@ public String shortDesc() { sb.append("sourceAddress=").append(getSourceAddress().buildAddressString()); return sb.toString(); } - - /** - * change watcher word cache - * - * @param watcher - * @return - */ - public static Watcher internWatcher(Watcher watcher) { - watcher.setRegisterId(watcher.getRegisterId()); - watcher.setDataInfoId(watcher.getDataInfoId()); - watcher.setInstanceId(watcher.getInstanceId()); - watcher.setGroup(watcher.getGroup()); - watcher.setDataId(watcher.getDataId()); - watcher.setClientId(watcher.getClientId()); - watcher.setCell(watcher.getCell()); - watcher.setProcessId(watcher.getProcessId()); - watcher.setAppName(watcher.getAppName()); - watcher.setSourceAddress(URL.internURL(watcher.getSourceAddress())); - watcher.setTargetAddress(URL.internURL(watcher.getTargetAddress())); - watcher.setAttributes(watcher.getAttributes()); - - return watcher; - } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/ClientOffWriteDataRequest.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/ClientOffWriteDataRequest.java index 686737898..65b325423 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/ClientOffWriteDataRequest.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/acceptor/ClientOffWriteDataRequest.java @@ -19,7 +19,7 @@ import com.alipay.sofa.registry.common.model.ClientOffPublishers; import com.alipay.sofa.registry.common.model.ConnectId; import com.alipay.sofa.registry.common.model.store.Publisher; -import java.util.List; +import java.util.Collection; /** * @author yuzhi.lyz @@ -30,7 +30,7 @@ public final class ClientOffWriteDataRequest implements WriteDataRequest publishers) { + public ClientOffWriteDataRequest(ConnectId connectId, Collection publishers) { this.connectId = connectId; this.requestBody = new ClientOffPublishers(connectId, publishers); } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java index 1933c445e..fd17a113d 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java @@ -59,6 +59,12 @@ import com.alipay.sofa.registry.server.session.slot.SlotTableCache; import com.alipay.sofa.registry.server.session.slot.SlotTableCacheImpl; import com.alipay.sofa.registry.server.session.store.*; +import com.alipay.sofa.registry.server.session.store.PublisherStore; +import com.alipay.sofa.registry.server.session.store.PublisherStoreImpl; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; +import com.alipay.sofa.registry.server.session.store.SubscriberStoreImpl; +import com.alipay.sofa.registry.server.session.store.WatcherStore; +import com.alipay.sofa.registry.server.session.store.WatcherStoreImpl; import com.alipay.sofa.registry.server.session.strategy.*; import com.alipay.sofa.registry.server.session.strategy.impl.*; import com.alipay.sofa.registry.server.shared.client.manager.BaseClientManagerService; @@ -475,20 +481,20 @@ public Registry sessionRegistry() { @Bean @ConditionalOnMissingBean - public Interests sessionInterests() { - return new SessionInterests(); + public PublisherStore publisherStore(SlotTableCache slotTableCache) { + return new PublisherStoreImpl(slotTableCache); } @Bean @ConditionalOnMissingBean - public Watchers sessionWatchers() { - return new SessionWatchers(); + public SubscriberStore subscriberStore(SessionServerConfig sessionServerConfig) { + return new SubscriberStoreImpl(sessionServerConfig); } @Bean @ConditionalOnMissingBean - public DataStore sessionDataStore() { - return new SessionDataStore(); + public WatcherStore watcherStore() { + return new WatcherStoreImpl(); } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java index 89852a4d6..1cc014a61 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/node/service/BufferedDataWritingEngine.java @@ -113,13 +113,17 @@ public void submit(DataServerReq dataServerReq) { */ if ((singleWorkerCachedRequest = worker.cachedRequests()) <= avgSingleQueueBufferSize || (totalCachedRequests = totalCachedRequests()) <= halfMaximumBufferSize) { - failed = worker.offer(new Req(slotId, dataServerReq)); + failed = !worker.offer(new Req(slotId, dataServerReq)); } if (failed) { throw new FastRejectedExecutionException( String.format( - "BlockingQueues.put overflow, idx=%d, totalSize=%d, queueSize=%d", - idx, totalCachedRequests, singleWorkerCachedRequest)); + "BlockingQueues.put overflow, idx=%d, totalCachedRequests=%d, singleWorkerCachedRequests=%d, halfMaximumBufferSize=%d, avgSingleQueueBufferSize=%d", + idx, + totalCachedRequests, + singleWorkerCachedRequest, + halfMaximumBufferSize, + avgSingleQueueBufferSize)); } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/push/FirePushService.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/push/FirePushService.java index 48cc563a6..40d871748 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/push/FirePushService.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/push/FirePushService.java @@ -31,7 +31,7 @@ import com.alipay.sofa.registry.server.session.cache.Key; import com.alipay.sofa.registry.server.session.cache.Value; import com.alipay.sofa.registry.server.session.circuit.breaker.CircuitBreakerService; -import com.alipay.sofa.registry.server.session.store.Interests; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; import com.alipay.sofa.registry.server.shared.util.DatumUtils; import com.alipay.sofa.registry.task.FastRejectedExecutionException; import com.alipay.sofa.registry.task.KeyedThreadPoolExecutor; @@ -54,7 +54,7 @@ public class FirePushService { @Autowired CacheService sessionCacheService; - @Autowired Interests sessionInterests; + @Autowired SubscriberStore subscriberStore; @Autowired CircuitBreakerService circuitBreakerService; @@ -151,7 +151,8 @@ static void handleFireOnWatchException(Watcher watcher, Throwable e) { public boolean fireOnDatum(SubDatum datum, String dataNode) { try { DataInfo dataInfo = DataInfo.valueOf(datum.getDataInfoId()); - Collection subscribers = sessionInterests.getInterests(dataInfo.getDataInfoId()); + Collection subscribers = + subscriberStore.getByDataInfoId(dataInfo.getDataInfoId()); final long now = System.currentTimeMillis(); TriggerPushContext pushCtx = new TriggerPushContext(datum.getDataCenter(), datum.getVersion(), dataNode, now); @@ -189,7 +190,7 @@ boolean doExecuteOnChange(String changeDataInfoId, TriggerPushContext changeCtx) private void onDatumChange(TriggerPushContext changeCtx, SubDatum datum) { Map> scopes = - SubscriberUtils.groupByScope(sessionInterests.getDatas(datum.getDataInfoId())); + SubscriberUtils.groupByScope(subscriberStore.getByDataInfoId(datum.getDataInfoId())); final long datumTimestamp = PushTrace.getTriggerPushTimestamp(datum); final PushCause cause = new PushCause(changeCtx, PushType.Sub, datumTimestamp); for (Map.Entry> scope : scopes.entrySet()) { diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java index a2c3a5a57..508909583 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java @@ -28,12 +28,11 @@ import com.alipay.sofa.registry.server.session.providedata.ConfigProvideDataWatcher; import com.alipay.sofa.registry.server.session.push.FirePushService; import com.alipay.sofa.registry.server.session.push.PushSwitchService; -import com.alipay.sofa.registry.server.session.store.Watchers; +import com.alipay.sofa.registry.server.session.store.WatcherStore; import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.LoopRunnable; -import com.google.common.collect.Lists; +import java.util.Collection; import java.util.Iterator; -import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import org.apache.commons.collections.CollectionUtils; @@ -50,19 +49,19 @@ public class DefaultClientRegistrationHook implements ClientRegistrationHook { private final FirePushService firePushService; private final PushSwitchService pushSwitchService; private final ConfigProvideDataWatcher configProvideDataWatcher; - private final Watchers sessionWatchers; + private final WatcherStore watcherStore; public DefaultClientRegistrationHook( SessionServerConfig sessionServerConfig, FirePushService firePushService, PushSwitchService pushSwitchService, ConfigProvideDataWatcher configProvideDataWatcher, - Watchers sessionWatchers) { + WatcherStore watcherStore) { this.sessionServerConfig = sessionServerConfig; this.firePushService = firePushService; this.pushSwitchService = pushSwitchService; this.configProvideDataWatcher = configProvideDataWatcher; - this.sessionWatchers = sessionWatchers; + this.watcherStore = watcherStore; ConcurrentUtils.createDaemonThread( "watcher-scan-dog", new LoopRunnable() { @@ -182,8 +181,8 @@ public boolean processWatch(Watcher w, boolean watchEnable) { : processWatchWhenWatchConfigDisable(w); } - public Tuple, List> filter() { - List watchers = Lists.newLinkedList(sessionWatchers.getDataList()); + public Tuple, Collection> filter() { + Collection watchers = watcherStore.getAll(); if (CollectionUtils.isEmpty(watchers)) { return null; } @@ -201,7 +200,7 @@ public Tuple, List> filter() { } public void processWatch() { - Tuple, List> filtered = filter(); + Tuple, Collection> filtered = filter(); if (filtered == null) { return; } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java index 28104109c..dd12e464b 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java @@ -40,15 +40,14 @@ import com.alipay.sofa.registry.server.session.push.PushSwitchService; import com.alipay.sofa.registry.server.session.push.TriggerPushContext; import com.alipay.sofa.registry.server.session.slot.SlotTableCache; -import com.alipay.sofa.registry.server.session.store.DataStore; -import com.alipay.sofa.registry.server.session.store.Interests; -import com.alipay.sofa.registry.server.session.store.Watchers; +import com.alipay.sofa.registry.server.session.store.PublisherStore; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; +import com.alipay.sofa.registry.server.session.store.WatcherStore; import com.alipay.sofa.registry.server.shared.env.ServerEnv; import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.LoopRunnable; import com.alipay.sofa.registry.util.StringFormatter; import com.alipay.sofa.registry.util.WakeUpLoopRunnable; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import java.util.*; @@ -69,14 +68,9 @@ public class SessionRegistry implements Registry { protected static final Logger SCAN_VER_LOGGER = LoggerFactory.getLogger("SCAN-VER"); - /** store subscribers */ - @Autowired protected Interests sessionInterests; - - /** store watchers */ - @Autowired protected Watchers sessionWatchers; - - /** store publishers */ - @Autowired protected DataStore sessionDataStore; + @Autowired protected PublisherStore publisherStore; + @Autowired protected SubscriberStore subscriberStore; + @Autowired protected WatcherStore watcherStore; /** transfer data to DataNode */ @Autowired protected DataNodeService dataNodeService; @@ -108,7 +102,7 @@ public void init() { firePushService, pushSwitchService, configProvideDataWatcher, - sessionWatchers); + watcherStore); ConcurrentUtils.createDaemonThread("SessionVerWatchDog", versionWatchDog).start(); ConcurrentUtils.createDaemonThread("SessionClientWatchDog", new ClientWatchDog()).start(); @@ -135,7 +129,7 @@ public void register(StoreData storeData, Channel channel) { case PUBLISHER: Publisher publisher = (Publisher) storeData; publisher.setSessionProcessId(ServerEnv.PROCESS_ID); - if (!sessionDataStore.add(publisher)) { + if (!publisherStore.add(publisher)) { break; } // All write operations to DataServer (pub/unPub/clientoff/renew/snapshot) @@ -145,14 +139,14 @@ public void register(StoreData storeData, Channel channel) { break; case SUBSCRIBER: Subscriber subscriber = (Subscriber) storeData; - if (!sessionInterests.add(subscriber)) { + if (!subscriberStore.add(subscriber)) { break; } clientRegistrationHook.afterClientRegister(storeData); break; case WATCHER: Watcher watcher = (Watcher) storeData; - if (!sessionWatchers.add(watcher)) { + if (!watcherStore.add(watcher)) { break; } clientRegistrationHook.afterClientRegister(storeData); @@ -174,7 +168,7 @@ public void unRegister(StoreData storeData) { Publisher publisher = (Publisher) storeData; publisher.setSessionProcessId(ServerEnv.PROCESS_ID); // no need to check whether the pub exist, make sure the unpub send to data - sessionDataStore.deleteById(storeData.getId(), publisher.getDataInfoId()); + publisherStore.delete(publisher.getDataInfoId(), storeData.getId()); // All write operations to DataServer (pub/unPub/clientoff) // are handed over to WriteDataAcceptor writeDataAcceptor.accept(new PublisherUnregisterWriteDataRequest(publisher)); @@ -183,14 +177,14 @@ public void unRegister(StoreData storeData) { break; case SUBSCRIBER: Subscriber subscriber = (Subscriber) storeData; - if (sessionInterests.deleteById(storeData.getId(), subscriber.getDataInfoId()) == null) { + if (subscriberStore.delete(subscriber.getDataInfoId(), storeData.getId()) == null) { break; } clientRegistrationHook.afterClientUnregister(storeData); break; case WATCHER: Watcher watcher = (Watcher) storeData; - if (sessionWatchers.deleteById(watcher.getId(), watcher.getDataInfoId()) == null) { + if (watcherStore.delete(watcher.getDataInfoId(), watcher.getId()) == null) { break; } clientRegistrationHook.afterClientUnregister(storeData); @@ -240,19 +234,22 @@ private void disableConnect( final String dataCenter = getDataCenterWhenPushEmpty(); if (checkSub) { - Map> subMap = - sessionInterests.queryByConnectIds(connectIdSet); - for (Entry> subEntry : subMap.entrySet()) { + for (ConnectId connectId : connectIdSet) { + Collection subscribers = subscriberStore.getByConnectId(connectId); + if (subscribers == null || subscribers.size() <= 0) { + continue; + } + int subEmptyCount = 0; - for (Subscriber sub : subEntry.getValue().values()) { + for (Subscriber sub : subscribers) { if (isPushEmpty(sub)) { - Long clientOffVersion = connectIdVersions.get(subEntry.getKey()); + Long clientOffVersion = connectIdVersions.get(connectId); if (clientOffVersion != null && clientOffVersion < sub.getRegisterTimestamp()) { Loggers.CLIENT_DISABLE_LOG.error( "[ClientOffVersionError]subEmpty,{},{},{}, clientOffVersion={} is smaller than subRegisterTimestamp={}", sub.getDataInfoId(), dataCenter, - subEntry.getKey(), + connectId, clientOffVersion, sub.getRegisterTimestamp()); continue; @@ -261,16 +258,15 @@ private void disableConnect( subEmptyCount++; firePushService.fireOnPushEmpty(sub, dataCenter); Loggers.CLIENT_DISABLE_LOG.info( - "subEmpty,{},{},{}", sub.getDataInfoId(), dataCenter, subEntry.getKey()); + "subEmpty,{},{},{}", sub.getDataInfoId(), dataCenter, connectId); } } - Loggers.CLIENT_DISABLE_LOG.info( - "connectId={}, subEmpty={}", subEntry.getKey(), subEmptyCount); + Loggers.CLIENT_DISABLE_LOG.info("connectId={}, subEmpty={}", connectId, subEmptyCount); } } - Map> pubMap = removeFromSession(connectIdSet, removeSubAndWat); - for (Entry> pubEntry : pubMap.entrySet()) { + Map> pubMap = removeFromSession(connectIdSet, removeSubAndWat); + for (Entry> pubEntry : pubMap.entrySet()) { clientOffToDataNode(pubEntry.getKey(), pubEntry.getValue()); Loggers.CLIENT_DISABLE_LOG.info( "connectId={}, pubRemove={}", pubEntry.getKey(), pubEntry.getValue().size()); @@ -282,24 +278,26 @@ public boolean isPushEmpty(Subscriber subscriber) { return false; } - private Map> removeFromSession( + private Map> removeFromSession( Set connectIds, boolean removeSubAndWat) { - Map> publisherMap = - sessionDataStore.deleteByConnectIds(connectIds); + Map> ret = Maps.newHashMap(); - if (removeSubAndWat) { - sessionInterests.deleteByConnectIds(connectIds); - sessionWatchers.deleteByConnectIds(connectIds); - } - - Map> ret = Maps.newHashMap(); - for (Entry> entry : publisherMap.entrySet()) { - ret.put(entry.getKey(), Lists.newArrayList(entry.getValue().values())); + if (connectIds != null && connectIds.size() > 0) { + for (ConnectId connectId : connectIds) { + Collection publishers = publisherStore.delete(connectId); + if (publishers != null && publishers.size() > 0) { + ret.put(connectId, publishers); + } + if (removeSubAndWat) { + subscriberStore.delete(connectId); + watcherStore.delete(connectId); + } + } } return ret; } - private void clientOffToDataNode(ConnectId connectId, List clientOffPublishers) { + private void clientOffToDataNode(ConnectId connectId, Collection clientOffPublishers) { if (CollectionUtils.isEmpty(clientOffPublishers)) { return; } @@ -364,7 +362,7 @@ private Tuple, List> selectSubscribers( long round, String dataCenter) { final long start = System.currentTimeMillis(); Tuple, List> tuple = - sessionInterests.selectSubscribers(dataCenter); + subscriberStore.selectSubscribers(dataCenter); SCAN_VER_LOGGER.info( "[select]round={}, interestSize={}, pushEmptySize={}, span={}", round, @@ -458,7 +456,7 @@ int handleFetchResult(long round, String dataCenter, Map version : result.callback.versions.entrySet()) { final String dataInfoId = version.getKey(); final long verVal = version.getValue().getValue(); - if (sessionInterests.checkInterestVersion(dataCenter, dataInfoId, verVal).interested) { + if (subscriberStore.checkInterestVersion(dataCenter, dataInfoId, verVal).interested) { TriggerPushContext ctx = new TriggerPushContext(dataCenter, verVal, result.leader, now); firePushService.fireOnChange(dataInfoId, ctx); SCAN_VER_LOGGER.info( @@ -597,9 +595,9 @@ public void cleanClientConnect() { } Set connectIndexes = Sets.newHashSetWithExpectedSize(1024 * 8); - connectIndexes.addAll(sessionDataStore.getConnectIds()); - connectIndexes.addAll(sessionInterests.getConnectIds()); - connectIndexes.addAll(sessionWatchers.getConnectIds()); + connectIndexes.addAll(publisherStore.getAllConnectId()); + connectIndexes.addAll(subscriberStore.getAllConnectId()); + connectIndexes.addAll(watcherStore.getAllConnectId()); List connectIds = new ArrayList<>(64); for (ConnectId connectId : connectIndexes) { diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/console/handler/FilterSubscriberIPsHandler.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/console/handler/FilterSubscriberIPsHandler.java index 5fb699827..75e505eab 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/console/handler/FilterSubscriberIPsHandler.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/console/handler/FilterSubscriberIPsHandler.java @@ -18,12 +18,19 @@ import com.alipay.sofa.registry.common.model.GenericResponse; import com.alipay.sofa.registry.common.model.sessionserver.FilterSubscriberIPsRequest; +import com.alipay.sofa.registry.common.model.store.Subscriber; import com.alipay.sofa.registry.remoting.Channel; -import com.alipay.sofa.registry.server.session.store.Interests; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; +import com.google.common.collect.Maps; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; public class FilterSubscriberIPsHandler extends AbstractConsoleHandler { - @Autowired protected Interests sessionInterests; + @Autowired protected SubscriberStore subscriberStore; @Override public Class interest() { @@ -32,7 +39,19 @@ public Class interest() { @Override public Object doHandle(Channel channel, FilterSubscriberIPsRequest request) { - return new GenericResponse() - .fillSucceed(sessionInterests.filterIPs(request.getGroup(), request.getIpLimit())); + Map> subscribers = + subscriberStore.query(request.getGroup(), request.getIpLimit()); + if (subscribers == null || subscribers.size() == 0) { + return new GenericResponse().fillSucceed(Collections.emptyMap()); + } + Map> ret = Maps.newHashMapWithExpectedSize(subscribers.size()); + for (Map.Entry> entry : subscribers.entrySet()) { + ret.put( + entry.getKey(), + entry.getValue().stream() + .map(subscriber -> subscriber.getSourceAddress().getIpAddress()) + .collect(Collectors.toList())); + } + return new GenericResponse().fillSucceed(ret); } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/console/handler/QuerySubscriberRequestHandler.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/console/handler/QuerySubscriberRequestHandler.java index 69dc507ce..33cef17e7 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/console/handler/QuerySubscriberRequestHandler.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/console/handler/QuerySubscriberRequestHandler.java @@ -21,16 +21,16 @@ import com.alipay.sofa.registry.common.model.sessionserver.QuerySubscriberRequest; import com.alipay.sofa.registry.common.model.store.Subscriber; import com.alipay.sofa.registry.remoting.Channel; -import com.alipay.sofa.registry.server.session.store.Interests; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; import java.util.Collection; import org.springframework.beans.factory.annotation.Autowired; public class QuerySubscriberRequestHandler extends AbstractConsoleHandler { - @Autowired protected Interests sessionInterests; + @Autowired protected SubscriberStore subscriberStore; @Override public Object doHandle(Channel channel, QuerySubscriberRequest request) { - Collection subscribers = sessionInterests.getInterests(request.getDataInfoId()); + Collection subscribers = subscriberStore.getByDataInfoId(request.getDataInfoId()); return new GenericResponse().fillSucceed(SubscriberUtils.convert(subscribers)); } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataChangeRequestHandler.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataChangeRequestHandler.java index f20f408fd..b943e7b6e 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataChangeRequestHandler.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataChangeRequestHandler.java @@ -28,7 +28,7 @@ import com.alipay.sofa.registry.server.session.push.FirePushService; import com.alipay.sofa.registry.server.session.push.PushSwitchService; import com.alipay.sofa.registry.server.session.push.TriggerPushContext; -import com.alipay.sofa.registry.server.session.store.Interests; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; import com.alipay.sofa.registry.server.shared.remoting.AbstractClientHandler; import com.alipay.sofa.registry.server.shared.remoting.RemotingHelper; import com.alipay.sofa.registry.util.ParaCheckUtil; @@ -45,7 +45,7 @@ public class DataChangeRequestHandler extends AbstractClientHandler e : dataChangeRequest.getDataInfoIds().entrySet()) { final String dataInfoId = e.getKey(); final DatumVersion version = e.getValue(); - Interests.InterestVersionCheck check = - sessionInterests.checkInterestVersion(dataCenter, dataInfoId, version.getValue()); + SubscriberStore.InterestVersionCheck check = + subscriberStore.checkInterestVersion(dataCenter, dataInfoId, version.getValue()); if (!check.interested) { - if (check != Interests.InterestVersionCheck.NoSub) { + if (check != SubscriberStore.InterestVersionCheck.NoSub) { // log exclude NoSub LOGGER.info("[SkipChange]{},{}, ver={}, {}", dataInfoId, dataCenter, version, check); } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffDigestRequestHandler.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffDigestRequestHandler.java index 04116b73a..7ebbd2f4e 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffDigestRequestHandler.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffDigestRequestHandler.java @@ -28,11 +28,13 @@ import com.alipay.sofa.registry.remoting.Channel; import com.alipay.sofa.registry.server.session.bootstrap.ExecutorManager; import com.alipay.sofa.registry.server.session.slot.SlotTableCache; -import com.alipay.sofa.registry.server.session.store.DataStore; +import com.alipay.sofa.registry.server.session.store.PublisherStore; import com.alipay.sofa.registry.server.shared.env.ServerEnv; import com.alipay.sofa.registry.server.shared.remoting.AbstractServerHandler; import com.alipay.sofa.registry.util.ParaCheckUtil; import com.alipay.sofa.registry.util.StringFormatter; +import java.util.Collection; +import java.util.HashMap; import java.util.Map; import java.util.concurrent.Executor; import org.springframework.beans.factory.annotation.Autowired; @@ -48,7 +50,7 @@ public class DataSlotDiffDigestRequestHandler @Autowired ExecutorManager executorManager; - @Autowired DataStore sessionDataStore; + @Autowired PublisherStore publisherStore; @Autowired SlotTableCache slotTableCache; @@ -61,11 +63,18 @@ public void checkParam(DataSlotDiffDigestRequest request) { @Override public Object doHandle(Channel channel, DataSlotDiffDigestRequest request) { try { + Map> existingPublishers = new HashMap<>(); + Collection publishers = publisherStore.getBySlotId(request.getSlotId()); + if (publishers != null) { + for (Publisher publisher : publishers) { + Map dataInfoIdPublishers = + existingPublishers.computeIfAbsent(publisher.getDataInfoId(), k -> new HashMap<>()); + dataInfoIdPublishers.put(publisher.getRegisterId(), publisher); + } + } + DataSlotDiffDigestResult result = - calcDiffResult( - request.getSlotId(), - request.getDatumDigest(), - sessionDataStore.getDataInfoIdPublishers(request.getSlotId())); + calcDiffResult(request.getSlotId(), request.getDatumDigest(), existingPublishers); result.setSlotTableEpoch(slotTableCache.getEpoch()); result.setSessionProcessId(ServerEnv.PROCESS_ID); return new GenericResponse().fillSucceed(result); diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffPublisherRequestHandler.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffPublisherRequestHandler.java index bfcc7d575..ad42fd7d8 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffPublisherRequestHandler.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffPublisherRequestHandler.java @@ -29,11 +29,13 @@ import com.alipay.sofa.registry.server.session.bootstrap.ExecutorManager; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; import com.alipay.sofa.registry.server.session.slot.SlotTableCache; -import com.alipay.sofa.registry.server.session.store.DataStore; +import com.alipay.sofa.registry.server.session.store.PublisherStore; import com.alipay.sofa.registry.server.shared.env.ServerEnv; import com.alipay.sofa.registry.server.shared.remoting.AbstractServerHandler; import com.alipay.sofa.registry.util.ParaCheckUtil; import com.alipay.sofa.registry.util.StringFormatter; +import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; @@ -53,7 +55,7 @@ public class DataSlotDiffPublisherRequestHandler @Autowired ExecutorManager executorManager; - @Autowired DataStore sessionDataStore; + @Autowired PublisherStore publisherStore; @Autowired SlotTableCache slotTableCache; @@ -67,11 +69,17 @@ public void checkParam(DataSlotDiffPublisherRequest request) { public Object doHandle(Channel channel, DataSlotDiffPublisherRequest request) { try { final int slotId = request.getSlotId(); + Map> existingPublishers = new HashMap<>(); + Collection publishers = publisherStore.getBySlotId(slotId); + if (publishers != null) { + for (Publisher publisher : publishers) { + Map dataInfoIdPublishers = + existingPublishers.computeIfAbsent(publisher.getDataInfoId(), k -> new HashMap<>()); + dataInfoIdPublishers.put(publisher.getRegisterId(), publisher); + } + } DataSlotDiffPublisherResult result = - calcDiffResult( - slotId, - request.getDatumSummaries(), - sessionDataStore.getDataInfoIdPublishers(slotId)); + calcDiffResult(slotId, request.getDatumSummaries(), existingPublishers); result.setSlotTableEpoch(slotTableCache.getEpoch()); result.setSessionProcessId(ServerEnv.PROCESS_ID); return new GenericResponse().fillSucceed(result); diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/resource/SessionDigestResource.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/resource/SessionDigestResource.java index ca29e5411..81c32ed31 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/resource/SessionDigestResource.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/resource/SessionDigestResource.java @@ -21,7 +21,6 @@ import com.alipay.sofa.registry.common.model.CommonResponse; import com.alipay.sofa.registry.common.model.ConnectId; import com.alipay.sofa.registry.common.model.GenericResponse; -import com.alipay.sofa.registry.common.model.Tuple; import com.alipay.sofa.registry.common.model.appmeta.InterfaceMapping; import com.alipay.sofa.registry.common.model.sessionserver.PubSubDataInfoIdRequest; import com.alipay.sofa.registry.common.model.sessionserver.PubSubDataInfoIdResp; @@ -38,10 +37,11 @@ import com.alipay.sofa.registry.remoting.exchange.message.SimpleRequest; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; import com.alipay.sofa.registry.server.session.providedata.FetchStopPushService; -import com.alipay.sofa.registry.server.session.store.DataStore; import com.alipay.sofa.registry.server.session.store.FetchPubSubDataInfoIdService; -import com.alipay.sofa.registry.server.session.store.Interests; -import com.alipay.sofa.registry.server.session.store.Watchers; +import com.alipay.sofa.registry.server.session.store.PublisherStore; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; +import com.alipay.sofa.registry.server.session.store.WatcherStore; +import com.alipay.sofa.registry.server.session.store.engine.StoreEngine; import com.alipay.sofa.registry.server.shared.meta.MetaServerService; import com.alipay.sofa.registry.store.api.repository.AppRevisionRepository; import com.alipay.sofa.registry.store.api.repository.InterfaceAppsRepository; @@ -82,14 +82,9 @@ public class SessionDigestResource { private static final Logger LOGGER = LoggerFactory.getLogger(ClientManagerResource.class); - /** store subscribers */ - @Autowired private Interests sessionInterests; - - /** store watchers */ - @Autowired private Watchers sessionWatchers; - - /** store publishers */ - @Autowired private DataStore sessionDataStore; + @Autowired private SubscriberStore subscriberStore; + @Autowired private WatcherStore watcherStore; + @Autowired private PublisherStore publisherStore; @Autowired private MetaServerService metaNodeService; @@ -156,9 +151,9 @@ public Map> getSessionDataByDataInfoId( @QueryParam("dataInfoId") String dataInfoId, @PathParam("type") String type) { Map> serverList = new HashMap<>(); if (dataInfoId != null) { - Collection publishers = sessionDataStore.getDatas(dataInfoId); - Collection subscribers = sessionInterests.getDatas(dataInfoId); - Collection watchers = sessionWatchers.getDatas(dataInfoId); + Collection publishers = publisherStore.getByDataInfoId(dataInfoId); + Collection subscribers = subscriberStore.getByDataInfoId(dataInfoId); + Collection watchers = watcherStore.getByDataInfoId(dataInfoId); fillServerList(type, serverList, publishers, subscribers, watchers); } @@ -188,16 +183,9 @@ public Map> getSessionDataByConnectId( connectIds.forEach( connectId -> { - Map pubMap = sessionDataStore.queryByConnectId(connectId); - Map subMap = sessionInterests.queryByConnectId(connectId); - Map watcherMap = sessionWatchers.queryByConnectId(connectId); - - Collection publishers = - pubMap != null && !pubMap.isEmpty() ? pubMap.values() : new ArrayList<>(); - Collection subscribers = - subMap != null && !subMap.isEmpty() ? subMap.values() : new ArrayList<>(); - Collection watchers = - watcherMap != null && !watcherMap.isEmpty() ? watcherMap.values() : new ArrayList<>(); + Collection publishers = publisherStore.getByConnectId(connectId); + Collection subscribers = subscriberStore.getByConnectId(connectId); + Collection watchers = watcherStore.getByConnectId(connectId); fillServerList(type, serverList, publishers, subscribers, watchers); }); @@ -277,13 +265,13 @@ protected PubSubDataInfoIdResp merge(List resps) { @Path("/data/count") @Produces(MediaType.APPLICATION_JSON) public String getSessionDataCount() { - Tuple countSub = sessionInterests.count(); - Tuple countPub = sessionDataStore.count(); - Tuple countSubW = sessionWatchers.count(); + StoreEngine.StoreStat countSub = subscriberStore.stat(); + StoreEngine.StoreStat countPub = publisherStore.stat(); + StoreEngine.StoreStat countSubW = watcherStore.stat(); return String.format( "Subscriber count: %s, Publisher count: %s, Watcher count: %s", - countSub.o2, countPub.o2, countSubW.o2); + countSub.size(), countPub.size(), countSubW.size()); } /** return true mean push switch on */ @@ -301,8 +289,8 @@ public Map getPushSwitch() { @Produces(MediaType.APPLICATION_JSON) public Collection getDataInfoIdList() { Collection ret = new HashSet<>(); - ret.addAll(sessionInterests.getDataInfoIds()); - ret.addAll(sessionDataStore.getDataInfoIds()); + ret.addAll(subscriberStore.getNonEmptyDataInfoId()); + ret.addAll(publisherStore.getNonEmptyDataInfoId()); return ret; } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/CacheCountTask.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/CacheCountTask.java index 819b3e5ea..a5a642913 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/CacheCountTask.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/CacheCountTask.java @@ -25,13 +25,13 @@ import com.alipay.sofa.registry.log.Logger; import com.alipay.sofa.registry.log.LoggerFactory; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; -import com.alipay.sofa.registry.server.session.store.DataStore; -import com.alipay.sofa.registry.server.session.store.Interests; -import com.alipay.sofa.registry.server.session.store.Watchers; +import com.alipay.sofa.registry.server.session.store.PublisherStore; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; +import com.alipay.sofa.registry.server.session.store.WatcherStore; import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.NamedThreadFactory; import io.prometheus.client.Gauge; -import java.util.List; +import java.util.Collection; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ScheduledExecutorService; @@ -49,11 +49,9 @@ public class CacheCountTask { LoggerFactory.getLogger(CacheCountTask.class, "[CacheCountTask]"); private static final Logger COUNT_LOGGER = LoggerFactory.getLogger("CACHE-COUNT"); - @Autowired DataStore sessionDataStore; - - @Autowired Interests sessionInterests; - - @Autowired Watchers sessionWatchers; + @Autowired PublisherStore publisherStore; + @Autowired SubscriberStore subscriberStore; + @Autowired WatcherStore watcherStore; @Autowired SessionServerConfig sessionServerConfig; @@ -72,9 +70,9 @@ public boolean init() { boolean syncCount() { try { - List pubs = sessionDataStore.getDataList(); - List subs = sessionInterests.getDataList(); - List wats = sessionWatchers.getDataList(); + Collection pubs = publisherStore.getAll(); + Collection subs = subscriberStore.getAll(); + Collection wats = watcherStore.getAll(); Map>> pubGroupCounts = DataUtils.countGroupByInstanceIdGroup(pubs); diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/SessionCacheDigestTask.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/SessionCacheDigestTask.java index 78599d4ee..47355cb0a 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/SessionCacheDigestTask.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/SessionCacheDigestTask.java @@ -23,8 +23,8 @@ import com.alipay.sofa.registry.log.Logger; import com.alipay.sofa.registry.log.LoggerFactory; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; -import com.alipay.sofa.registry.server.session.store.DataStore; -import com.alipay.sofa.registry.server.session.store.Interests; +import com.alipay.sofa.registry.server.session.store.PublisherStore; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; import com.alipay.sofa.registry.util.ConcurrentUtils; import com.alipay.sofa.registry.util.NamedThreadFactory; import java.util.*; @@ -44,9 +44,9 @@ public class SessionCacheDigestTask { private static final Logger LOGGER = LoggerFactory.getLogger("CACHE-DIGEST"); - @Autowired DataStore sessionDataStore; + @Autowired PublisherStore publisherStore; - @Autowired Interests sessionInterests; + @Autowired SubscriberStore subscriberStore; @Autowired SessionServerConfig sessionServerConfig; @@ -72,16 +72,16 @@ public boolean init() { boolean dump() { try { - Collection storeDataInfoIds = sessionDataStore.getDataInfoIds(); - Collection interestDataInfoIds = sessionInterests.getDataInfoIds(); + Collection storeDataInfoIds = publisherStore.getNonEmptyDataInfoId(); + Collection interestDataInfoIds = subscriberStore.getNonEmptyDataInfoId(); Set dataInfoIds = new HashSet<>(storeDataInfoIds.size() + interestDataInfoIds.size()); dataInfoIds.addAll(storeDataInfoIds); dataInfoIds.addAll(interestDataInfoIds); for (String dataInfoId : dataInfoIds) { - Collection publishers = sessionDataStore.getDatas(dataInfoId); - Collection subscribers = sessionInterests.getDatas(dataInfoId); + Collection publishers = publisherStore.getByDataInfoId(dataInfoId); + Collection subscribers = subscriberStore.getByDataInfoId(dataInfoId); LOGGER.info( "[dataInfo] {}; {}; {}; {}; [{}]; [{}]", diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/SyncClientsHeartbeatTask.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/SyncClientsHeartbeatTask.java index 98b6b5e2c..517c60c09 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/SyncClientsHeartbeatTask.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/scheduler/timertask/SyncClientsHeartbeatTask.java @@ -16,16 +16,16 @@ */ package com.alipay.sofa.registry.server.session.scheduler.timertask; -import com.alipay.sofa.registry.common.model.Tuple; import com.alipay.sofa.registry.log.Logger; import com.alipay.sofa.registry.log.LoggerFactory; import com.alipay.sofa.registry.remoting.Server; import com.alipay.sofa.registry.remoting.exchange.Exchange; import com.alipay.sofa.registry.server.session.bootstrap.ExecutorManager; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; -import com.alipay.sofa.registry.server.session.store.DataStore; -import com.alipay.sofa.registry.server.session.store.Interests; -import com.alipay.sofa.registry.server.session.store.Watchers; +import com.alipay.sofa.registry.server.session.store.PublisherStore; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; +import com.alipay.sofa.registry.server.session.store.WatcherStore; +import com.alipay.sofa.registry.server.session.store.engine.StoreEngine; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; @@ -43,22 +43,17 @@ public class SyncClientsHeartbeatTask { @Autowired SessionServerConfig sessionServerConfig; - /** store subscribers */ - @Autowired Interests sessionInterests; - - /** store watchers */ - @Autowired Watchers sessionWatchers; - - /** store publishers */ - @Autowired DataStore sessionDataStore; + @Autowired PublisherStore publisherStore; + @Autowired SubscriberStore subscriberStore; + @Autowired WatcherStore watcherStore; @Autowired ExecutorManager executorManager; @Scheduled(initialDelay = 60000, fixedRate = 60000) public void syncCount() { - Tuple countSub = sessionInterests.count(); - Tuple countPub = sessionDataStore.count(); - Tuple countSubW = sessionWatchers.count(); + StoreEngine.StoreStat countSub = subscriberStore.stat(); + StoreEngine.StoreStat countPub = publisherStore.stat(); + StoreEngine.StoreStat countSubW = watcherStore.stat(); int channelCount = 0; Server sessionServer = boltExchange.getServer(sessionServerConfig.getServerPort()); @@ -66,19 +61,19 @@ public void syncCount() { channelCount = sessionServer.getChannelCount(); } - Metrics.PUB_SUM.set(countPub.o2); - Metrics.SUB_SUM.set(countSub.o2); - Metrics.WAT_SUM.set(countSubW.o2); + Metrics.PUB_SUM.set(countPub.size()); + Metrics.SUB_SUM.set(countSub.size()); + Metrics.WAT_SUM.set(countSubW.size()); Metrics.CHANNEL_SUM.set(channelCount); CONSOLE_COUNT_LOGGER.info( "Subscriber count: {}, Publisher count: {}, Watcher count: {}, Connection count: {}, SubDataId={}, PubDataId={}, WatDataId={}", - countSub.o2, - countPub.o2, - countSubW.o2, + countSub.size(), + countPub.size(), + countSubW.size(), channelCount, - countSub.o1, - countPub.o1, - countSubW.o1); + countSub.nonEmptyDataIdSize(), + countPub.nonEmptyDataIdSize(), + countSubW.nonEmptyDataIdSize()); } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/AbstractClientStore.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/AbstractClientStore.java new file mode 100644 index 000000000..281783d9f --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/AbstractClientStore.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; + +import com.alipay.sofa.registry.common.model.ConnectId; +import com.alipay.sofa.registry.common.model.store.StoreData; +import com.alipay.sofa.registry.server.session.store.engine.StoreEngine; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.BiConsumer; + +/** Abstract Implementation of ClientStore. */ +public abstract class AbstractClientStore> implements ClientStore { + + protected final StoreEngine storeEngine; + private final ConnectDataIndexer connectDataIndexer = + new ConnectDataIndexer(getClass().getName()); + + public AbstractClientStore(StoreEngine storeEngine) { + this.storeEngine = storeEngine; + } + + @Override + public boolean add(T storeData) { + return connectDataIndexer.add( + storeData.connectId(), + new DataPos(storeData.getDataInfoId(), storeData.getId()), + () -> storeEngine.putIfAbsent(storeData).getKey()); + } + + @Override + public T get(String dataInfoId, String registerId) { + return storeEngine.get(dataInfoId, registerId); + } + + @Override + public T delete(String dataInfoId, String registerId) { + return storeEngine.delete(dataInfoId, registerId); + } + + @Override + public Collection getByConnectId(ConnectId connectId) { + List result = new ArrayList<>(); + for (DataPos pos : connectDataIndexer.queryByKey(connectId)) { + String dataInfoId = pos.getDataInfoId(); + String registerId = pos.getRegisterId(); + T storeData = storeEngine.get(dataInfoId, registerId); + if (storeData != null) { + result.add(storeData); + } + } + return result; + } + + @Override + public Collection getByDataInfoId(String dataInfoId) { + return storeEngine.get(dataInfoId); + } + + @Override + public Collection getAll() { + return storeEngine.getAll(); + } + + @Override + public Collection getNonEmptyDataInfoId() { + return storeEngine.getNonEmptyDataInfoId(); + } + + @Override + public Collection delete(ConnectId connectId) { + List result = new ArrayList<>(); + for (DataPos pos : connectDataIndexer.queryByKey(connectId)) { + String dataInfoId = pos.getDataInfoId(); + String registerId = pos.getRegisterId(); + T storeData = storeEngine.get(dataInfoId, registerId); + if (storeData == null || !storeData.connectId().equals(connectId)) { + continue; + } + if (storeEngine.delete(storeData)) { + result.add(storeData); + } + } + return result; + } + + @Override + public Collection getAllConnectId() { + return connectDataIndexer.getKeys(); + } + + @Override + public StoreEngine.StoreStat stat() { + return storeEngine.stat(); + } + + static class ConnectDataIndexer extends DataIndexer { + + public ConnectDataIndexer(String name) { + super(name); + } + + @Override + protected void dataStoreForEach(BiConsumer consumer) {} + } +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/AbstractDataManager.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/AbstractDataManager.java deleted file mode 100644 index 566ad53b9..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/AbstractDataManager.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; - -import com.alipay.sofa.registry.common.model.ConnectId; -import com.alipay.sofa.registry.common.model.Tuple; -import com.alipay.sofa.registry.common.model.store.BaseInfo; -import com.alipay.sofa.registry.log.Logger; -import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; -import com.alipay.sofa.registry.util.ParaCheckUtil; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import java.util.*; -import java.util.function.BiConsumer; -import org.apache.commons.collections.MapUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.CollectionUtils; - -/** - * @author yuzhi.lyz - * @version v 0.1 2020-12-18 17:18 yuzhi.lyz Exp $ - */ -public abstract class AbstractDataManager - implements DataManager { - - protected final Logger logger; - - final ConnectDataIndexer connectDataIndexer = new ConnectDataIndexer(getClass().getName()); - - @Autowired protected SessionServerConfig sessionServerConfig; - - AbstractDataManager(Logger logger) { - this.logger = logger; - } - - private Tuple addDataToStore(T data) { - Map dataMap = getStore().getOrCreate(data.getDataInfoId()); - final String registerId = data.getRegisterId(); - // quick path - if (dataMap.putIfAbsent(registerId, data) == null) { - return new Tuple<>(null, true); - } - for (; ; ) { - final T existing = dataMap.get(registerId); - if (existing == null) { - if (dataMap.putIfAbsent(registerId, data) == null) { - return new Tuple<>(null, true); - } - } else { - if (!existing.registerVersion().orderThan(data.registerVersion())) { - logger.warn( - "[conflict]{},{},exist={}/{},input={}/{}", - data.getDataInfoId(), - data.getRegisterId(), - existing.registerVersion(), - existing.getRegisterTimestamp(), - data.registerVersion(), - data.getRegisterTimestamp()); - return new Tuple<>(existing, false); - } - if (dataMap.replace(registerId, existing, data)) { - return new Tuple<>(existing, true); - } - } - } - } - - protected Tuple addData(T data) { - return connectDataIndexer.add(data.connectId(), DataPos.of(data), () -> addDataToStore(data)); - } - - @Override - public T deleteById(String registerId, String dataInfoId) { - Map dataMap = getStore().get(dataInfoId); - if (CollectionUtils.isEmpty(dataMap)) { - logger.warn("Delete but not registered, {}", dataInfoId); - return null; - } - T dataToDelete = dataMap.remove(registerId); - - if (dataToDelete == null) { - logger.warn("Delete but not registered, {}, {}", dataInfoId, registerId); - } - return dataToDelete; - } - - @Override - public Map deleteByConnectId(ConnectId connectId) { - Store store = getStore(); - Map ret = Maps.newHashMapWithExpectedSize(128); - for (DataPos pos : connectDataIndexer.queryByKey(connectId)) { - Map dataMap = store.get(pos.getDataInfoId()); - if (CollectionUtils.isEmpty(dataMap)) { - continue; - } - T data = dataMap.get(pos.getRegisterId()); - if (data == null || !data.connectId().equals(connectId)) { - continue; - } - if (dataMap.remove(pos.getRegisterId(), data)) { - ret.put(data.getRegisterId(), data); - } - } - return ret; - } - - @Override - public Map> deleteByConnectIds(Set connectIds) { - Map> ret = Maps.newHashMapWithExpectedSize(connectIds.size()); - for (ConnectId connectId : connectIds) { - Map m = deleteByConnectId(connectId); - if (!CollectionUtils.isEmpty(m)) { - ret.put(connectId, m); - } - } - return ret; - } - - @Override - public void forEach(BiConsumer> consumer) { - getStore() - .forEach( - (String dataInfoId, Map datas) -> { - if (!CollectionUtils.isEmpty(datas)) { - consumer.accept(dataInfoId, Collections.unmodifiableMap(datas)); - } - }); - } - - @Override - public Collection getDatas(String dataInfoId) { - ParaCheckUtil.checkNotBlank(dataInfoId, "dataInfoId"); - Map dataMap = getStore().get(dataInfoId); - if (MapUtils.isEmpty(dataMap)) { - return Collections.emptyList(); - } - return Lists.newArrayList(dataMap.values()); - } - - @Override - public Map> getDatas() { - return getStore().copyMap(); - } - - @Override - public List getDataList() { - List ret = new ArrayList<>(1024); - getStore() - .forEach( - (String dataInfoId, Map datas) -> { - ret.addAll(datas.values()); - }); - return ret; - } - - @Override - public Map queryByConnectId(ConnectId connectId) { - Map ret = Maps.newHashMapWithExpectedSize(128); - for (DataPos pos : connectDataIndexer.queryByKey(connectId)) { - T data = queryById(pos.getRegisterId(), pos.getDataInfoId()); - if (data != null && data.connectId().equals(connectId)) { - ret.put(data.getRegisterId(), data); - } - } - return ret; - } - - /** - * query data by client node connectId - * - * @param connectIds - * @return - */ - @Override - public Map> queryByConnectIds(Set connectIds) { - Map> ret = Maps.newHashMapWithExpectedSize(connectIds.size()); - for (ConnectId connectId : connectIds) { - Map m = queryByConnectId(connectId); - if (!CollectionUtils.isEmpty(m)) { - ret.put(connectId, m); - } - } - return ret; - } - - @Override - public T queryById(String registerId, String dataInfoId) { - final Map datas = getStore().get(dataInfoId); - return datas == null ? null : datas.get(registerId); - } - - @Override - public Tuple count() { - return getStore().count(); - } - - @Override - public Set getConnectIds() { - return connectDataIndexer.getKeys(); - } - - @Override - public Collection getDataInfoIds() { - return getStore().getDataInfoIds(); - } - - public SessionServerConfig getSessionServerConfig() { - return sessionServerConfig; - } - - /** - * Setter method for property sessionServerConfig. - * - * @param sessionServerConfig value to be assigned to property sessionServerConfig - */ - public void setSessionServerConfig(SessionServerConfig sessionServerConfig) { - this.sessionServerConfig = sessionServerConfig; - } - - protected abstract Store getStore(); - - class ConnectDataIndexer extends DataIndexer { - - public ConnectDataIndexer(String name) { - super(name); - } - - @Override - protected void dataStoreForEach(BiConsumer consumer) { - Store store = getStore(); - if (store == null) { - return; - } - store.forEach( - (dataInfoId, datum) -> { - for (T data : datum.values()) { - consumer.accept(data.connectId(), DataPos.of(data)); - } - }); - } - } -} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/ClientStore.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/ClientStore.java new file mode 100644 index 000000000..ceaaf0fe9 --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/ClientStore.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; + +import com.alipay.sofa.registry.common.model.ConnectId; +import com.alipay.sofa.registry.common.model.store.StoreData; +import com.alipay.sofa.registry.server.session.store.engine.StoreEngine; +import java.util.Collection; + +/** Used to store client information. */ +public interface ClientStore> { + + /** + * Add client. + * + * @param storeData client data + * @return true if add successfully + */ + boolean add(T storeData); + + /** + * Get client data by dataInfoId and registerId. + * + * @param dataInfoId dataInfoId + * @param registerId registerId + * @return client data + */ + T get(String dataInfoId, String registerId); + + /** + * Delete client by dataInfoId and registerId. + * + * @param dataInfoId dataInfoId + * @param registerId registerId + * @return client deleted + */ + T delete(String dataInfoId, String registerId); + + /** + * Get client by dataInfoId. + * + * @param dataInfoId dataInfoId + * @return client data + */ + Collection getByDataInfoId(String dataInfoId); + + /** + * Get client by ConnectId. + * + * @param connectId ConnectId + * @return client data + */ + Collection getByConnectId(ConnectId connectId); + + /** + * Delete client data with ConnectId. + * + * @param connectId ConnectId + * @return deleted client data + */ + Collection delete(ConnectId connectId); + + /** + * Get all connectId. + * + * @return ConnectId collection + */ + Collection getAllConnectId(); + + /** + * Get all client data. + * + * @return all client data + */ + Collection getAll(); + + /** + * Get all dataInfoId which has non-empty client collection. + * + * @return dataInfo collection + */ + Collection getNonEmptyDataInfoId(); + + /** + * Get stat info. + * + * @return store stat info + */ + StoreEngine.StoreStat stat(); +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/ClientsGroup.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/ClientsGroup.java new file mode 100644 index 000000000..20a8d5707 --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/ClientsGroup.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; + +import com.alipay.sofa.registry.common.model.store.StoreData; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import javafx.util.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** A series of StoreData collections with the same dataInfoId. */ +public class ClientsGroup> { + + private static final Logger LOGGER = LoggerFactory.getLogger(ClientsGroup.class); + + private final String dataInfoId; + private final Map clients; + + public ClientsGroup(String dataInfoId, int initialSize) { + this.dataInfoId = dataInfoId; + this.clients = new ConcurrentHashMap<>(initialSize); + } + + public String dataInfoId() { + return dataInfoId; + } + + public int size() { + return clients.size(); + } + + public Pair putIfAbsent(T storeData) { + String registerId = storeData.getId(); + StoreData exist = clients.putIfAbsent(registerId, storeData); + if (exist == null) { + return new Pair<>(true, null); + } + + for (; ; ) { + final T existing = clients.get(registerId); + if (existing == null) { + if (clients.putIfAbsent(registerId, storeData) == null) { + System.out.println(">>>>>>>>>>" + System.currentTimeMillis() + " add: " + registerId); + return new Pair<>(true, null); + } + } else { + if (!existing.registerVersion().orderThan(storeData.registerVersion())) { + LOGGER.warn( + "[conflict]{},{},exist={}/{},input={}/{}", + storeData.getDataInfoId(), + registerId, + existing.registerVersion(), + existing.getRegisterTimestamp(), + storeData.registerVersion(), + storeData.getRegisterTimestamp()); + return new Pair<>(false, existing); + } + if (clients.replace(registerId, existing, storeData)) { + System.out.println(">>>>>>>>>>" + System.currentTimeMillis() + " add: " + registerId); + return new Pair<>(true, existing); + } + } + } + } + + public T get(String registerId) { + return clients.get(registerId); + } + + public T remove(String registerId) { + return clients.remove(registerId); + } + + public boolean remove(T t) { + return clients.remove(t.getId(), t); + } + + public Collection all() { + return clients.values(); + } + + public Collection limit(int limit) { + return clients.values().stream().limit(Math.max(limit, 0)).collect(Collectors.toList()); + } +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/DataManager.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/DataManager.java deleted file mode 100644 index 05f5c91c2..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/DataManager.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; - -import com.alipay.sofa.registry.common.model.ConnectId; -import com.alipay.sofa.registry.common.model.Tuple; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.BiConsumer; - -/** - * Session Data store manager,according base data function - * - *

Session Data struct - * - *

- DataInfo ID | - Publisher List | - Subscriber List - * - * @author shangyu.wh - * @version $Id: DataManager.java, v 0.1 2017-11-30 17:57 shangyu.wh Exp $ - */ -public interface DataManager { - - /** - * new publisher and subscriber data add - * - * @param data - */ - boolean add(DATA data); - - /** - * query data by client node connectId - * - * @param connectId - * @return - */ - Map queryByConnectId(ConnectId connectId); - - /** - * query data by client node connectId - * - * @param connectIds - * @return - */ - Map> queryByConnectIds(Set connectIds); - - /** - * remove data by client node connectId - * - * @param connectId - */ - Map deleteByConnectId(ConnectId connectId); - - /** - * remove data by client node connectIds - * - * @param connectIds - */ - Map> deleteByConnectIds(Set connectIds); - - DATA queryById(ID registerId, DATAINFOID dataInfoId); - - /** - * remove single data by register id - * - * @param registerId - * @param dataInfoId - * @return - */ - DATA deleteById(ID registerId, DATAINFOID dataInfoId); - - /** dataInfoId.size and data.size */ - Tuple count(); - - Set getConnectIds(); - - Collection getDatas(DATAINFOID dataInfoId); - - List getDataList(); - - Map> getDatas(); - - Collection getDataInfoIds(); - - void forEach(BiConsumer> consumer); -} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/FetchPubSubDataInfoIdService.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/FetchPubSubDataInfoIdService.java index f1e09378b..52b5842c8 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/FetchPubSubDataInfoIdService.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/FetchPubSubDataInfoIdService.java @@ -23,6 +23,8 @@ import com.alipay.sofa.registry.server.session.connections.ConnectionsService; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -40,10 +42,10 @@ public class FetchPubSubDataInfoIdService { @Autowired private ConnectionsService connectionsService; /** store subscribers */ - @Autowired protected Interests sessionInterests; + @Autowired protected SubscriberStore subscriberStore; /** store publishers */ - @Autowired protected DataStore sessionDataStore; + @Autowired protected PublisherStore publisherStore; public PubSubDataInfoIdResp queryByIps(Set ips) { @@ -53,10 +55,27 @@ public PubSubDataInfoIdResp queryByIps(Set ips) { return resp; } - Map> connectIdPubMap = - sessionDataStore.queryByConnectIds(Sets.newHashSet(connectIds)); - Map> connectIdSubMap = - sessionInterests.queryByConnectIds(Sets.newHashSet(connectIds)); + Map> connectIdPubMap = new HashMap<>(); + Map> connectIdSubMap = new HashMap<>(); + for (ConnectId connectId : connectIds) { + Collection publishers = publisherStore.getByConnectId(connectId); + if (publishers != null && publishers.size() > 0) { + for (Publisher publisher : publishers) { + Map dataInfoIdPublishers = + connectIdPubMap.computeIfAbsent(publisher.connectId(), connectId1 -> new HashMap<>()); + dataInfoIdPublishers.put(publisher.getRegisterId(), publisher); + } + } + Collection subscribers = subscriberStore.getByConnectId(connectId); + if (subscribers != null && subscribers.size() > 0) { + for (Subscriber subscriber : subscribers) { + Map dataInfoIdSubscribers = + connectIdSubMap.computeIfAbsent( + subscriber.connectId(), connectId1 -> new HashMap<>()); + dataInfoIdSubscribers.put(subscriber.getRegisterId(), subscriber); + } + } + } // collect pub and sub dataInfoIds Map> pubs = parsePubDataInfoIds(connectIdPubMap); diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/DataStore.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/PublisherStore.java similarity index 74% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/DataStore.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/PublisherStore.java index 5236cefde..2576a3d08 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/DataStore.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/PublisherStore.java @@ -17,14 +17,16 @@ package com.alipay.sofa.registry.server.session.store; import com.alipay.sofa.registry.common.model.store.Publisher; -import java.util.Map; +import java.util.Collection; -/** - * @author shangyu.wh - * @version $Id: DataStore.java, v 0.1 2017-12-01 18:13 shangyu.wh Exp $ - */ -public interface DataStore extends DataManager { +/** Used to store publisher information */ +public interface PublisherStore extends ClientStore { - Map> getDataInfoIdPublishers( - int slotId); + /** + * Get publisher with slot. + * + * @param slotId slot id + * @return publisher collection + */ + Collection getBySlotId(int slotId); } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionWatchers.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/PublisherStoreImpl.java similarity index 51% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionWatchers.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/PublisherStoreImpl.java index 2a80a1ee1..fb8465968 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionWatchers.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/PublisherStoreImpl.java @@ -16,33 +16,22 @@ */ package com.alipay.sofa.registry.server.session.store; -import com.alipay.sofa.registry.common.model.Tuple; -import com.alipay.sofa.registry.common.model.store.Watcher; -import com.alipay.sofa.registry.log.Logger; -import com.alipay.sofa.registry.log.LoggerFactory; +import com.alipay.sofa.registry.common.model.store.Publisher; +import com.alipay.sofa.registry.server.session.slot.SlotTableCache; +import com.alipay.sofa.registry.server.session.store.engine.SlotMemoryStoreEngine; +import java.util.Collection; -/** - * @author shangyu.wh - * @version $Id: SessionWatchers.java, v 0.1 2018-04-17 19:00 shangyu.wh Exp $ - */ -public class SessionWatchers extends AbstractDataManager implements Watchers { - private static final Logger LOGGER = LoggerFactory.getLogger(SessionWatchers.class); - - private final Store store = new SimpleStore<>(1024 * 16, 32); +/** Implementation of PublisherStore. */ +public class PublisherStoreImpl extends AbstractClientStore implements PublisherStore { - public SessionWatchers() { - super(LOGGER); - } - - @Override - public boolean add(Watcher watcher) { - Watcher.internWatcher(watcher); - Tuple ret = addData(watcher); - return ret.o2; + public PublisherStoreImpl(SlotTableCache slotTableCache) { + super(new SlotMemoryStoreEngine<>(slotTableCache::slotOf)); } @Override - protected Store getStore() { - return store; + public Collection getBySlotId(int slotId) { + SlotMemoryStoreEngine slotStoreEngine = + (SlotMemoryStoreEngine) storeEngine; + return slotStoreEngine.getSlotStoreData(slotId); } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionDataStore.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionDataStore.java deleted file mode 100644 index 3332a580d..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionDataStore.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; - -import com.alipay.sofa.registry.common.model.PublisherUtils; -import com.alipay.sofa.registry.common.model.Tuple; -import com.alipay.sofa.registry.common.model.store.Publisher; -import com.alipay.sofa.registry.log.Logger; -import com.alipay.sofa.registry.log.LoggerFactory; -import com.alipay.sofa.registry.server.session.slot.SlotTableCache; -import com.alipay.sofa.registry.util.ParaCheckUtil; -import com.google.common.annotations.VisibleForTesting; -import java.util.Map; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * @author shangyu.wh - * @version $Id: SessionDataStore.java, v 0.1 2017-12-01 18:14 shangyu.wh Exp $ - */ -public class SessionDataStore extends AbstractDataManager implements DataStore { - - private static final Logger LOGGER = LoggerFactory.getLogger(SessionDataStore.class); - - @Autowired SlotTableCache slotTableCache; - - private final SlotStore store = new SlotStore<>(this::slotOf); - - public SessionDataStore() { - super(LOGGER); - } - - @Override - public boolean add(Publisher publisher) { - ParaCheckUtil.checkNotNull(publisher.getVersion(), "publisher.version"); - ParaCheckUtil.checkNotNull(publisher.getRegisterTimestamp(), "publisher.registerTimestamp"); - - PublisherUtils.internPublisher(publisher); - Tuple ret = addData(publisher); - return ret.o2; - } - - @Override - public Map> getDataInfoIdPublishers(int slotId) { - return store.copyMap(slotId); - } - - @Override - protected Store getStore() { - return store; - } - - @VisibleForTesting - public void setSlotTableCache(SlotTableCache slotTableCache) { - this.slotTableCache = slotTableCache; - } - - protected int slotOf(String dataInfoId) { - return slotTableCache.slotOf(dataInfoId); - } -} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionInterests.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionInterests.java deleted file mode 100644 index 40ff4cc15..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SessionInterests.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; - -import com.alipay.sofa.registry.common.model.Tuple; -import com.alipay.sofa.registry.common.model.dataserver.DatumVersion; -import com.alipay.sofa.registry.common.model.store.Subscriber; -import com.alipay.sofa.registry.core.model.ScopeEnum; -import com.alipay.sofa.registry.log.Logger; -import com.alipay.sofa.registry.log.LoggerFactory; -import com.alipay.sofa.registry.util.ParaCheckUtil; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import org.apache.commons.lang.StringUtils; -import org.springframework.util.CollectionUtils; - -/** - * @author shangyu.wh - * @version $Id: AbstractSessionInterests.java, v 0.1 2017-11-30 20:42 shangyu.wh Exp $ - */ -public class SessionInterests extends AbstractDataManager implements Interests { - - private static final Logger LOGGER = LoggerFactory.getLogger(SessionInterests.class); - - public SessionInterests() { - super(LOGGER); - } - - private final Store store = new SimpleStore<>(1024 * 16, 256); - - @Override - public boolean add(Subscriber subscriber) { - ParaCheckUtil.checkNotNull(subscriber.getScope(), "subscriber.scope"); - ParaCheckUtil.checkNotNull(subscriber.getClientVersion(), "subscriber.clientVersion"); - - Subscriber.internSubscriber(subscriber); - Tuple ret = addData(subscriber); - return ret.o2; - } - - @Override - public InterestVersionCheck checkInterestVersion( - String dataCenter, String datumDataInfoId, long version) { - Collection subscribers = getInterests(datumDataInfoId); - if (CollectionUtils.isEmpty(subscribers)) { - return InterestVersionCheck.NoSub; - } - for (Subscriber subscriber : subscribers) { - if (subscriber.checkVersion(dataCenter, version)) { - return InterestVersionCheck.Interested; - } - } - return InterestVersionCheck.Obsolete; - } - - @Override - public Collection getInterests(String datumDataInfoId) { - return getDatas(datumDataInfoId); - } - - @Override - public Tuple, List> selectSubscribers(String dataCenter) { - final String localDataCenter = sessionServerConfig.getSessionServerDataCenter(); - final boolean isLocalDataCenter = localDataCenter.equals(dataCenter); - Store store = getStore(); - final Map versions = - Maps.newHashMapWithExpectedSize(store.getDataInfoIds().size()); - final List toPushEmptySubscribers = Lists.newArrayListWithCapacity(256); - - store.forEach( - (String dataInfoId, Map subs) -> { - if (CollectionUtils.isEmpty(subs)) { - return; - } - long maxVersion = 0; - for (Subscriber sub : subs.values()) { - // not global sub and not local dataCenter, not interest the other dataCenter's pub - if (sub.getScope() != ScopeEnum.global && !isLocalDataCenter) { - continue; - } - if (sub.isMarkedPushEmpty(dataCenter)) { - if (sub.needPushEmpty(dataCenter)) { - toPushEmptySubscribers.add(sub); - } - continue; - } - final long pushVersion = sub.getPushedVersion(dataCenter); - if (maxVersion < pushVersion) { - maxVersion = pushVersion; - } - } - versions.put(dataInfoId, new DatumVersion(maxVersion)); - }); - return Tuple.of(versions, toPushEmptySubscribers); - } - - @Override - protected Store getStore() { - return store; - } - - @Override - public Map> filterIPs(String group, int limit) { - Map> ret = Maps.newHashMapWithExpectedSize(1024); - forEach( - (String dataInfoId, Map subs) -> { - if (CollectionUtils.isEmpty(subs)) { - return; - } - String g = subs.values().stream().findAny().get().getGroup(); - if (!StringUtils.equals(g, group)) { - return; - } - ret.put( - dataInfoId, - subs.values().stream() - .map(s -> s.getSourceAddress().getIpAddress()) - .limit(Math.max(limit, 0)) - .collect(Collectors.toList())); - }); - return ret; - } -} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SimpleStore.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SimpleStore.java deleted file mode 100644 index 3034b7dc9..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SimpleStore.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; - -import com.alipay.sofa.registry.common.model.Tuple; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiConsumer; -import org.springframework.util.CollectionUtils; - -public class SimpleStore implements Store { - protected final Map> stores; - private final int registerIdCount; - - public SimpleStore(int dataIdCount, int registerIdCount) { - stores = new ConcurrentHashMap<>(dataIdCount); - this.registerIdCount = registerIdCount; - } - - @Override - public Map get(String dataInfoId) { - return stores.get(dataInfoId); - } - - @Override - public Map getOrCreate(String dataInfoId) { - return stores.computeIfAbsent(dataInfoId, k -> new ConcurrentHashMap<>(registerIdCount)); - } - - @Override - public void forEach(BiConsumer> consumer) { - stores.forEach(consumer); - } - - @Override - public Map> copyMap() { - Map> ret = Maps.newHashMapWithExpectedSize(stores.size()); - for (Map.Entry> e : stores.entrySet()) { - if (!e.getValue().isEmpty()) { - ret.put(e.getKey(), new HashMap<>(e.getValue())); - } - } - return ret; - } - - @Override - public Tuple count() { - long dataInfoIdCount = 0; - long dataCount = 0; - for (Map map : stores.values()) { - int size = map.size(); - dataCount += size; - if (size != 0) { - dataInfoIdCount++; - } - } - return Tuple.of(dataInfoIdCount, dataCount); - } - - @Override - public Collection getDataInfoIds() { - Set ret = Sets.newHashSetWithExpectedSize(stores.values().size()); - for (Map.Entry> e : stores.entrySet()) { - if (!CollectionUtils.isEmpty(e.getValue())) { - ret.add(e.getKey()); - } - } - return ret; - } -} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SlotStore.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SlotStore.java deleted file mode 100644 index c2f47e962..000000000 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SlotStore.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; - -import com.alipay.sofa.registry.common.model.Tuple; -import com.google.common.collect.Maps; -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiConsumer; -import org.glassfish.jersey.internal.guava.Sets; - -public class SlotStore implements Store { - private final Map> slots = new ConcurrentHashMap<>(512); - private final SlotOfCaller slotOfCaller; - - public SlotStore(SlotOfCaller slotOfCaller) { - this.slotOfCaller = slotOfCaller; - } - - private SimpleStore getOrCreateStore(int slotId) { - return slots.computeIfAbsent(slotId, k -> new SimpleStore<>(256, 256)); - } - - private SimpleStore getOrCreateStore(String dataInfoId) { - int slotId = slotOfCaller.slotOf(dataInfoId); - return getOrCreateStore(slotId); - } - - @Override - public Map get(String dataInfoId) { - return getOrCreateStore(dataInfoId).get(dataInfoId); - } - - @Override - public Map getOrCreate(String dataInfoId) { - return getOrCreateStore(dataInfoId).getOrCreate(dataInfoId); - } - - @Override - public void forEach(BiConsumer> consumer) { - for (SimpleStore store : slots.values()) { - store.forEach(consumer); - } - } - - @Override - public Map> copyMap() { - Map> ret = Maps.newHashMapWithExpectedSize(1024 * 16); - for (SimpleStore store : slots.values()) { - ret.putAll(store.copyMap()); - } - return ret; - } - - public Map> copyMap(int slotId) { - SimpleStore store = getOrCreateStore(slotId); - return store.copyMap(); - } - - public Tuple count() { - long dataInfoIdCount = 0; - long dataCount = 0; - for (SimpleStore store : slots.values()) { - Tuple ret = store.count(); - dataInfoIdCount += ret.getFirst(); - dataCount += ret.getSecond(); - } - return new Tuple<>(dataInfoIdCount, dataCount); - } - - @Override - public Collection getDataInfoIds() { - Set ret = Sets.newHashSetWithExpectedSize(1024 * 16); - for (SimpleStore store : slots.values()) { - ret.addAll(store.getDataInfoIds()); - } - return ret; - } - - public interface SlotOfCaller { - int slotOf(String dataInfoId); - } -} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/Interests.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SubscriberStore.java similarity index 66% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/Interests.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SubscriberStore.java index 0cd89a738..02ba0452b 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/Interests.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SubscriberStore.java @@ -23,29 +23,36 @@ import java.util.List; import java.util.Map; -/** - * @author shangyu.wh - * @version $Id: SessionInterests.java, v 0.1 2017-11-30 15:53 shangyu.wh Exp $ - */ -public interface Interests extends DataManager { +/** Used to store subscriber information. */ +public interface SubscriberStore extends ClientStore { /** - * check subscribers interest dataInfoId version,very dataCenter dataInfoId version different if - * return false else check return bigger version + * Group subscriber by group and returns a limit of elements. * - * @param dataCenter - * @param datumDataInfoId - * @param version - * @return + * @param group target group of Subscriber + * @param limit maximum number to return, returns empty if negative + * @return subscriber collection */ - InterestVersionCheck checkInterestVersion( - String dataCenter, String datumDataInfoId, long version); - - Collection getInterests(String datumDataInfoId); + Map> query(String group, int limit); + /** + * Select subscriber with target data center. + * + * @param dataCenter target data center + * @return subscriber collection + */ Tuple, List> selectSubscribers(String dataCenter); - Map> filterIPs(String group, int limit); + /** + * Check if there is subscriber that interest the data and has correct version. + * + * @param dataCenter data center + * @param datumDataInfoId data id + * @param version required version + * @return InterestVersionCheck + */ + InterestVersionCheck checkInterestVersion( + String dataCenter, String datumDataInfoId, long version); enum InterestVersionCheck { NoSub(false), diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SubscriberStoreImpl.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SubscriberStoreImpl.java new file mode 100644 index 000000000..279e4274e --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/SubscriberStoreImpl.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; + +import com.alipay.sofa.registry.common.model.Tuple; +import com.alipay.sofa.registry.common.model.dataserver.DatumVersion; +import com.alipay.sofa.registry.common.model.store.Subscriber; +import com.alipay.sofa.registry.core.model.ScopeEnum; +import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; +import com.alipay.sofa.registry.server.session.store.engine.SimpleMemoryStoreEngine; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.springframework.util.CollectionUtils; + +/** Implementation of SubscriberStore. */ +public class SubscriberStoreImpl extends AbstractClientStore + implements SubscriberStore { + + private final SessionServerConfig sessionServerConfig; + + public SubscriberStoreImpl(SessionServerConfig sessionServerConfig) { + super(new SimpleMemoryStoreEngine<>(1024 * 16)); + this.sessionServerConfig = sessionServerConfig; + } + + @Override + public Map> query(String group, int limit) { + return storeEngine.filter(group, limit); + } + + @Override + public Tuple, List> selectSubscribers(String dataCenter) { + final String localDataCenter = sessionServerConfig.getSessionServerDataCenter(); + final boolean isLocalDataCenter = localDataCenter.equals(dataCenter); + + final Map versions = new HashMap<>(); + final List toPushEmptySubscribers = new ArrayList<>(); + + Collection dataInfoIdCollection = getNonEmptyDataInfoId(); + if (dataInfoIdCollection == null || dataInfoIdCollection.size() == 0) { + return Tuple.of(versions, toPushEmptySubscribers); + } + for (String dataInfoId : dataInfoIdCollection) { + Collection subscribers = getByDataInfoId(dataInfoId); + if (CollectionUtils.isEmpty(subscribers)) { + continue; + } + + long maxVersion = 0; + for (Subscriber sub : subscribers) { + // not global sub and not local dataCenter, not interest the other dataCenter's pub + if (sub.getScope() != ScopeEnum.global && !isLocalDataCenter) { + continue; + } + if (sub.isMarkedPushEmpty(dataCenter)) { + if (sub.needPushEmpty(dataCenter)) { + toPushEmptySubscribers.add(sub); + } + continue; + } + final long pushVersion = sub.getPushedVersion(dataCenter); + if (maxVersion < pushVersion) { + maxVersion = pushVersion; + } + } + versions.put(dataInfoId, new DatumVersion(maxVersion)); + } + return Tuple.of(versions, toPushEmptySubscribers); + } + + @Override + public InterestVersionCheck checkInterestVersion( + String dataCenter, String datumDataInfoId, long version) { + Collection subscribers = getByDataInfoId(datumDataInfoId); + if (CollectionUtils.isEmpty(subscribers)) { + return InterestVersionCheck.NoSub; + } + for (Subscriber subscriber : subscribers) { + if (subscriber.checkVersion(dataCenter, version)) { + return InterestVersionCheck.Interested; + } + } + return InterestVersionCheck.Obsolete; + } +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/Watchers.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/WatcherStore.java similarity index 83% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/Watchers.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/WatcherStore.java index 48a7bc80e..91f08c20a 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/Watchers.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/WatcherStore.java @@ -18,8 +18,5 @@ import com.alipay.sofa.registry.common.model.store.Watcher; -/** - * @author shangyu.wh - * @version $Id: SessionInterests.java, v 0.1 2017-11-30 15:53 shangyu.wh Exp $ - */ -public interface Watchers extends DataManager {} +/** Used to store observer information */ +public interface WatcherStore extends ClientStore {} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/Store.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/WatcherStoreImpl.java similarity index 66% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/Store.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/WatcherStoreImpl.java index 24598a32b..87968c0d8 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/Store.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/WatcherStoreImpl.java @@ -16,21 +16,13 @@ */ package com.alipay.sofa.registry.server.session.store; -import com.alipay.sofa.registry.common.model.Tuple; -import java.util.Collection; -import java.util.Map; -import java.util.function.BiConsumer; +import com.alipay.sofa.registry.common.model.store.Watcher; +import com.alipay.sofa.registry.server.session.store.engine.SimpleMemoryStoreEngine; -public interface Store { - Map get(String dataInfoId); +/** Implementation of WatcherStore. */ +public class WatcherStoreImpl extends AbstractClientStore implements WatcherStore { - Map getOrCreate(String dataInfoId); - - void forEach(BiConsumer> consumer); - - Map> copyMap(); - - Tuple count(); - - Collection getDataInfoIds(); + public WatcherStoreImpl() { + super(new SimpleMemoryStoreEngine<>(1024 * 16)); + } } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngine.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngine.java new file mode 100644 index 000000000..fecd38713 --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngine.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store.engine; + +import com.alipay.sofa.registry.common.model.store.DataInfo; +import com.alipay.sofa.registry.common.model.store.StoreData; +import com.alipay.sofa.registry.server.session.store.ClientsGroup; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import javafx.util.Pair; + +/** StoreEngine implemented based on HashMap. */ +public class SimpleMemoryStoreEngine> implements StoreEngine { + + private final Map> groups; + + public SimpleMemoryStoreEngine(int initialSize) { + this.groups = new ConcurrentHashMap<>(initialSize); + } + + @Override + public Pair putIfAbsent(T storeData) { + String dataInfoId = storeData.getDataInfoId(); + ClientsGroup clientsGroup = groups.get(dataInfoId); + if (clientsGroup == null) { + clientsGroup = new ClientsGroup<>(dataInfoId, 128); + ClientsGroup exist = groups.putIfAbsent(dataInfoId, clientsGroup); + if (exist != null) { + // 如果之前已经存在了,直接复用之前的ClientGroups,并向其中加入新的StoreData + // 如果exist == null,意味着新的ClientGroups被添加进去了,向新的ClientGroups加入StoreData + clientsGroup = exist; + } + } + + return clientsGroup.putIfAbsent(storeData); + } + + @Override + public T get(String dataInfoId, String registerId) { + ClientsGroup clientsGroup = groups.get(dataInfoId); + if (clientsGroup == null) { + return null; + } + + return clientsGroup.get(registerId); + } + + @Override + public T delete(String dataInfoId, String registerId) { + ClientsGroup clientsGroup = groups.get(dataInfoId); + if (clientsGroup == null) { + return null; + } + return clientsGroup.remove(registerId); + } + + @Override + public boolean delete(T storeData) { + ClientsGroup clientsGroup = groups.get(storeData.getDataInfoId()); + if (clientsGroup == null) { + return false; + } + return clientsGroup.remove(storeData); + } + + @Override + public Collection get(String dataInfoId) { + ClientsGroup clientsGroup = groups.get(dataInfoId); + if (clientsGroup == null) { + return null; + } + return clientsGroup.all(); + } + + @Override + public Collection getAll() { + Set result = new HashSet<>(); + for (ClientsGroup clientsGroup : groups.values()) { + Collection storeDataCollection = clientsGroup.all(); + if (storeDataCollection != null && storeDataCollection.size() > 0) { + result.addAll(storeDataCollection); + } + } + return result; + } + + @Override + public Map> filter(String group, int limit) { + Map> result = new HashMap<>(); + for (Map.Entry> entry : groups.entrySet()) { + String dataInfoId = entry.getKey(); + if (!group.equals(DataInfo.parse(dataInfoId)[2])) { + continue; + } + result.put(dataInfoId, entry.getValue().limit(limit)); + } + return result; + } + + @Override + public Collection getNonEmptyDataInfoId() { + Set result = new HashSet<>(); + for (ClientsGroup clientsGroup : groups.values()) { + if (clientsGroup.size() > 0) { + result.add(clientsGroup.dataInfoId()); + } + } + return result; + } + + @Override + public StoreStat stat() { + long dataInfoIdCount = 0; + long dataCount = 0; + for (ClientsGroup clientsGroup : groups.values()) { + int size = clientsGroup.size(); + dataCount += size; + if (size != 0) { + dataInfoIdCount++; + } + } + return new StoreStat(dataInfoIdCount, dataCount); + } +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SlotMemoryStoreEngine.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SlotMemoryStoreEngine.java new file mode 100644 index 000000000..eead55290 --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SlotMemoryStoreEngine.java @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store.engine; + +import com.alipay.sofa.registry.common.model.store.StoreData; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import javafx.util.Pair; + +/** + * Combine a series of SimpleMemoryStoreEngine and map and store StoreData according to a certain + * strategy. + */ +public class SlotMemoryStoreEngine> implements SlotStoreEngine { + + private final SlotCaller slotCaller; + private final Map> slotsStore; + + public SlotMemoryStoreEngine(SlotCaller slotCaller) { + this.slotCaller = slotCaller; + this.slotsStore = new ConcurrentHashMap<>(512); + } + + private SimpleMemoryStoreEngine getOrCreateStore(String dataInfoId) { + int slotId = slotCaller.slotOf(dataInfoId); + return slotsStore.computeIfAbsent(slotId, integer -> new SimpleMemoryStoreEngine<>(256)); + } + + @Override + public Pair putIfAbsent(T storeData) { + SimpleMemoryStoreEngine storeEngine = getOrCreateStore(storeData.getDataInfoId()); + return storeEngine.putIfAbsent(storeData); + } + + @Override + public T get(String dataInfoId, String registerId) { + SimpleMemoryStoreEngine storeEngine = getOrCreateStore(dataInfoId); + return storeEngine.get(dataInfoId, registerId); + } + + @Override + public T delete(String dataInfoId, String registerId) { + SimpleMemoryStoreEngine storeEngine = getOrCreateStore(dataInfoId); + return storeEngine.delete(dataInfoId, registerId); + } + + @Override + public boolean delete(T storeData) { + SimpleMemoryStoreEngine storeEngine = getOrCreateStore(storeData.getDataInfoId()); + return storeEngine.delete(storeData); + } + + @Override + public Collection get(String dataInfoId) { + int slotId = slotCaller.slotOf(dataInfoId); + SimpleMemoryStoreEngine storeEngine = slotsStore.get(slotId); + if (storeEngine == null) { + return null; + } + return storeEngine.get(dataInfoId); + } + + @Override + public Collection getAll() { + Set result = new HashSet<>(); + for (SimpleMemoryStoreEngine storeEngine : slotsStore.values()) { + result.addAll(storeEngine.getAll()); + } + return result; + } + + @Override + public Map> filter(String group, int limit) { + Map> result = new HashMap<>(); + for (SimpleMemoryStoreEngine storeEngine : slotsStore.values()) { + result.putAll(storeEngine.filter(group, limit)); + } + return result; + } + + @Override + public Collection getNonEmptyDataInfoId() { + Set result = new HashSet<>(); + for (SimpleMemoryStoreEngine storeEngine : slotsStore.values()) { + result.addAll(storeEngine.getNonEmptyDataInfoId()); + } + return result; + } + + @Override + public StoreStat stat() { + long dataInfoIdCount = 0; + long dataCount = 0; + for (SimpleMemoryStoreEngine store : slotsStore.values()) { + StoreStat storeStat = store.stat(); + dataInfoIdCount += storeStat.nonEmptyDataIdSize(); + dataCount += storeStat.size(); + } + return new StoreStat(dataInfoIdCount, dataCount); + } + + @Override + public Collection getSlotStoreData(int slotId) { + SimpleMemoryStoreEngine simpleMemoryStoreEngine = slotsStore.get(slotId); + if (simpleMemoryStoreEngine == null) { + return Collections.emptyList(); + } + return simpleMemoryStoreEngine.getAll(); + } + + public interface SlotCaller { + int slotOf(String dataInfoId); + } +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SlotStoreEngine.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SlotStoreEngine.java new file mode 100644 index 000000000..439ce1a82 --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SlotStoreEngine.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store.engine; + +import com.alipay.sofa.registry.common.model.store.StoreData; +import java.util.Collection; + +/** A storage engine that supports aggregation by a specific key. */ +public interface SlotStoreEngine> extends StoreEngine { + + /** + * All StoreData belonging to the same slot. + * + * @param slotId slot id + * @return StoreData belonging to the same slot + */ + Collection getSlotStoreData(int slotId); +} diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/StoreEngine.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/StoreEngine.java new file mode 100644 index 000000000..b77dd1c2f --- /dev/null +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/StoreEngine.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store.engine; + +import com.alipay.sofa.registry.common.model.store.StoreData; +import java.util.Collection; +import java.util.Map; +import javafx.util.Pair; + +/** Engine for storing StoreData. */ +public interface StoreEngine> { + + /** + * If the specified key is + * + *

1. not already associated with a value + * + *

2. or is mapped to null + * + *

3. or the version of the associated value is less than the target version + * + *

, associates it with the given value and returns previous value. + * + * @param storeData new value + * @return whether the put operation is successful and the previous value + */ + Pair putIfAbsent(T storeData); + + /** + * Returns the value to which the specified key is mapped, or null if this map contains no mapping + * for the key. + * + * @param dataInfoId dataInfoId of StoreData + * @param registerId register of StoreData + * @return the value to which the specified key is mapped, or null if this map contains no mapping + * for the key + */ + T get(String dataInfoId, String registerId); + + /** + * Removes the mapping for a key from this map if it is present (optional operation). + * + * @param dataInfoId dataInfoId of StoreData + * @param registerId register of StoreData + * @return the previous value associated with key, or null if there was no mapping for key. + */ + T delete(String dataInfoId, String registerId); + + /** + * Delete target data. + * + * @param storeData target data + * @return true if the target data was successfully deleted + */ + boolean delete(T storeData); + + /** + * Get all StoreData associated with target dataInfoId. + * + * @param dataInfoId dataInfoId of StoreData + * @return all StoreData associated with target dataInfoId. + */ + Collection get(String dataInfoId); + + /** + * Get all StoreData in this store. + * + * @return all StoreData in this store. + */ + Collection getAll(); + + /** + * Filter target data with limit. + * + * @param group DataInfo group + * @param limit limit + * @return data collections + */ + Map> filter(String group, int limit); + + /** + * Get collection of dataInfoId which has non-empty StoreData collection. + * + * @return collection of dataInfoId which has non-empty StoreData collection. + */ + Collection getNonEmptyDataInfoId(); + + /** + * Get the stat of this store. + * + * @return the stat of this store. + */ + StoreStat stat(); + + class StoreStat { + + private final long nonEmptyDataIdSize; + private final long size; + + public StoreStat(long nonEmptyDataIdSize, long size) { + this.nonEmptyDataIdSize = nonEmptyDataIdSize; + this.size = size; + } + + public long nonEmptyDataIdSize() { + return nonEmptyDataIdSize; + } + + public long size() { + return size; + } + } +} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManagerTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManagerTest.java index 65348acdc..a43caba57 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManagerTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/interceptor/OrderedInterceptorManagerTest.java @@ -16,6 +16,8 @@ */ package com.alipay.sofa.registry.server.session.interceptor; +import com.alipay.sofa.registry.common.model.ConnectId; +import com.alipay.sofa.registry.common.model.RegisterVersion; import com.alipay.sofa.registry.common.model.store.StoreData; import com.alipay.sofa.registry.exception.InterceptorExecutionException; import java.util.ArrayList; @@ -43,6 +45,26 @@ public DataType getDataType() { public Object getId() { return "dataId"; } + + @Override + public String getDataInfoId() { + return null; + } + + @Override + public RegisterVersion registerVersion() { + return null; + } + + @Override + public long getRegisterTimestamp() { + return 0; + } + + @Override + public ConnectId connectId() { + return null; + } }, null); } diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/push/FirePushServiceTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/push/FirePushServiceTest.java index 5ffe499c0..e3439bf6e 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/push/FirePushServiceTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/push/FirePushServiceTest.java @@ -30,7 +30,7 @@ import com.alipay.sofa.registry.server.session.circuit.breaker.CircuitBreakerService; import com.alipay.sofa.registry.server.session.providedata.FetchGrayPushSwitchService; import com.alipay.sofa.registry.server.session.providedata.FetchStopPushService; -import com.alipay.sofa.registry.server.session.store.Interests; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; import com.alipay.sofa.registry.task.FastRejectedExecutionException; import com.google.common.collect.Lists; import java.util.Collections; @@ -51,7 +51,7 @@ public void testFire() { svc.sessionServerConfig = config; FetchStopPushService fetchStopPushService = new FetchStopPushService(); svc.pushSwitchService = new PushSwitchService(); - svc.sessionInterests = Mockito.mock(Interests.class); + svc.subscriberStore = Mockito.mock(SubscriberStore.class); svc.pushProcessor = Mockito.mock(PushProcessor.class); svc.pushSwitchService.setFetchStopPushService(fetchStopPushService); svc.pushSwitchService.setFetchGrayPushSwitchService(new FetchGrayPushSwitchService()); @@ -100,7 +100,7 @@ public void testPushEmpty() { SessionServerConfigBean config = TestUtils.newSessionConfig("testDc"); svc.sessionServerConfig = config; svc.pushSwitchService = Mockito.mock(PushSwitchService.class); - svc.sessionInterests = Mockito.mock(Interests.class); + svc.subscriberStore = Mockito.mock(SubscriberStore.class); svc.circuitBreakerService = Mockito.mock(CircuitBreakerService.class); svc.changeProcessor = Mockito.mock(ChangeProcessor.class); svc.pushProcessor = Mockito.mock(PushProcessor.class); @@ -126,7 +126,7 @@ private FirePushService mockFirePushService() { FirePushService svc = new FirePushService(); SessionServerConfigBean config = TestUtils.newSessionConfig("testDc"); svc.sessionServerConfig = config; - svc.sessionInterests = Mockito.mock(Interests.class); + svc.subscriberStore = Mockito.mock(SubscriberStore.class); svc.pushProcessor = Mockito.mock(PushProcessor.class); svc.sessionCacheService = Mockito.mock(CacheService.class); svc.pushSwitchService = Mockito.mock(PushSwitchService.class); @@ -148,7 +148,7 @@ public void testExecuteOnChange() { Subscriber subscriber = TestUtils.newZoneSubscriber(dataId, zone); Value v = new Value((Sizer) datum); when(svc.sessionCacheService.getValueIfPresent(Mockito.anyObject())).thenReturn(v); - when(svc.sessionInterests.getDatas(Mockito.anyObject())) + when(svc.subscriberStore.getByDataInfoId(Mockito.anyObject())) .thenReturn(Collections.singletonList(subscriber)); svc.pushSwitchService = new PushSwitchService(); svc.pushSwitchService.setFetchStopPushService(new FetchStopPushService()); diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/console/handler/FilterSubscriberIPsHandlerTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/console/handler/FilterSubscriberIPsHandlerTest.java index c43ba730e..7c7087517 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/console/handler/FilterSubscriberIPsHandlerTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/console/handler/FilterSubscriberIPsHandlerTest.java @@ -20,7 +20,7 @@ import com.alipay.sofa.registry.common.model.CommonResponse; import com.alipay.sofa.registry.common.model.sessionserver.FilterSubscriberIPsRequest; -import com.alipay.sofa.registry.server.session.store.Interests; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; import org.junit.Assert; import org.junit.Test; @@ -34,7 +34,7 @@ private FilterSubscriberIPsHandler newHandler() { @Test public void testHandle() { FilterSubscriberIPsHandler handler = newHandler(); - handler.sessionInterests = mock(Interests.class); + handler.subscriberStore = mock(SubscriberStore.class); CommonResponse obj = (CommonResponse) handler.doHandle(null, new FilterSubscriberIPsRequest("DEFAULT_GROUP", 1)); Assert.assertTrue(obj.isSuccess()); diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/console/handler/QuerySubscriberRequestHandlerTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/console/handler/QuerySubscriberRequestHandlerTest.java index 5f2957fcf..284e01c08 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/console/handler/QuerySubscriberRequestHandlerTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/console/handler/QuerySubscriberRequestHandlerTest.java @@ -25,7 +25,7 @@ import com.alipay.sofa.registry.server.session.TestUtils; import com.alipay.sofa.registry.server.session.bootstrap.ExecutorManager; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfigBean; -import com.alipay.sofa.registry.server.session.store.Interests; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; import org.junit.Assert; import org.junit.Test; @@ -47,7 +47,7 @@ private QuerySubscriberRequestHandler newHandler() { @Test public void testHandle() { QuerySubscriberRequestHandler handler = newHandler(); - handler.sessionInterests = mock(Interests.class); + handler.subscriberStore = mock(SubscriberStore.class); CommonResponse obj = (CommonResponse) handler.doHandle(null, request()); Assert.assertTrue(obj.isSuccess()); diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataChangeRequestHandlerTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataChangeRequestHandlerTest.java index 4e03833a0..a6a479b60 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataChangeRequestHandlerTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataChangeRequestHandlerTest.java @@ -30,7 +30,7 @@ import com.alipay.sofa.registry.server.session.providedata.FetchStopPushService; import com.alipay.sofa.registry.server.session.push.FirePushService; import com.alipay.sofa.registry.server.session.push.PushSwitchService; -import com.alipay.sofa.registry.server.session.store.Interests; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; import java.util.HashMap; import java.util.Map; import org.junit.Assert; @@ -63,7 +63,7 @@ public void testHandle() { handler.pushSwitchService = new PushSwitchService(); handler.executorManager = new ExecutorManager(serverConfigBean); handler.firePushService = mock(FirePushService.class); - handler.sessionInterests = mock(Interests.class); + handler.subscriberStore = mock(SubscriberStore.class); handler.pushSwitchService.setFetchStopPushService(new FetchStopPushService()); handler.pushSwitchService.setFetchGrayPushSwitchService(new FetchGrayPushSwitchService()); @@ -73,14 +73,14 @@ public void testHandle() { Assert.assertNull(obj); handler.pushSwitchService.getFetchStopPushService().setStopPushSwitch(init, false); - when(handler.sessionInterests.checkInterestVersion(anyString(), anyString(), anyLong())) - .thenReturn(Interests.InterestVersionCheck.Obsolete); + when(handler.subscriberStore.checkInterestVersion(anyString(), anyString(), anyLong())) + .thenReturn(SubscriberStore.InterestVersionCheck.Obsolete); obj = handler.doHandle(null, request()); Assert.assertNull(obj); verify(handler.firePushService, times(0)).fireOnChange(anyString(), anyObject()); - when(handler.sessionInterests.checkInterestVersion(anyString(), anyString(), anyLong())) - .thenReturn(Interests.InterestVersionCheck.Interested); + when(handler.subscriberStore.checkInterestVersion(anyString(), anyString(), anyLong())) + .thenReturn(SubscriberStore.InterestVersionCheck.Interested); obj = handler.doHandle(null, request()); Assert.assertNull(obj); verify(handler.firePushService, times(2)).fireOnChange(anyString(), anyObject()); diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffDigestRequestHandlerTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffDigestRequestHandlerTest.java index def7ab497..1847bcb00 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffDigestRequestHandlerTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffDigestRequestHandlerTest.java @@ -29,7 +29,7 @@ import com.alipay.sofa.registry.server.session.TestUtils; import com.alipay.sofa.registry.server.session.bootstrap.ExecutorManager; import com.alipay.sofa.registry.server.session.slot.SlotTableCache; -import com.alipay.sofa.registry.server.session.store.DataStore; +import com.alipay.sofa.registry.server.session.store.PublisherStore; import java.util.Collections; import java.util.Map; import org.junit.Assert; @@ -69,9 +69,8 @@ public void testHandle() { Assert.assertFalse(resp.isSuccess()); Assert.assertNull(resp.getData()); - handler.sessionDataStore = mock(DataStore.class); - when(handler.sessionDataStore.getDataInfoIdPublishers(anyInt())) - .thenReturn(Collections.emptyMap()); + handler.publisherStore = mock(PublisherStore.class); + when(handler.publisherStore.getBySlotId(anyInt())).thenReturn(Collections.emptyList()); resp = (GenericResponse) handler.doHandle(channel, request); Assert.assertTrue(resp.isSuccess()); Assert.assertNotNull(resp.getData()); diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffPublisherRequestHandlerTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffPublisherRequestHandlerTest.java index 0fe5bd4fa..1fb5f88b5 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffPublisherRequestHandlerTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/DataSlotDiffPublisherRequestHandlerTest.java @@ -29,7 +29,7 @@ import com.alipay.sofa.registry.server.session.TestUtils; import com.alipay.sofa.registry.server.session.bootstrap.ExecutorManager; import com.alipay.sofa.registry.server.session.slot.SlotTableCache; -import com.alipay.sofa.registry.server.session.store.DataStore; +import com.alipay.sofa.registry.server.session.store.PublisherStore; import java.util.Collections; import java.util.List; import org.junit.Assert; @@ -71,9 +71,8 @@ public void testHandle() { Assert.assertFalse(resp.isSuccess()); Assert.assertNull(resp.getData()); - handler.sessionDataStore = mock(DataStore.class); - when(handler.sessionDataStore.getDataInfoIdPublishers(anyInt())) - .thenReturn(Collections.emptyMap()); + handler.publisherStore = mock(PublisherStore.class); + when(handler.publisherStore.getBySlotId(anyInt())).thenReturn(Collections.emptyList()); resp = (GenericResponse) handler.doHandle(channel, request); Assert.assertTrue(resp.isSuccess()); Assert.assertNotNull(resp.getData()); diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/scheduler/timertask/CacheTaskTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/scheduler/timertask/CacheTaskTest.java index 7e3a467fc..73f5721e9 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/scheduler/timertask/CacheTaskTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/scheduler/timertask/CacheTaskTest.java @@ -16,7 +16,6 @@ */ package com.alipay.sofa.registry.server.session.scheduler.timertask; -import com.alipay.sofa.registry.common.model.Tuple; import com.alipay.sofa.registry.common.model.store.Publisher; import com.alipay.sofa.registry.common.model.store.Subscriber; import com.alipay.sofa.registry.common.model.store.Watcher; @@ -24,56 +23,60 @@ import com.alipay.sofa.registry.server.session.TestUtils; import com.alipay.sofa.registry.server.session.bootstrap.ExecutorManager; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfigBean; -import com.alipay.sofa.registry.server.session.store.DataStore; -import com.alipay.sofa.registry.server.session.store.Interests; -import com.alipay.sofa.registry.server.session.store.Watchers; +import com.alipay.sofa.registry.server.session.store.PublisherStore; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; +import com.alipay.sofa.registry.server.session.store.WatcherStore; +import com.alipay.sofa.registry.server.session.store.engine.StoreEngine; import com.google.common.collect.Lists; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; public class CacheTaskTest { - private String app = "app"; - private String group = "group"; - private String instanceId = "instanceId"; - private String dataInfoId = "dataInfoId"; - private Watchers watchers; - private Interests interests; - private DataStore dataStore; + private WatcherStore watcherStore; + private SubscriberStore subscriberStore; + private PublisherStore publisherStore; private void init() { - this.watchers = Mockito.mock(Watchers.class); + final String app = "app"; + final String group = "group"; + final String instanceId = "instanceId"; + final String dataInfoId = "dataInfoId"; + + this.watcherStore = Mockito.mock(WatcherStore.class); Watcher watcher = new Watcher(); watcher.setAppName(app); watcher.setGroup(group); watcher.setInstanceId(instanceId); watcher.setDataInfoId(dataInfoId); - Mockito.when(watchers.count()).thenReturn(Tuple.of(1L, 1L)); - Mockito.when(watchers.getDataList()).thenReturn(Lists.newArrayList(watcher)); + Mockito.when(watcherStore.stat()).thenReturn(new StoreEngine.StoreStat(1, 1)); + Mockito.when(watcherStore.getAll()).thenReturn(Lists.newArrayList(watcher)); - this.interests = Mockito.mock(Interests.class); + this.subscriberStore = Mockito.mock(SubscriberStore.class); Subscriber subscriber = new Subscriber(); subscriber.setAppName(app); subscriber.setGroup(group); subscriber.setInstanceId(instanceId); subscriber.setDataInfoId(dataInfoId); - Mockito.when(interests.count()).thenReturn(Tuple.of(1L, 2L)); - Mockito.when(interests.getDataList()).thenReturn(Lists.newArrayList(subscriber)); - Mockito.when(interests.getDataInfoIds()).thenReturn(Lists.newArrayList(dataInfoId)); - Mockito.when(interests.getDatas(Mockito.anyString())) + Mockito.when(subscriberStore.stat()).thenReturn(new StoreEngine.StoreStat(1, 2)); + Mockito.when(subscriberStore.getAll()).thenReturn(Lists.newArrayList(subscriber)); + Mockito.when(subscriberStore.getNonEmptyDataInfoId()) + .thenReturn(Lists.newArrayList(dataInfoId)); + Mockito.when(subscriberStore.getByDataInfoId(Mockito.anyString())) .thenReturn(Lists.newArrayList(subscriber)); - this.dataStore = Mockito.mock(DataStore.class); + this.publisherStore = Mockito.mock(PublisherStore.class); Publisher publisher = new Publisher(); publisher.setAppName(app); publisher.setGroup(group); publisher.setInstanceId(instanceId); publisher.setDataInfoId(dataInfoId); - Mockito.when(dataStore.count()).thenReturn(Tuple.of(1L, 3L)); - Mockito.when(dataStore.getDataList()).thenReturn(Lists.newArrayList(publisher)); - Mockito.when(dataStore.getDataInfoIds()).thenReturn(Lists.newArrayList(dataInfoId)); - Mockito.when(dataStore.getDatas(Mockito.anyString())).thenReturn(Lists.newArrayList(publisher)); + Mockito.when(publisherStore.stat()).thenReturn(new StoreEngine.StoreStat(1L, 3L)); + Mockito.when(publisherStore.getAll()).thenReturn(Lists.newArrayList(publisher)); + Mockito.when(publisherStore.getNonEmptyDataInfoId()).thenReturn(Lists.newArrayList(dataInfoId)); + Mockito.when(publisherStore.getByDataInfoId(Mockito.anyString())) + .thenReturn(Lists.newArrayList(publisher)); } @Test @@ -85,9 +88,9 @@ public void testCount() { // npe Assert.assertFalse(task.syncCount()); - task.sessionWatchers = watchers; - task.sessionDataStore = dataStore; - task.sessionInterests = interests; + task.watcherStore = watcherStore; + task.publisherStore = publisherStore; + task.subscriberStore = subscriberStore; serverConfigBean.setCacheCountIntervalSecs(0); Assert.assertFalse(task.init()); @@ -106,8 +109,8 @@ public void testDigest() { // npe Assert.assertFalse(task.dump()); - task.sessionDataStore = dataStore; - task.sessionInterests = interests; + task.publisherStore = publisherStore; + task.subscriberStore = subscriberStore; serverConfigBean.setCacheDigestIntervalMinutes(0); Assert.assertFalse(task.init()); @@ -123,12 +126,11 @@ public void testClient() { SyncClientsHeartbeatTask task = new SyncClientsHeartbeatTask(); SessionServerConfigBean serverConfigBean = TestUtils.newSessionConfig("testDc"); task.sessionServerConfig = serverConfigBean; - task.sessionDataStore = dataStore; - task.sessionInterests = interests; - task.sessionWatchers = watchers; + task.publisherStore = publisherStore; + task.subscriberStore = subscriberStore; + task.watcherStore = watcherStore; - BoltExchange boltExchange = Mockito.mock(BoltExchange.class); - task.boltExchange = boltExchange; + task.boltExchange = Mockito.mock(BoltExchange.class); task.executorManager = new ExecutorManager(serverConfigBean); task.syncCount(); } diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/DataCacheTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/DataCacheTest.java index 3b2cff377..950e704b1 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/DataCacheTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/DataCacheTest.java @@ -26,7 +26,6 @@ import com.alipay.sofa.registry.core.model.ScopeEnum; import com.alipay.sofa.registry.net.NetUtil; import com.alipay.sofa.registry.server.session.bootstrap.CommonConfig; -import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfigBean; import com.alipay.sofa.registry.server.session.providedata.FetchStopPushService; import com.alipay.sofa.registry.server.session.slot.SlotTableCache; @@ -53,30 +52,29 @@ public class DataCacheTest extends BaseTest { @Test public void testGetSub() { - SessionInterests sessionInterests = new SessionInterests(); - sessionInterests.setSessionServerConfig(new SessionServerConfigBean(null)); + SubscriberStore subscriberStore = new SubscriberStoreImpl(new SessionServerConfigBean(null)); String dataId = "dataid"; String connectId = "192.168.1.2:9000_127.0.0.1:34567"; for (int i = 0; i < 100; i++) { - sessionInterests.add(getSub(dataId, ScopeEnum.zone, null, null)); + subscriberStore.add(getSub(dataId, ScopeEnum.zone, null, null)); } // add other ip - sessionInterests.add(getSub(dataId, ScopeEnum.zone, null, new URL("192.168.1.9", 8000))); + subscriberStore.add(getSub(dataId, ScopeEnum.zone, null, new URL("192.168.1.9", 8000))); Map> map = getCacheSub( - DataInfo.toDataInfoId(dataId, "instance2", "rpc"), ScopeEnum.zone, sessionInterests); - Assert.assertTrue(getCacheSub(sessionInterests, connectId)); + DataInfo.toDataInfoId(dataId, "instance2", "rpc"), ScopeEnum.zone, subscriberStore); + Assert.assertTrue(getCacheSub(subscriberStore, connectId)); - sessionInterests.deleteByConnectId(ConnectId.parse(connectId)); + subscriberStore.delete(ConnectId.parse(connectId)); Map> map2 = getCacheSub( - DataInfo.toDataInfoId(dataId, "instance2", "rpc"), ScopeEnum.zone, sessionInterests); + DataInfo.toDataInfoId(dataId, "instance2", "rpc"), ScopeEnum.zone, subscriberStore); - Assert.assertFalse(getCacheSub(sessionInterests, connectId)); + Assert.assertFalse(getCacheSub(subscriberStore, connectId)); // map no change Assert.assertEquals(2, map.size()); @@ -89,8 +87,7 @@ public void testGetSub() { @Test public void testDeleteSubById() { - SessionInterests sessionInterests = new SessionInterests(); - sessionInterests.setSessionServerConfig(new SessionServerConfigBean(null)); + SubscriberStore sessionInterests = new SubscriberStoreImpl(new SessionServerConfigBean(null)); String dataId = "dataid"; @@ -109,7 +106,7 @@ public void testDeleteSubById() { DataInfo.toDataInfoId(dataId, "instance2", "rpc"), ScopeEnum.zone, sessionInterests); Assert.assertTrue(getCacheSub(sessionInterests, "192.168.1.9:8000_127.0.0.1:34567")); - sessionInterests.deleteById("xxregist123", DataInfo.toDataInfoId(dataId, "instance2", "rpc")); + sessionInterests.delete(DataInfo.toDataInfoId(dataId, "instance2", "rpc"), "xxregist123"); Map> map2 = getCacheSub( @@ -134,27 +131,26 @@ public void testDeleteSubById() { @Test public void testGetPub() { - SessionDataStore sessionDataStore = new SessionDataStore(); - sessionDataStore.slotTableCache = mock(SlotTableCache.class); - doReturn(0).when(sessionDataStore.slotTableCache).slotOf(anyString()); + SlotTableCache slotTableCache = mock(SlotTableCache.class); + PublisherStore publisherStore = new PublisherStoreImpl(slotTableCache); + doReturn(0).when(slotTableCache).slotOf(anyString()); String dataId = "dataid"; String connectId = "192.168.1.2:9000_127.0.0.1:34567"; for (int i = 0; i < 10; i++) { - - sessionDataStore.add(getPub(dataId, null, null)); + publisherStore.add(getPub(dataId, null, null)); } - Assert.assertTrue(getCachePub(sessionDataStore, connectId)); - sessionDataStore.deleteByConnectId(ConnectId.parse(connectId)); - Assert.assertFalse(getCachePub(sessionDataStore, connectId)); + Assert.assertTrue(getCachePub(publisherStore, connectId)); + publisherStore.delete(ConnectId.parse(connectId)); + Assert.assertFalse(getCachePub(publisherStore, connectId)); } @Test public void testGetPubRefresh() { - SessionDataStore sessionDataStore = new SessionDataStore(); - sessionDataStore.slotTableCache = mock(SlotTableCache.class); - doReturn(0).when(sessionDataStore.slotTableCache).slotOf(anyString()); + SlotTableCache slotTableCache = mock(SlotTableCache.class); + PublisherStore publisherStore = new PublisherStoreImpl(slotTableCache); + doReturn(0).when(slotTableCache).slotOf(anyString()); String dataId = "dataid"; String connectId = "192.168.1.2:9000"; @@ -163,11 +159,11 @@ public void testGetPubRefresh() { for (int i = 0; i < number; i++) { String connectIdss = "192.111.0.1:" + (8000 + i); Publisher p = getPub(dataId, null, URL.valueOf(connectIdss)); - sessionDataStore.add(p); + publisherStore.add(p); publisherList.add(p); Assert.assertTrue( getCachePub( - sessionDataStore, + publisherStore, connectIdss + ValueConstants.CONNECT_ID_SPLIT + p.getTargetAddress().buildAddressString())); @@ -175,44 +171,42 @@ public void testGetPubRefresh() { for (Publisher p : publisherList) { String c = connectId + ValueConstants.CONNECT_ID_SPLIT + p.getTargetAddress().buildAddressString(); - Assert.assertFalse(getCachePub(sessionDataStore, c)); + Assert.assertFalse(getCachePub(publisherStore, c)); } } @Test public void testDelPubById() { - SessionDataStore sessionDataStore = new SessionDataStore(); - sessionDataStore.slotTableCache = mock(SlotTableCache.class); - doReturn(0).when(sessionDataStore.slotTableCache).slotOf(anyString()); + SlotTableCache slotTableCache = mock(SlotTableCache.class); + PublisherStore publisherStore = new PublisherStoreImpl(slotTableCache); + doReturn(0).when(slotTableCache).slotOf(anyString()); String dataId = "dataid"; String connectId = "192.168.1.2:9000_127.0.0.1:34567"; for (int i = 0; i < 10; i++) { - - sessionDataStore.add(getPub(dataId, null, null)); + publisherStore.add(getPub(dataId, null, null)); } + publisherStore.add(getPub(dataId, "XXXX", new URL("192.168.1.9", 8000))); - sessionDataStore.add(getPub(dataId, "XXXX", new URL("192.168.1.9", 8000))); - - Assert.assertTrue(getCachePub(sessionDataStore, connectId)); - Assert.assertTrue(getCachePub(sessionDataStore, "192.168.1.9:8000_127.0.0.1:34567")); - sessionDataStore.deleteById("XXXX", DataInfo.toDataInfoId(dataId, "instance2", "rpc")); - Assert.assertTrue(getCachePub(sessionDataStore, connectId)); - Assert.assertFalse(getCachePub(sessionDataStore, "192.168.1.9:8000_127.0.0.1:34567")); + Assert.assertTrue(getCachePub(publisherStore, connectId)); + Assert.assertTrue(getCachePub(publisherStore, "192.168.1.9:8000_127.0.0.1:34567")); + publisherStore.delete(DataInfo.toDataInfoId(dataId, "instance2", "rpc"), "XXXX"); + Assert.assertTrue(getCachePub(publisherStore, connectId)); + Assert.assertFalse(getCachePub(publisherStore, "192.168.1.9:8000_127.0.0.1:34567")); } - private boolean getCachePub(SessionDataStore sessionDataStore, String connectId) { - Map map = sessionDataStore.queryByConnectId(ConnectId.parse(connectId)); - return map != null && !map.isEmpty(); + private boolean getCachePub(PublisherStore publisherStore, String connectId) { + Collection publishers = publisherStore.getByConnectId(ConnectId.parse(connectId)); + return publishers != null && !publishers.isEmpty(); } - private boolean getCacheSub(SessionInterests sessionInterests, String connectId) { - Map map = sessionInterests.queryByConnectId(ConnectId.parse(connectId)); - return map != null && !map.isEmpty(); + private boolean getCacheSub(SubscriberStore subscriberStore, String connectId) { + Collection subscribers = subscriberStore.getByConnectId(ConnectId.parse(connectId)); + return subscribers != null && !subscribers.isEmpty(); } private Map> getCacheSub( - String dataInfoId, ScopeEnum scopeEnum, SessionInterests sessionInterests) { - Collection subscribers = sessionInterests.getDatas(dataInfoId); + String dataInfoId, ScopeEnum scopeEnum, SubscriberStore subscriberStore) { + Collection subscribers = subscriberStore.getByDataInfoId(dataInfoId); Map> ret = Maps.newHashMap(); Map> scopes = SubscriberUtils.groupByScope(subscribers); List list = scopes.get(scopeEnum); @@ -272,10 +266,9 @@ private Publisher getPub(String dataId, String registerId, URL url) { @Test public void testOverwriteSameConnectIdPublisher() { - - SessionDataStore sessionDataStore = new SessionDataStore(); - sessionDataStore.slotTableCache = mock(SlotTableCache.class); - doReturn(0).when(sessionDataStore.slotTableCache).slotOf(anyString()); + SlotTableCache slotTableCache = mock(SlotTableCache.class); + PublisherStore publisherStore = new PublisherStoreImpl(slotTableCache); + doReturn(0).when(slotTableCache).slotOf(anyString()); Publisher publisher1 = new Publisher(); publisher1.setDataInfoId("dataInfoId1"); @@ -294,20 +287,16 @@ public void testOverwriteSameConnectIdPublisher() { publisher2.setTargetAddress(new URL("192.168.1.2", 9600)); publisher2.setVersion(2L); publisher2.setRegisterTimestamp(System.currentTimeMillis()); - Assert.assertTrue(sessionDataStore.add(publisher1)); - Assert.assertTrue(sessionDataStore.add(publisher2)); + Assert.assertTrue(publisherStore.add(publisher1)); + Assert.assertTrue(publisherStore.add(publisher2)); Assert.assertEquals( - sessionDataStore - .queryByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) - .size(), + publisherStore.getByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")).size(), 2); - Assert.assertFalse(sessionDataStore.add(publisher2)); + Assert.assertFalse(publisherStore.add(publisher2)); Assert.assertEquals( - sessionDataStore - .queryByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) - .size(), + publisherStore.getByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")).size(), 2); Publisher publisher3 = new Publisher(); @@ -328,18 +317,14 @@ public void testOverwriteSameConnectIdPublisher() { publisher4.setVersion(2L); publisher4.setRegisterTimestamp(System.currentTimeMillis() + 1000); - Assert.assertTrue(sessionDataStore.add(publisher3)); - Assert.assertTrue(sessionDataStore.add(publisher4)); + Assert.assertTrue(publisherStore.add(publisher3)); + Assert.assertTrue(publisherStore.add(publisher4)); Assert.assertEquals( - sessionDataStore - .queryByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) - .size(), + publisherStore.getByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")).size(), 0); Assert.assertEquals( - sessionDataStore - .queryByConnectId(ConnectId.parse("192.168.1.1:12346_192.168.1.2:9600")) - .size(), + publisherStore.getByConnectId(ConnectId.parse("192.168.1.1:12346_192.168.1.2:9600")).size(), 2); } @@ -349,9 +334,8 @@ public void testOverwriteSameConnectIdSubscriber() { FetchStopPushService fetchStopPushService = mock(FetchStopPushService.class); when(fetchStopPushService.isStopPushSwitch()).thenReturn(false); - SessionInterests sessionInterests = new SessionInterests(); - SessionServerConfig config = new SessionServerConfigBean(new CommonConfig()); - sessionInterests.setSessionServerConfig(config); + SubscriberStore sessionInterests = + new SubscriberStoreImpl(new SessionServerConfigBean(new CommonConfig())); Subscriber subscriber1 = createSubscriber(); subscriber1.setScope(ScopeEnum.dataCenter); @@ -376,14 +360,14 @@ public void testOverwriteSameConnectIdSubscriber() { Assert.assertEquals( sessionInterests - .queryByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) + .getByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) .size(), 2); sessionInterests.add(subscriber2); Assert.assertEquals( sessionInterests - .queryByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) + .getByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) .size(), 2); @@ -412,87 +396,19 @@ public void testOverwriteSameConnectIdSubscriber() { Assert.assertEquals( sessionInterests - .queryByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) + .getByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) .size(), 0); Assert.assertEquals( sessionInterests - .queryByConnectId(ConnectId.parse("192.168.1.1:12346_192.168.1.2:9600")) - .size(), - 2); - } - - @Test - public void testOverwriteSameConnectIdWatcher() { - - SessionWatchers sessionWatchers = new SessionWatchers(); - - Watcher watcher1 = createWatcher(); - watcher1.setDataInfoId("dataInfoId1"); - watcher1.setDataId("dataId1"); - watcher1.setRegisterId("RegisterId1"); - watcher1.setSourceAddress(new URL("192.168.1.1", 12345)); - watcher1.setTargetAddress(new URL("192.168.1.2", 9600)); - - Watcher watcher2 = createWatcher(); - watcher2.setDataInfoId("dataInfoId2"); - watcher2.setDataId("dataId2"); - watcher2.setRegisterId("RegisterId2"); - watcher2.setSourceAddress(new URL("192.168.1.1", 12345)); - watcher2.setTargetAddress(new URL("192.168.1.2", 9600)); - - Assert.assertTrue(sessionWatchers.add(watcher1)); - Assert.assertTrue(sessionWatchers.add(watcher2)); - - Assert.assertEquals( - sessionWatchers - .queryByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) - .size(), - 2); - sessionWatchers.add(watcher2); - - Assert.assertEquals( - sessionWatchers - .queryByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) - .size(), - 2); - - Watcher watcher3 = createWatcher(); - watcher3.setDataInfoId(watcher1.getDataInfoId()); - watcher3.setDataId(watcher1.getDataId()); - watcher3.setVersion(1); - watcher3.setRegisterId(watcher1.getRegisterId()); - watcher3.setSourceAddress(new URL("192.168.1.1", 12346)); - watcher3.setTargetAddress(new URL("192.168.1.2", 9600)); - - Watcher watcher4 = createWatcher(); - watcher4.setDataInfoId(watcher2.getDataInfoId()); - watcher4.setVersion(1); - watcher4.setDataId(watcher2.getDataId()); - watcher4.setRegisterId(watcher2.getRegisterId()); - watcher4.setSourceAddress(new URL("192.168.1.1", 12346)); - watcher4.setTargetAddress(new URL("192.168.1.2", 9600)); - - Assert.assertTrue(sessionWatchers.add(watcher3)); - Assert.assertTrue(sessionWatchers.add(watcher4)); - - Assert.assertEquals( - sessionWatchers - .queryByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) - .size(), - 0); - Assert.assertEquals( - sessionWatchers - .queryByConnectId(ConnectId.parse("192.168.1.1:12346_192.168.1.2:9600")) + .getByConnectId(ConnectId.parse("192.168.1.1:12346_192.168.1.2:9600")) .size(), 2); } @Test public void testSubAndClientOffUnorder() { - SessionInterests sessionInterests = new SessionInterests(); - SessionServerConfig config = new SessionServerConfigBean(null); - sessionInterests.setSessionServerConfig(config); + SubscriberStore sessionInterests = new SubscriberStoreImpl(new SessionServerConfigBean(null)); Subscriber subscriber1 = createSubscriber(); subscriber1.setScope(ScopeEnum.dataCenter); @@ -516,7 +432,7 @@ public void testSubAndClientOffUnorder() { Assert.assertTrue(sessionInterests.add(subscriber2)); - sessionInterests.deleteByConnectId( + sessionInterests.delete( ConnectId.parse( subscriber1.getSourceAddress().buildAddressString() + "_" @@ -524,12 +440,12 @@ public void testSubAndClientOffUnorder() { Assert.assertEquals( sessionInterests - .queryByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) + .getByConnectId(ConnectId.parse("192.168.1.1:12345_192.168.1.2:9600")) .isEmpty(), true); Assert.assertEquals( sessionInterests - .queryByConnectId(ConnectId.parse("192.168.1.1:12346_192.168.1.2:9600")) + .getByConnectId(ConnectId.parse("192.168.1.1:12346_192.168.1.2:9600")) .size(), 1); @@ -537,8 +453,9 @@ public void testSubAndClientOffUnorder() { getCacheSub(subscriber1.getDataInfoId(), subscriber1.getScope(), sessionInterests); Assert.assertEquals(addressMap.get(new InetSocketAddress("192.168.1.1", 12345)), null); Assert.assertEquals(addressMap.get(new InetSocketAddress("192.168.1.1", 12346)).size(), 1); - Assert.assertEquals(sessionInterests.getDatas(subscriber1.getDataInfoId()).size(), 1); - Assert.assertTrue(sessionInterests.getDatas(subscriber1.getDataInfoId()).contains(subscriber2)); + Assert.assertEquals(sessionInterests.getByDataInfoId(subscriber1.getDataInfoId()).size(), 1); + Assert.assertTrue( + sessionInterests.getByDataInfoId(subscriber1.getDataInfoId()).contains(subscriber2)); } private Subscriber createSubscriber() { diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/PublisherStoreTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/PublisherStoreTest.java new file mode 100644 index 000000000..a7c2fb1ea --- /dev/null +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/PublisherStoreTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; + +import com.alipay.sofa.registry.common.model.store.Publisher; +import com.alipay.sofa.registry.common.model.store.URL; +import com.alipay.sofa.registry.server.session.slot.SlotTableCache; +import java.util.Collection; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +/** */ +public class PublisherStoreTest { + + @Test + public void test() { + String dataInfoId = "dataInfoId"; + String registerId = "registerId"; + + String dataInfoId00 = "dataInfoId00"; + String registerId00 = "registerId00"; + + SlotTableCache slotTableCache = Mockito.mock(SlotTableCache.class); + Mockito.when(slotTableCache.slotOf(dataInfoId)).thenReturn(0); + Mockito.when(slotTableCache.slotOf(dataInfoId00)).thenReturn(1); + PublisherStoreImpl publisherStore = new PublisherStoreImpl(slotTableCache); + + long time = System.currentTimeMillis(); + Publisher publisher = new Publisher(); + publisher.setDataInfoId(dataInfoId); + publisher.setRegisterId(registerId); + publisher.setVersion(1L); + publisher.setClientRegisterTimestamp(time); + publisher.setSourceAddress(new URL("192.168.1.2", 9000)); + publisher.setTargetAddress(new URL("127.0.0.1", 34567)); + + Publisher publisher00 = new Publisher(); + publisher00.setDataInfoId(dataInfoId00); + publisher00.setRegisterId(registerId00); + publisher00.setVersion(1L); + publisher00.setClientRegisterTimestamp(time); + publisher00.setSourceAddress(new URL("192.168.1.2", 9000)); + publisher00.setTargetAddress(new URL("127.0.0.1", 34567)); + + publisherStore.add(publisher); + publisherStore.add(publisher00); + + Collection slotPublishers = publisherStore.getBySlotId(1); + Assert.assertEquals(1, slotPublishers.size()); + Publisher publisher1 = slotPublishers.stream().findAny().get(); + Assert.assertEquals(publisher00, publisher1); + } +} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SessionDataStoreTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SessionDataStoreTest.java deleted file mode 100644 index efe17a352..000000000 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SessionDataStoreTest.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; - -import com.alipay.sofa.registry.common.model.ConnectId; -import com.alipay.sofa.registry.common.model.PublisherUtils; -import com.alipay.sofa.registry.common.model.store.Publisher; -import com.alipay.sofa.registry.common.model.store.URL; -import com.alipay.sofa.registry.server.session.TestUtils; -import com.alipay.sofa.registry.server.session.slot.SlotTableCache; -import com.alipay.sofa.registry.server.session.slot.SlotTableCacheImpl; -import com.alipay.sofa.registry.util.ConcurrentUtils; -import com.alipay.sofa.registry.util.StringFormatter; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import java.util.*; -import java.util.concurrent.*; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; - -public class SessionDataStoreTest { - @Test - public void test() { - SessionDataStore store = new SessionDataStore(); - store.slotTableCache = Mockito.mock(SlotTableCache.class); - Publisher publisher0 = TestUtils.createTestPublishers(0, 1).get(0); - Publisher publisher1 = TestUtils.createTestPublishers(1, 1).get(0); - Mockito.when(store.slotTableCache.slotOf(publisher0.getDataInfoId())).thenReturn(0); - Mockito.when(store.slotTableCache.slotOf(publisher1.getDataInfoId())).thenReturn(1); - - Assert.assertEquals(store.count().o2.longValue(), 0); - store.add(publisher0); - store.add(publisher1); - Assert.assertEquals(store.count().o2.longValue(), 2); - - Map> m = store.getDatas(); - Assert.assertEquals(m.size(), 2); - assertPublisher(m, publisher0); - assertPublisher(m, publisher1); - - Collection publishers = store.getDatas(publisher0.getDataInfoId()); - Assert.assertEquals(publishers.size(), 1); - Assert.assertTrue(publishers.contains(publisher0)); - - publishers = store.getDatas(publisher1.getDataInfoId()); - Assert.assertEquals(publishers.size(), 1); - Assert.assertTrue(publishers.contains(publisher1)); - - m = store.getDataInfoIdPublishers(0); - Assert.assertEquals(m.size(), 1); - assertPublisher(m, publisher0); - - m = store.getDataInfoIdPublishers(1); - Assert.assertEquals(m.size(), 1); - assertPublisher(m, publisher1); - - List list = store.getDataList(); - Assert.assertEquals(list.size(), 2); - Assert.assertTrue(list.contains(publisher0)); - Assert.assertTrue(list.contains(publisher1)); - - Collection dataInfoIds = store.getDataInfoIds(); - Assert.assertEquals(dataInfoIds.size(), 2); - Assert.assertTrue(dataInfoIds.contains(publisher0.getDataInfoId())); - Assert.assertTrue(dataInfoIds.contains(publisher1.getDataInfoId())); - - Set connectIds = store.getConnectIds(); - Assert.assertTrue(connectIds.size() <= 2); - Assert.assertTrue(connectIds.contains(publisher0.connectId())); - Assert.assertTrue(connectIds.contains(publisher1.connectId())); - - Publisher query = store.queryById("1", "2"); - Assert.assertNull(query); - - query = store.queryById(publisher0.getRegisterId(), "2"); - Assert.assertNull(query); - - query = store.queryById("1", publisher0.getDataInfoId()); - Assert.assertNull(query); - - query = store.queryById(publisher0.getDataInfoId(), publisher0.getRegisterId()); - Assert.assertNull(query); - - query = store.queryById(publisher0.getRegisterId(), publisher0.getDataInfoId()); - Assert.assertEquals(query, publisher0); - - query = store.queryById(publisher1.getRegisterId(), publisher1.getDataInfoId()); - Assert.assertEquals(query, publisher1); - - Map map = store.queryByConnectId(ConnectId.of("xx:100", "yy:200")); - Assert.assertEquals(map.size(), 0); - - map = store.queryByConnectId(publisher0.connectId()); - Assert.assertEquals(map.get(publisher0.getRegisterId()), publisher0); - - map = store.queryByConnectId(publisher1.connectId()); - Assert.assertEquals(map.get(publisher1.getRegisterId()), publisher1); - - Assert.assertNull(store.deleteById("1", "2")); - - Assert.assertNotNull(store.deleteById(publisher0.getRegisterId(), publisher0.getDataInfoId())); - query = store.queryById(publisher0.getRegisterId(), publisher0.getDataInfoId()); - Assert.assertNull(query); - - query = store.queryById(publisher1.getRegisterId(), publisher1.getDataInfoId()); - Assert.assertNotNull(query); - - map = store.deleteByConnectId(publisher1.connectId()); - Assert.assertEquals(map.size(), 1); - Assert.assertEquals(map.get(publisher1.getRegisterId()), publisher1); - Assert.assertEquals(store.getDatas().size(), 0); - } - - private void assertPublisher(Map> m, Publisher publisher) { - Assert.assertEquals(m.get(publisher.getDataInfoId()).get(publisher.getRegisterId()), publisher); - Assert.assertEquals(m.get(publisher.getDataInfoId()).size(), 1); - } - - @Test - public void testConcurrent() throws InterruptedException { - SessionDataStore store = new SessionDataStore(); - store.slotTableCache = new SlotTableCacheImpl(); - int urlCount = 100; - List candUrls = Lists.newArrayListWithExpectedSize(urlCount); - URL targetAddress = new URL("192.168.0.2", 9600); - for (int i = 0; i < urlCount; i++) { - candUrls.add(i, new URL("192.168.0.1", 50000 + i)); - } - int dataIdCount = 20; - int ipPerDataId = 100; - Random random = new Random(); - random.setSeed(System.currentTimeMillis()); - List pubs = Lists.newArrayListWithCapacity(dataIdCount * ipPerDataId * 2); - Set urlset = Sets.newHashSetWithExpectedSize(candUrls.size()); - for (int i = 0; i < dataIdCount; i++) { - for (int j = 0; j < ipPerDataId; j++) { - Publisher pub = TestUtils.createTestPublisher(StringFormatter.format("dataId-{}", i)); - URL u1 = candUrls.get(random.nextInt(urlCount)); - urlset.add(u1); - pub.setSourceAddress(u1); - pub.setTargetAddress(targetAddress); - pubs.add(pub); - Publisher newPub = PublisherUtils.clonePublisher(pub); - newPub.setVersion(pub.getVersion() + 1); - URL u2 = candUrls.get(random.nextInt(urlCount)); - urlset.add(u2); - newPub.setSourceAddress(u2); - newPub.setTargetAddress(targetAddress); - pubs.add(newPub); - } - } - List urls = new ArrayList<>(urlset); - Collections.shuffle(pubs); - List unpubs = pickSample(pubs, pubs.size() / 10, random); - List clientOffUrls = pickSample(urls, urls.size() / 5, random); - List clientOffs = Lists.newArrayListWithExpectedSize(clientOffUrls.size()); - for (URL url : clientOffUrls) { - clientOffs.add( - new ConnectId( - url.getIpAddress(), url.getPort(), - targetAddress.getIpAddress(), targetAddress.getPort())); - } - - CountDownLatch latch = new CountDownLatch(pubs.size() + unpubs.size() + clientOffs.size()); - ThreadPoolExecutor pubExecutor = - new ThreadPoolExecutor(20, 20, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(pubs.size())); - ThreadPoolExecutor unpubExecutor = - new ThreadPoolExecutor( - 20, 20, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(unpubs.size())); - ThreadPoolExecutor clientOffExecutor = - new ThreadPoolExecutor( - clientOffs.size(), - clientOffs.size(), - 0, - TimeUnit.SECONDS, - new LinkedBlockingDeque<>(clientOffs.size())); - Timer refreshTimer = new Timer(); - - for (Publisher pub : pubs) { - pubExecutor.execute( - () -> { - store.addData(pub); - latch.countDown(); - }); - } - for (Publisher pub : unpubs) { - unpubExecutor.execute( - () -> { - store.deleteById(pub.getRegisterId(), pub.getDataInfoId()); - latch.countDown(); - }); - } - for (ConnectId connectId : clientOffs) { - clientOffExecutor.execute( - () -> { - ConcurrentUtils.sleepUninterruptibly(random.nextInt(10), TimeUnit.MILLISECONDS); - store.deleteByConnectId(connectId); - latch.countDown(); - }); - } - refreshTimer.scheduleAtFixedRate( - new TimerTask() { - @Override - public void run() { - store.connectDataIndexer.triggerRefresh(); - } - }, - 0, - 50); - latch.await(); - for (Publisher publisher : store.getDataList()) { - Assert.assertTrue( - store.queryByConnectId(publisher.connectId()).containsKey(publisher.getRegisterId())); - } - Assert.assertTrue(store.getConnectIds().size() >= urls.size() - clientOffs.size()); - for (ConnectId connectId : clientOffs) { - store.deleteByConnectId(connectId); - } - for (Publisher publisher : store.getDataList()) { - Assert.assertTrue( - store.queryByConnectId(publisher.connectId()).containsKey(publisher.getRegisterId())); - } - Assert.assertTrue(store.getConnectIds().size() >= urls.size() - clientOffs.size()); - - pubExecutor.shutdown(); - unpubExecutor.shutdown(); - clientOffExecutor.shutdown(); - refreshTimer.cancel(); - } - - public static List pickSample(List population, int nSamplesNeeded, Random r) { - ArrayList ret = new ArrayList<>(nSamplesNeeded); - int i = 0, nLeft = population.size(); - while (nSamplesNeeded > 0) { - int rand = r.nextInt(nLeft); - if (rand < nSamplesNeeded) { - ret.add(population.get(i)); - nSamplesNeeded--; - } - nLeft--; - i++; - } - Collections.shuffle(ret); - return ret; - } -} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SessionInterestsTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SessionInterestsTest.java deleted file mode 100644 index 0c84b3bea..000000000 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SessionInterestsTest.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; - -import com.alipay.sofa.registry.common.model.dataserver.DatumVersion; -import com.alipay.sofa.registry.common.model.store.DataInfo; -import com.alipay.sofa.registry.common.model.store.Subscriber; -import com.alipay.sofa.registry.server.session.AbstractSessionServerTestBase; -import java.util.Collection; -import java.util.Map; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class SessionInterestsTest extends AbstractSessionServerTestBase { - - private SessionInterests interests = new SessionInterests(); - - @Before - public void beforeSessionInterestsTest() { - interests.setSessionServerConfig(sessionServerConfig); - } - - @Test - public void testAdd() { - Subscriber subscriber1 = randomSubscriber(); - subscriber1.setVersion(0); - Subscriber subscriber2 = randomSubscriber(); - subscriber2.setVersion(1); - Assert.assertNotNull(subscriber1.getDataInfoId()); - Assert.assertTrue(interests.add(subscriber1)); - Assert.assertTrue(interests.add(subscriber2)); - } - - @Test - public void testCheckInterestVersion() { - Map map = interests.selectSubscribers(getDc()).o1; - Assert.assertEquals(0, map.size()); - - Assert.assertSame( - Interests.InterestVersionCheck.NoSub, - interests.checkInterestVersion(getDc(), randomSubscriber().getDataInfoId(), 1L)); - String dataInfo = randomString(10); - String instanceId = randomString(10); - Subscriber subscriber = randomSubscriber(dataInfo, instanceId); - interests.add(subscriber); - Assert.assertEquals( - Interests.InterestVersionCheck.Interested, - interests.checkInterestVersion( - getDc(), - DataInfo.toDataInfoId(dataInfo, instanceId, "default-group"), - System.currentTimeMillis() + 100)); - - Assert.assertTrue(subscriber.checkAndUpdateCtx(getDc(), 100, 10)); - Assert.assertFalse(subscriber.needPushEmpty(getDc())); - subscriber.markPushEmpty(getDc(), 100); - Assert.assertTrue(subscriber.needPushEmpty(getDc())); - Assert.assertFalse(subscriber.needPushEmpty(getDc() + "1")); - Assert.assertEquals( - Interests.InterestVersionCheck.Obsolete, - interests.checkInterestVersion( - getDc(), DataInfo.toDataInfoId(dataInfo, instanceId, "default-group"), 80)); - - Subscriber subscriber2 = randomSubscriber(dataInfo, instanceId); - interests.add(subscriber2); - - Collection dataList = interests.getDataList(); - for (Subscriber s : dataList) { - if (s == subscriber2) { - Assert.assertTrue(!s.hasPushed()); - } - } - - subscriber2.checkAndUpdateCtx(getDc(), 80, 20); - - // get sub2.dc1 - map = interests.selectSubscribers(getDc() + "1").o1; - Assert.assertEquals(map.size(), 1); - Assert.assertEquals(map.get(subscriber.getDataInfoId()).getValue(), 0); - - // get sub2 - map = interests.selectSubscribers(getDc()).o1; - Assert.assertEquals(map.size(), 1); - Assert.assertEquals(map.get(subscriber.getDataInfoId()).getValue(), 80); - } - - @Test - public void testFilterIPs() { - Assert.assertEquals(0, interests.filterIPs("", 0).size()); - Subscriber subscriber = randomSubscriber(); - interests.add(subscriber); - Assert.assertEquals(0, interests.filterIPs("", 0).size()); - Assert.assertEquals(1, interests.filterIPs(subscriber.getGroup(), 0).size()); - Assert.assertEquals( - 0, interests.filterIPs(subscriber.getGroup(), 0).get(subscriber.getDataInfoId()).size()); - Assert.assertEquals( - 1, interests.filterIPs(subscriber.getGroup(), 1).get(subscriber.getDataInfoId()).size()); - Assert.assertEquals( - 0, interests.filterIPs(subscriber.getGroup(), -1).get(subscriber.getDataInfoId()).size()); - Assert.assertEquals( - 1, interests.filterIPs(subscriber.getGroup(), 100).get(subscriber.getDataInfoId()).size()); - } -} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/StorePerformanceTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/StorePerformanceTest.java deleted file mode 100644 index 15b4a5e90..000000000 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/StorePerformanceTest.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; - -import com.alipay.sofa.registry.common.model.store.BaseInfo; -import com.alipay.sofa.registry.common.model.store.Publisher; -import com.alipay.sofa.registry.common.model.store.Subscriber; -import com.alipay.sofa.registry.common.model.store.URL; -import com.alipay.sofa.registry.core.model.ScopeEnum; -import com.alipay.sofa.registry.server.session.TestUtils; -import com.alipay.sofa.registry.server.session.slot.SlotTableCacheImpl; -import com.alipay.sofa.registry.util.ConcurrentUtils; -import java.util.List; -import org.junit.Test; - -public class StorePerformanceTest { - - private static final int DATA_ID_NUM = 10000; - private static final int DATA_NUM = 80; - - @Test - public void test() { - // too slow - // warm(); - // testSub0(); - // testSub1(); - } - - public static void warm() { - SessionInterests store = new SessionInterests(); - - for (int i = 0; i < 5; i++) { - int slotId = i % 256; - List list = TestUtils.createTestPublishers(slotId, 5); - for (Publisher p : list) { - Subscriber sub = new Subscriber(); - sub.setRegisterId(p.getRegisterId()); - sub.setDataInfoId(p.getDataInfoId()); - sub.setClientVersion(BaseInfo.ClientVersion.StoreData); - sub.setScope(ScopeEnum.zone); - sub.setSourceAddress(new URL("192.168.0.1", 54321)); - sub.setTargetAddress(new URL("192.168.0.2", 9600)); - sub.needPushEmpty("testdc"); - store.add(sub); - } - } - final long start = System.currentTimeMillis(); - for (int i = 0; i < 1000000; i++) { - final List l = store.getDataList(); - for (Subscriber s : l) { - s.needPushEmpty("testdc"); - } - store.forEach( - (d, map) -> { - for (Subscriber s : map.values()) { - s.needPushEmpty("testdc"); - } - }); - if (i % 10000 == 0) { - System.out.println(i + ":" + (System.currentTimeMillis() - start)); - } - } - } - - public static void testSub0() { - SessionInterests store = new SessionInterests(); - - for (int i = 0; i < DATA_ID_NUM; i++) { - int slotId = i % 256; - List list = TestUtils.createTestPublishers(slotId, DATA_NUM); - for (Publisher p : list) { - Subscriber sub = new Subscriber(); - sub.setRegisterId(p.getRegisterId()); - sub.setDataInfoId(p.getDataInfoId()); - sub.setClientVersion(BaseInfo.ClientVersion.StoreData); - sub.setScope(ScopeEnum.zone); - sub.needPushEmpty("testdc"); - store.add(sub); - } - } - List list = store.getDataList(); - System.out.println("start test"); - long size = 0; - long start = System.currentTimeMillis(); - for (int i = 0; i < 10000; i++) { - final List l = store.getDataList(); - for (Subscriber s : l) { - s.needPushEmpty("testdc"); - } - size += l.size(); - if (i % 100 == 0) { - System.out.println(i + ":" + (System.currentTimeMillis() - start)); - } - } - System.out.println(size + ":" + (System.currentTimeMillis() - start)); - if (true) { - return; - } - size = 0; - ConcurrentUtils.createDaemonThread("test-mofidier", new Modifier((List) list, store)).start(); - start = System.currentTimeMillis(); - for (int i = 0; i < 10000; i++) { - final List l = store.getDataList(); - for (Subscriber s : l) { - s.needPushEmpty("testdc"); - } - size += l.size(); - if (i % 100 == 0) { - System.out.println(i + ":" + (System.currentTimeMillis() - start)); - } - } - System.out.println(size + ":" + (System.currentTimeMillis() - start)); - } - - public static void testSub1() { - SessionInterests store = new SessionInterests(); - - for (int i = 0; i < DATA_ID_NUM; i++) { - int slotId = i % 256; - List list = TestUtils.createTestPublishers(slotId, DATA_NUM); - for (Publisher p : list) { - Subscriber sub = new Subscriber(); - sub.setRegisterId(p.getRegisterId()); - sub.setDataInfoId(p.getDataInfoId()); - sub.setClientVersion(BaseInfo.ClientVersion.StoreData); - sub.setScope(ScopeEnum.zone); - sub.needPushEmpty("testdc"); - store.add(sub); - } - } - List list = store.getDataList(); - System.out.println("start test"); - long size = 0; - long start = System.currentTimeMillis(); - for (int i = 0; i < 10000; i++) { - store.forEach( - (d, map) -> { - for (Subscriber s : map.values()) { - s.needPushEmpty("testdc"); - } - }); - if (i % 100 == 0) { - System.out.println(i + ":" + (System.currentTimeMillis() - start)); - } - } - System.out.println(size + ":" + (System.currentTimeMillis() - start)); - - if (true) { - return; - } - size = 0; - ConcurrentUtils.createDaemonThread("test-mofidier", new Modifier((List) list, store)).start(); - start = System.currentTimeMillis(); - for (int i = 0; i < 10000; i++) { - store.forEach( - (d, map) -> { - for (Subscriber s : map.values()) { - s.needPushEmpty("testdc"); - } - }); - if (i % 100 == 0) { - System.out.println(i + ":" + (System.currentTimeMillis() - start)); - } - } - System.out.println(size + ":" + (System.currentTimeMillis() - start)); - } - - private static final class Modifier implements Runnable { - final List infoList; - final AbstractDataManager mgr; - - Modifier(List list, AbstractDataManager mgr) { - this.infoList = list; - this.mgr = mgr; - } - - @Override - public void run() { - int i = 0; - for (; ; ) { - if (i < 0) { - i = 0; - } - BaseInfo b = infoList.get(i % infoList.size()); - mgr.deleteById(b.getRegisterId(), b.getDataInfoId()); - mgr.add(b); - } - } - } - - public static void testData() { - SessionDataStore store = new SessionDataStore(); - store.slotTableCache = new SlotTableCacheImpl(); - - for (int i = 0; i < DATA_ID_NUM; i++) { - int slotId = i % 256; - List list = TestUtils.createTestPublishers(slotId, DATA_NUM); - for (Publisher p : list) { - store.add(p); - } - } - System.out.println("start warm"); - for (int i = 0; i < 10000; i++) { - store.getDataList(); - } - System.out.println("start test"); - long size = 0; - long start = System.currentTimeMillis(); - for (int i = 0; i < 10000; i++) { - size += store.getDataList().size(); - } - System.out.println(size + ":" + (System.currentTimeMillis() - start)); - - size = 0; - start = System.currentTimeMillis(); - for (int i = 0; i < 10000; i++) { - size += store.getDataList().size(); - } - System.out.println(size + ":" + (System.currentTimeMillis() - start)); - } -} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SubscriberStoreTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SubscriberStoreTest.java new file mode 100644 index 000000000..5f01f556b --- /dev/null +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/SubscriberStoreTest.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; + +import com.alipay.sofa.registry.common.model.ConnectId; +import com.alipay.sofa.registry.common.model.Tuple; +import com.alipay.sofa.registry.common.model.dataserver.DatumVersion; +import com.alipay.sofa.registry.common.model.store.Subscriber; +import com.alipay.sofa.registry.common.model.store.URL; +import com.alipay.sofa.registry.core.model.ScopeEnum; +import com.alipay.sofa.registry.server.session.bootstrap.SessionServerConfig; +import java.util.List; +import java.util.Map; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Matchers; +import org.mockito.Mockito; + +/** */ +public class SubscriberStoreTest { + + @Test + public void testSelectSubscribers() { + String dataInfoId = "dataInfoId"; + String registerId = "registerId"; + + String dataInfoId00 = "dataInfoId00"; + String registerId00 = "registerId00"; + + SessionServerConfig sessionServerConfig = Mockito.mock(SessionServerConfig.class); + Mockito.when(sessionServerConfig.getSessionServerDataCenter()).thenReturn("localDataCenter"); + SubscriberStoreImpl subscriberStore = new SubscriberStoreImpl(sessionServerConfig); + + long time = System.currentTimeMillis(); + Subscriber subscriber = Mockito.mock(Subscriber.class); + Mockito.when(subscriber.getDataInfoId()).thenReturn(dataInfoId); + Mockito.when(subscriber.getId()).thenReturn(registerId); + Mockito.when(subscriber.getRegisterId()).thenReturn(registerId); + Mockito.when(subscriber.getScope()).thenReturn(ScopeEnum.zone).thenReturn(ScopeEnum.global); + Mockito.when(subscriber.getVersion()).thenReturn(1L); + Mockito.when(subscriber.getClientRegisterTimestamp()).thenReturn(time); + Mockito.when(subscriber.getSourceAddress()).thenReturn(new URL("192.168.1.2", 9000)); + Mockito.when(subscriber.getTargetAddress()).thenReturn(new URL("127.0.0.1", 34567)); + + ConnectId connectId = + new ConnectId( + new URL("192.168.1.2", 9000).getIpAddress(), + new URL("192.168.1.2", 9000).getPort(), + new URL("127.0.0.1", 34567).getIpAddress(), + new URL("127.0.0.1", 34567).getPort()); + + Mockito.when(subscriber.connectId()).thenReturn(connectId); + Mockito.when(subscriber.isMarkedPushEmpty(Matchers.anyString())).thenReturn(true); + Mockito.when(subscriber.needPushEmpty(Matchers.anyString())).thenReturn(true); + subscriberStore.add(subscriber); + + Subscriber subscriber00 = new Subscriber(); + subscriber00.setDataInfoId(dataInfoId00); + subscriber00.setRegisterId(registerId00); + subscriber00.setScope(ScopeEnum.global); + subscriber00.setVersion(1L); + subscriber00.setClientRegisterTimestamp(time); + subscriber00.setSourceAddress(new URL("192.168.1.2", 9000)); + subscriber00.setTargetAddress(new URL("127.0.0.1", 34567)); + + subscriberStore.add(subscriber00); + + Tuple, List> result = + subscriberStore.selectSubscribers("!localDataCenter"); + Assert.assertEquals(2, result.o1.size()); + Map map = result.getFirst(); + for (Map.Entry entry : map.entrySet()) { + Assert.assertTrue(entry.getKey().equals(dataInfoId) || entry.getKey().equals(dataInfoId00)); + Assert.assertEquals(0, entry.getValue().getValue()); + } + Assert.assertEquals(0, result.o2.size()); + + result = subscriberStore.selectSubscribers("localDataCenter"); + Assert.assertEquals(2, result.o1.size()); + map = result.getFirst(); + for (Map.Entry entry : map.entrySet()) { + Assert.assertTrue(entry.getKey().equals(dataInfoId) || entry.getKey().equals(dataInfoId00)); + Assert.assertEquals(0, entry.getValue().getValue()); + } + Assert.assertEquals(1, result.o2.size()); + } + + @Test + public void testCheckInterestVersion() { + String dataInfoId = "dataInfoId"; + String registerId = "registerId"; + + String dataInfoId00 = "dataInfoId00"; + String registerId00 = "registerId00"; + + SessionServerConfig sessionServerConfig = Mockito.mock(SessionServerConfig.class); + Mockito.when(sessionServerConfig.getSessionServerDataCenter()).thenReturn("localDataCenter"); + SubscriberStoreImpl subscriberStore = new SubscriberStoreImpl(sessionServerConfig); + + long time = System.currentTimeMillis(); + Subscriber subscriber = Mockito.mock(Subscriber.class); + Mockito.when(subscriber.getDataInfoId()).thenReturn(dataInfoId); + Mockito.when(subscriber.getId()).thenReturn(registerId); + Mockito.when(subscriber.getRegisterId()).thenReturn(registerId); + Mockito.when(subscriber.getScope()).thenReturn(ScopeEnum.zone).thenReturn(ScopeEnum.global); + Mockito.when(subscriber.getVersion()).thenReturn(1L); + Mockito.when(subscriber.getClientRegisterTimestamp()).thenReturn(time); + Mockito.when(subscriber.getSourceAddress()).thenReturn(new URL("192.168.1.2", 9000)); + Mockito.when(subscriber.getTargetAddress()).thenReturn(new URL("127.0.0.1", 34567)); + + ConnectId connectId = + new ConnectId( + new URL("192.168.1.2", 9000).getIpAddress(), + new URL("192.168.1.2", 9000).getPort(), + new URL("127.0.0.1", 34567).getIpAddress(), + new URL("127.0.0.1", 34567).getPort()); + + Mockito.when(subscriber.connectId()).thenReturn(connectId); + Mockito.when(subscriber.isMarkedPushEmpty(Matchers.anyString())).thenReturn(true); + Mockito.when(subscriber.needPushEmpty(Matchers.anyString())).thenReturn(true); + subscriberStore.add(subscriber); + + Subscriber subscriber00 = new Subscriber(); + subscriber00.setDataInfoId(dataInfoId00); + subscriber00.setRegisterId(registerId00); + subscriber00.setScope(ScopeEnum.global); + subscriber00.setVersion(1L); + subscriber00.setClientRegisterTimestamp(time); + subscriber00.setSourceAddress(new URL("192.168.1.2", 9000)); + subscriber00.setTargetAddress(new URL("127.0.0.1", 34567)); + + subscriberStore.add(subscriber00); + + SubscriberStore.InterestVersionCheck check = + subscriberStore.checkInterestVersion("localDataCenter", dataInfoId00 + "1", 0); + Assert.assertEquals(SubscriberStore.InterestVersionCheck.NoSub, check); + + check = subscriberStore.checkInterestVersion("localDataCenter", dataInfoId, 0); + Assert.assertEquals(SubscriberStore.InterestVersionCheck.Obsolete, check); + + Mockito.when(subscriber.checkVersion(Matchers.anyString(), Matchers.anyLong())) + .thenReturn(true); + check = subscriberStore.checkInterestVersion("localDataCenter", dataInfoId, 0); + Assert.assertEquals(SubscriberStore.InterestVersionCheck.Interested, check); + } +} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/WatcherStoreTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/WatcherStoreTest.java new file mode 100644 index 000000000..a50e0f279 --- /dev/null +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/WatcherStoreTest.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store; + +import com.alipay.sofa.registry.common.model.ConnectId; +import com.alipay.sofa.registry.common.model.store.URL; +import com.alipay.sofa.registry.common.model.store.Watcher; +import com.alipay.sofa.registry.server.session.store.engine.StoreEngine; +import java.util.Collection; +import org.junit.Assert; +import org.junit.Test; + +/** */ +public class WatcherStoreTest { + + @Test + public void test() { + WatcherStoreImpl watcherStore = new WatcherStoreImpl(); + + String dataInfoId = "dataInfoId"; + String registerId = "registerId"; + Watcher watcher = watcherStore.get(dataInfoId, registerId); + Assert.assertNull(watcher); + + long time = System.currentTimeMillis(); + watcher = new Watcher(); + watcher.setDataInfoId(dataInfoId); + watcher.setRegisterId(registerId); + watcher.setVersion(1L); + watcher.setClientRegisterTimestamp(time); + watcher.setSourceAddress(new URL("192.168.1.2", 9000)); + watcher.setTargetAddress(new URL("127.0.0.1", 34567)); + boolean success = watcherStore.add(watcher); + Assert.assertTrue(success); + + watcher = watcherStore.get(dataInfoId, registerId); + Assert.assertNotNull(watcher); + + Collection watchers = watcherStore.getAll(); + Assert.assertTrue(watchers.contains(watcher)); + + watchers = watcherStore.getByDataInfoId(dataInfoId); + Assert.assertTrue(watchers.contains(watcher)); + + Collection connectIds = watcherStore.getAllConnectId(); + Assert.assertEquals(1, connectIds.size()); + + ConnectId connectId = connectIds.stream().findAny().get(); + Assert.assertNotNull(connectId); + + watchers = watcherStore.getByConnectId(connectId); + Assert.assertTrue(watchers.contains(watcher)); + + StoreEngine.StoreStat storeStat = watcherStore.stat(); + Assert.assertEquals(1, storeStat.nonEmptyDataIdSize()); + Assert.assertEquals(1, storeStat.size()); + + watcherStore.delete(connectId); + watcher = watcherStore.get(dataInfoId, registerId); + Assert.assertNull(watcher); + storeStat = watcherStore.stat(); + Assert.assertEquals(0, storeStat.nonEmptyDataIdSize()); + Assert.assertEquals(0, storeStat.size()); + + Watcher watcher00 = new Watcher(); + watcher00.setDataInfoId(dataInfoId + "00"); + watcher00.setRegisterId(registerId + "00"); + watcher00.setVersion(1L); + watcher00.setClientRegisterTimestamp(time); + watcher00.setSourceAddress(new URL("192.168.1.2", 9000)); + watcher00.setTargetAddress(new URL("127.0.0.1", 34567)); + watcherStore.add(watcher00); + + storeStat = watcherStore.stat(); + Assert.assertEquals(1, storeStat.nonEmptyDataIdSize()); + Assert.assertEquals(1, storeStat.size()); + + Watcher deleted = watcherStore.delete(dataInfoId + "00", registerId + "00"); + Assert.assertEquals(watcher00, deleted); + + storeStat = watcherStore.stat(); + Assert.assertEquals(0, storeStat.nonEmptyDataIdSize()); + Assert.assertEquals(0, storeStat.size()); + } +} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngineTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngineTest.java new file mode 100644 index 000000000..07e550864 --- /dev/null +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngineTest.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store.engine; + +import com.alipay.sofa.registry.common.model.store.Watcher; +import java.util.Collection; +import javafx.util.Pair; +import org.junit.Assert; +import org.junit.Test; + +/** 测试基础的存储引擎 */ +public class SimpleMemoryStoreEngineTest { + + @Test + public void test() { + String dataInfoId = "dataInfoId"; + String registerId = "registerId"; + SimpleMemoryStoreEngine storeEngine = new SimpleMemoryStoreEngine<>(128); + Watcher watcher = storeEngine.get(dataInfoId, registerId); + Assert.assertNull(watcher); + + long time = System.currentTimeMillis(); + + watcher = new Watcher(); + watcher.setDataInfoId(dataInfoId); + watcher.setRegisterId(registerId); + watcher.setVersion(1L); + watcher.setClientRegisterTimestamp(time); + Pair pair = storeEngine.putIfAbsent(watcher); + Assert.assertTrue(pair.getKey()); + Assert.assertNull(pair.getValue()); + // 重复添加,且版本相同的情况则添加失败,返回的Watcher是已经存在的Watcher + pair = storeEngine.putIfAbsent(watcher); + Assert.assertFalse(pair.getKey()); + Assert.assertEquals(watcher, pair.getValue()); + // 重复添加,提升版本好,能添加成功 + Watcher watcher1 = new Watcher(); + watcher1.setDataInfoId(dataInfoId); + watcher1.setRegisterId(registerId); + watcher1.setVersion(2L); + watcher1.setClientRegisterTimestamp(time); + pair = storeEngine.putIfAbsent(watcher1); + Assert.assertTrue(pair.getKey()); + Assert.assertEquals(watcher, pair.getValue()); + + // get出来是最新添加的Watcher + Watcher watcher2 = storeEngine.get(dataInfoId, registerId); + Assert.assertEquals(watcher1, watcher2); + + // 批量获取的结果中包含了目标Watcher + Collection watchers = storeEngine.get(dataInfoId); + Assert.assertTrue(watchers.contains(watcher1)); + Collection allWatchers = storeEngine.getAll(); + Assert.assertTrue(allWatchers.contains(watcher1)); + + // 验证删除元素 + Watcher deletedWatcher = storeEngine.delete(dataInfoId, registerId); + Assert.assertEquals(watcher1, deletedWatcher); + + // 同一个DataInfoId增加两个元素,用于验证统计结果 + Watcher watcher00 = new Watcher(); + watcher00.setDataInfoId(dataInfoId + "00"); + watcher00.setRegisterId(registerId + "00"); + watcher00.setVersion(1L); + watcher00.setClientRegisterTimestamp(time); + storeEngine.putIfAbsent(watcher00); + + Watcher watcher01 = new Watcher(); + watcher01.setDataInfoId(dataInfoId + "00"); + watcher01.setRegisterId(registerId + "01"); + watcher01.setVersion(1L); + watcher01.setClientRegisterTimestamp(time); + storeEngine.putIfAbsent(watcher01); + + Collection nonEmptyDataInfoIdCollection = storeEngine.getNonEmptyDataInfoId(); + Assert.assertEquals(1, nonEmptyDataInfoIdCollection.size()); + Assert.assertTrue(nonEmptyDataInfoIdCollection.contains(dataInfoId + "00")); + + StoreEngine.StoreStat storeStat = storeEngine.stat(); + Assert.assertEquals(1, storeStat.nonEmptyDataIdSize()); + Assert.assertEquals(2, storeStat.size()); + } +} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/engine/SlotMemoryStoreEngineTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/engine/SlotMemoryStoreEngineTest.java new file mode 100644 index 000000000..3728b7616 --- /dev/null +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/store/engine/SlotMemoryStoreEngineTest.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.registry.server.session.store.engine; + +import com.alipay.sofa.registry.common.model.store.Watcher; +import java.util.Collection; +import javafx.util.Pair; +import org.junit.Assert; +import org.junit.Test; + +/** 测试支持按Key进行分槽的存储引擎 */ +public class SlotMemoryStoreEngineTest { + + @Test + public void test() { + SlotMemoryStoreEngine storeEngine = new SlotMemoryStoreEngine<>(String::hashCode); + + String dataInfoId = "dataInfoId"; + String registerId = "registerId"; + Watcher watcher = storeEngine.get(dataInfoId, registerId); + Assert.assertNull(watcher); + + long time = System.currentTimeMillis(); + + watcher = new Watcher(); + watcher.setDataInfoId(dataInfoId); + watcher.setRegisterId(registerId); + watcher.setVersion(1L); + watcher.setClientRegisterTimestamp(time); + Pair pair = storeEngine.putIfAbsent(watcher); + Assert.assertTrue(pair.getKey()); + Assert.assertNull(pair.getValue()); + // 重复添加,且版本相同的情况则添加失败,返回的Watcher是已经存在的Watcher + pair = storeEngine.putIfAbsent(watcher); + Assert.assertFalse(pair.getKey()); + Assert.assertEquals(watcher, pair.getValue()); + // 重复添加,提升版本好,能添加成功 + Watcher watcher1 = new Watcher(); + watcher1.setDataInfoId(dataInfoId); + watcher1.setRegisterId(registerId); + watcher1.setVersion(2L); + watcher1.setClientRegisterTimestamp(time); + pair = storeEngine.putIfAbsent(watcher1); + Assert.assertTrue(pair.getKey()); + Assert.assertEquals(watcher, pair.getValue()); + + // get出来是最新添加的Watcher + Watcher watcher2 = storeEngine.get(dataInfoId, registerId); + Assert.assertEquals(watcher1, watcher2); + + // 批量获取的结果中包含了目标Watcher + Collection watchers = storeEngine.get(dataInfoId); + Assert.assertTrue(watchers.contains(watcher1)); + Collection allWatchers = storeEngine.getAll(); + Assert.assertTrue(allWatchers.contains(watcher1)); + + // 验证删除元素 + Watcher deletedWatcher = storeEngine.delete(dataInfoId, registerId); + Assert.assertEquals(watcher1, deletedWatcher); + + // 同一个DataInfoId增加两个元素,用于验证统计结果 + Watcher watcher00 = new Watcher(); + watcher00.setDataInfoId(dataInfoId + "00"); + watcher00.setRegisterId(registerId + "00"); + watcher00.setVersion(1L); + watcher00.setClientRegisterTimestamp(time); + storeEngine.putIfAbsent(watcher00); + + Watcher watcher01 = new Watcher(); + watcher01.setDataInfoId(dataInfoId + "00"); + watcher01.setRegisterId(registerId + "01"); + watcher01.setVersion(1L); + watcher01.setClientRegisterTimestamp(time); + storeEngine.putIfAbsent(watcher01); + + Collection nonEmptyDataInfoIdCollection = storeEngine.getNonEmptyDataInfoId(); + Assert.assertEquals(1, nonEmptyDataInfoIdCollection.size()); + Assert.assertTrue(nonEmptyDataInfoIdCollection.contains(dataInfoId + "00")); + + StoreEngine.StoreStat storeStat = storeEngine.stat(); + Assert.assertEquals(1, storeStat.nonEmptyDataIdSize()); + Assert.assertEquals(2, storeStat.size()); + + int slotId = (dataInfoId + "00").hashCode(); + Collection slotWatchers = storeEngine.getSlotStoreData(slotId); + Assert.assertEquals(2, slotWatchers.size()); + } +} diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java index 7b91dbabf..09c1d9436 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java @@ -34,10 +34,11 @@ import com.alipay.sofa.registry.server.session.push.FirePushService; import com.alipay.sofa.registry.server.session.push.PushSwitchService; import com.alipay.sofa.registry.server.session.registry.DefaultClientRegistrationHook; -import com.alipay.sofa.registry.server.session.store.Watchers; +import com.alipay.sofa.registry.server.session.store.WatcherStore; +import com.alipay.sofa.registry.server.session.store.WatcherStoreImpl; import com.google.common.collect.Sets; +import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Set; import org.junit.Assert; import org.junit.Before; @@ -62,7 +63,7 @@ public void testAfterPublisherRegister() { mock(FirePushService.class), mock(PushSwitchService.class), mock(ConfigProvideDataWatcher.class), - mock(Watchers.class)); + mock(WatcherStoreImpl.class)); clientRegistrationHook.afterClientRegister(new Publisher()); } @@ -70,7 +71,7 @@ public void testAfterPublisherRegister() { public void testAfterWatcherRegisterDisable() { FirePushService firePushService = mock(FirePushService.class); PushSwitchService pushSwitchService = mock(PushSwitchService.class); - Watchers sessionWatchers = mock(Watchers.class); + WatcherStore watcherStore = mock(WatcherStoreImpl.class); ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); DefaultClientRegistrationHook clientRegistrationHook = new DefaultClientRegistrationHook( @@ -78,7 +79,7 @@ public void testAfterWatcherRegisterDisable() { firePushService, pushSwitchService, configProvideDataWatcher, - sessionWatchers); + watcherStore); Watcher w = TestUtils.newWatcher(dataId); clientRegistrationHook.afterClientRegister(w); @@ -96,7 +97,7 @@ public void testAfterWatcherRegisterEnable() { sessionServerConfig.setWatchConfigEnable(true); FirePushService firePushService = mock(FirePushService.class); PushSwitchService pushSwitchService = mock(PushSwitchService.class); - Watchers sessionWatchers = mock(Watchers.class); + WatcherStore watcherStore = mock(WatcherStoreImpl.class); ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); DefaultClientRegistrationHook clientRegistrationHook = new DefaultClientRegistrationHook( @@ -104,7 +105,7 @@ public void testAfterWatcherRegisterEnable() { firePushService, pushSwitchService, configProvideDataWatcher, - sessionWatchers); + watcherStore); Watcher w = TestUtils.newWatcher(dataId); clientRegistrationHook.afterClientRegister(w); @@ -125,7 +126,7 @@ public void testAfterWatcherRegisterEnable() { public void testFilter() { FirePushService firePushService = mock(FirePushService.class); PushSwitchService pushSwitchService = mock(PushSwitchService.class); - Watchers sessionWatchers = mock(Watchers.class); + WatcherStore watcherStore = mock(WatcherStoreImpl.class); ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); DefaultClientRegistrationHook clientRegistrationHook = new DefaultClientRegistrationHook( @@ -133,14 +134,14 @@ public void testFilter() { firePushService, pushSwitchService, configProvideDataWatcher, - sessionWatchers); + watcherStore); Assert.assertNull(clientRegistrationHook.filter()); Watcher w = TestUtils.newWatcher(dataId); - when(sessionWatchers.getDataList()).thenReturn(Collections.singletonList(w)); - Tuple, List> t = clientRegistrationHook.filter(); + when(watcherStore.getAll()).thenReturn(Collections.singletonList(w)); + Tuple, Collection> t = clientRegistrationHook.filter(); Assert.assertEquals(t.o1, Sets.newHashSet(w.getDataInfoId())); - Assert.assertEquals(t.o2.get(0), w); + Assert.assertTrue(t.o2.contains(w)); sessionServerConfig.setWatchConfigEnable(true); clientRegistrationHook.processWatch(); @@ -157,7 +158,7 @@ public void testFilter() { public void testProcess() { FirePushService firePushService = mock(FirePushService.class); PushSwitchService pushSwitchService = mock(PushSwitchService.class); - Watchers sessionWatchers = mock(Watchers.class); + WatcherStore watcherStore = mock(WatcherStoreImpl.class); ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); DefaultClientRegistrationHook clientRegistrationHook = new DefaultClientRegistrationHook( @@ -165,7 +166,7 @@ public void testProcess() { firePushService, pushSwitchService, configProvideDataWatcher, - sessionWatchers); + watcherStore); Watcher w = TestUtils.newWatcher(dataId); Assert.assertTrue(clientRegistrationHook.processWatchWhenWatchConfigDisable(w)); diff --git a/test/src/test/java/com/alipay/sofa/registry/test/BaseIntegrationTest.java b/test/src/test/java/com/alipay/sofa/registry/test/BaseIntegrationTest.java index 5f153c935..db8ec82b8 100644 --- a/test/src/test/java/com/alipay/sofa/registry/test/BaseIntegrationTest.java +++ b/test/src/test/java/com/alipay/sofa/registry/test/BaseIntegrationTest.java @@ -54,8 +54,8 @@ import com.alipay.sofa.registry.server.session.remoting.console.SessionConsoleExchanger; import com.alipay.sofa.registry.server.session.resource.PersistenceClientManagerResource; import com.alipay.sofa.registry.server.session.resource.SessionDigestResource; -import com.alipay.sofa.registry.server.session.store.DataStore; -import com.alipay.sofa.registry.server.session.store.Interests; +import com.alipay.sofa.registry.server.session.store.PublisherStore; +import com.alipay.sofa.registry.server.session.store.SubscriberStore; import com.alipay.sofa.registry.server.test.TestRegistryMain; import com.alipay.sofa.registry.util.ParaCheckUtil; import com.alipay.sofa.registry.util.StringFormatter; @@ -103,8 +103,8 @@ public class BaseIntegrationTest extends AbstractTest { protected static volatile Channel metaChannel; protected static volatile SessionRegistry sessionRegistry; - protected static volatile Interests sessionInterests; - protected static volatile DataStore sessionDataStore; + protected static volatile SubscriberStore subscriberStore; + protected static volatile PublisherStore publisherStore; protected static volatile DatumStorage localDatumStorage; protected static volatile ClientManagerResource clientManagerResource; @@ -188,8 +188,8 @@ public static void startServerIfNecessary() throws Exception { dataApplicationContext = testRegistryMain.getDataApplicationContext(); initRegistryClientAndChannel(); sessionRegistry = sessionApplicationContext.getBean("sessionRegistry", SessionRegistry.class); - sessionInterests = sessionApplicationContext.getBean("sessionInterests", Interests.class); - sessionDataStore = sessionApplicationContext.getBean("sessionDataStore", DataStore.class); + subscriberStore = sessionApplicationContext.getBean("subscriberStore", SubscriberStore.class); + publisherStore = sessionApplicationContext.getBean("publisherStore", PublisherStore.class); clientManagerResource = metaApplicationContext.getBean("clientManagerResource", ClientManagerResource.class); diff --git a/test/src/test/java/com/alipay/sofa/registry/test/client/ClientManagerTest.java b/test/src/test/java/com/alipay/sofa/registry/test/client/ClientManagerTest.java index 0aa614314..4dd3a780d 100644 --- a/test/src/test/java/com/alipay/sofa/registry/test/client/ClientManagerTest.java +++ b/test/src/test/java/com/alipay/sofa/registry/test/client/ClientManagerTest.java @@ -77,7 +77,8 @@ public void testClientOff() throws InterruptedException, TimeoutException { Thread.sleep(5000L); // check session - Assert.assertTrue(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertTrue( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data Assert.assertTrue( @@ -105,7 +106,8 @@ public void testClientOff() throws InterruptedException, TimeoutException { Thread.sleep(3000L); // check session local cache - Assert.assertFalse(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertFalse( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data publisher Assert.assertFalse( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); @@ -114,7 +116,8 @@ public void testClientOff() throws InterruptedException, TimeoutException { Thread.sleep(2000L); // check session local cache - Assert.assertFalse(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertFalse( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data publisher Assert.assertFalse( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); @@ -141,7 +144,8 @@ public void testClientOff() throws InterruptedException, TimeoutException { Thread.sleep(5000); // check session local cache - Assert.assertTrue(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertTrue( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); Assert.assertTrue( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); } @@ -224,7 +228,8 @@ public void testReduce() throws InterruptedException, TimeoutException { Thread.sleep(5000L); // check session - Assert.assertTrue(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertTrue( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data Assert.assertTrue( @@ -252,7 +257,8 @@ public void testReduce() throws InterruptedException, TimeoutException { Thread.sleep(3000L); // check session local cache - Assert.assertFalse(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertFalse( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data publisher Assert.assertFalse( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); @@ -261,7 +267,8 @@ public void testReduce() throws InterruptedException, TimeoutException { Thread.sleep(2000L); // check session local cache - Assert.assertFalse(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertFalse( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data publisher Assert.assertFalse( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); @@ -288,7 +295,8 @@ public void testReduce() throws InterruptedException, TimeoutException { Thread.sleep(5000); // check session local cache - Assert.assertFalse(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertFalse( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); Assert.assertFalse( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); @@ -296,7 +304,8 @@ public void testReduce() throws InterruptedException, TimeoutException { Thread.sleep(2000L); // check session local cache - Assert.assertTrue(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertTrue( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data publisher Assert.assertTrue( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); diff --git a/test/src/test/java/com/alipay/sofa/registry/test/client/SessionPersistenceClientManagerTest.java b/test/src/test/java/com/alipay/sofa/registry/test/client/SessionPersistenceClientManagerTest.java index 77f366423..c1387b2f8 100644 --- a/test/src/test/java/com/alipay/sofa/registry/test/client/SessionPersistenceClientManagerTest.java +++ b/test/src/test/java/com/alipay/sofa/registry/test/client/SessionPersistenceClientManagerTest.java @@ -77,7 +77,8 @@ public void testClientOff() throws InterruptedException, TimeoutException { Thread.sleep(5000L); // check session - Assert.assertTrue(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertTrue( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data Assert.assertTrue( @@ -110,7 +111,8 @@ public void testClientOff() throws InterruptedException, TimeoutException { Thread.sleep(3000L); // check session local cache - Assert.assertFalse(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertFalse( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data publisher Assert.assertFalse( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); @@ -119,7 +121,8 @@ public void testClientOff() throws InterruptedException, TimeoutException { Thread.sleep(2000L); // check session local cache - Assert.assertFalse(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertFalse( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data publisher Assert.assertFalse( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); @@ -151,7 +154,8 @@ public void testClientOff() throws InterruptedException, TimeoutException { Thread.sleep(5000); // check session local cache - Assert.assertTrue(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertTrue( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); Assert.assertTrue( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); } @@ -244,7 +248,8 @@ public void testReduce() throws InterruptedException, TimeoutException { Thread.sleep(5000L); // check session - Assert.assertTrue(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertTrue( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data Assert.assertTrue( @@ -277,7 +282,8 @@ public void testReduce() throws InterruptedException, TimeoutException { Thread.sleep(3000L); // check session local cache - Assert.assertFalse(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertFalse( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data publisher Assert.assertFalse( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); @@ -286,7 +292,8 @@ public void testReduce() throws InterruptedException, TimeoutException { Thread.sleep(2000L); // check session local cache - Assert.assertFalse(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertFalse( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data publisher Assert.assertFalse( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); @@ -318,7 +325,8 @@ public void testReduce() throws InterruptedException, TimeoutException { Thread.sleep(5000); // check session local cache - Assert.assertFalse(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertFalse( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); Assert.assertFalse( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); @@ -326,7 +334,8 @@ public void testReduce() throws InterruptedException, TimeoutException { Thread.sleep(2000L); // check session local cache - Assert.assertTrue(isExist(sessionDataStore.getDatas(dataInfo.getDataInfoId()), localAddress)); + Assert.assertTrue( + isExist(publisherStore.getByDataInfoId(dataInfo.getDataInfoId()), localAddress)); // check data publisher Assert.assertTrue( isExist(localDatumStorage.getAllPublisher().get(dataInfo.getDataInfoId()), localAddress)); diff --git a/test/src/test/java/com/alipay/sofa/registry/test/resource/session/ClientsManagerOpenResourceTest.java b/test/src/test/java/com/alipay/sofa/registry/test/resource/session/ClientsManagerOpenResourceTest.java index 4ab5d59a8..ad1cd8d15 100644 --- a/test/src/test/java/com/alipay/sofa/registry/test/resource/session/ClientsManagerOpenResourceTest.java +++ b/test/src/test/java/com/alipay/sofa/registry/test/resource/session/ClientsManagerOpenResourceTest.java @@ -62,24 +62,21 @@ public void testZoneClientOff() throws Exception { registryClient1.register(registration, value); Thread.sleep(3000L); - long count = - sessionDataStore.getDataList().stream().filter(p -> p.getDataId().equals(dataId)).count(); - Assert.assertEquals(count, 1); + long count = publisherStore.getAll().stream().filter(p -> p.getDataId().equals(dataId)).count(); + Assert.assertEquals(1, count); response = mockedResource.clientOffInZone(sessionChannel.getLocalAddress().getHostString()); assertTrue(response.isSuccess()); - count = - sessionDataStore.getDataList().stream().filter(p -> p.getDataId().equals(dataId)).count(); - Assert.assertEquals(count, 0); + count = publisherStore.getAll().stream().filter(p -> p.getDataId().equals(dataId)).count(); + Assert.assertEquals(0, count); // clientOn response = mockedResource.clientOn(sessionChannel.getLocalAddress().getHostString()); assertTrue(response.getMessage(), response.isSuccess()); Thread.sleep(5000L); - count = - sessionDataStore.getDataList().stream().filter(p -> p.getDataId().equals(dataId)).count(); - Assert.assertEquals(count, 1); + count = publisherStore.getAll().stream().filter(p -> p.getDataId().equals(dataId)).count(); + Assert.assertEquals(1, count); } @After From 189d7e0a57dc4bfb0ad8e2b78496f3048d59257b Mon Sep 17 00:00:00 2001 From: linxin Date: Wed, 22 Mar 2023 19:54:21 +0800 Subject: [PATCH 16/17] spring bean ClientRegistrationHook --- .../bootstrap/SessionServerConfiguration.java | 9 +- .../DefaultClientRegistrationHook.java | 27 ++--- .../session/registry/SessionRegistry.java | 11 +- .../DefaultAppRevisionHandlerStrategy.java | 3 +- .../DefaultPublisherHandlerStrategy.java | 3 +- .../DefaultSubscriberHandlerStrategy.java | 3 +- .../DefaultWatcherHandlerStrategy.java | 3 +- .../session/strategy/{impl => }/Metrics.java | 2 +- .../strategy/{impl => }/RegisterLogs.java | 2 +- .../DefaultClientRegistrationHookTest.java | 101 +++++------------- .../ServiceAppMappingPbHandlerTest.java | 2 +- .../strategy/{impl => }/MetricsTest.java | 2 +- 12 files changed, 56 insertions(+), 112 deletions(-) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/{impl => }/DefaultAppRevisionHandlerStrategy.java (98%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/{impl => }/DefaultPublisherHandlerStrategy.java (97%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/{impl => }/DefaultSubscriberHandlerStrategy.java (97%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/{impl => }/DefaultWatcherHandlerStrategy.java (97%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/{impl => }/Metrics.java (98%) rename server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/{impl => }/RegisterLogs.java (96%) rename server/server/session/src/test/java/com/alipay/sofa/registry/server/session/{strategy/impl => registry}/DefaultClientRegistrationHookTest.java (55%) rename server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/{impl => }/MetricsTest.java (93%) diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java index 1933c445e..ea7566cc4 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/bootstrap/SessionServerConfiguration.java @@ -44,6 +44,8 @@ import com.alipay.sofa.registry.server.session.node.service.*; import com.alipay.sofa.registry.server.session.providedata.*; import com.alipay.sofa.registry.server.session.push.*; +import com.alipay.sofa.registry.server.session.registry.ClientRegistrationHook; +import com.alipay.sofa.registry.server.session.registry.DefaultClientRegistrationHook; import com.alipay.sofa.registry.server.session.registry.Registry; import com.alipay.sofa.registry.server.session.registry.SessionRegistry; import com.alipay.sofa.registry.server.session.remoting.ClientNodeExchanger; @@ -60,7 +62,6 @@ import com.alipay.sofa.registry.server.session.slot.SlotTableCacheImpl; import com.alipay.sofa.registry.server.session.store.*; import com.alipay.sofa.registry.server.session.strategy.*; -import com.alipay.sofa.registry.server.session.strategy.impl.*; import com.alipay.sofa.registry.server.shared.client.manager.BaseClientManagerService; import com.alipay.sofa.registry.server.shared.client.manager.ClientManagerService; import com.alipay.sofa.registry.server.shared.meta.MetaServerManager; @@ -627,6 +628,12 @@ public CacheCountTask cacheCountTask() { @Configuration public static class SessionStrategyConfiguration { + @Bean + @ConditionalOnMissingBean + public ClientRegistrationHook clientRegistrationHook() { + return new DefaultClientRegistrationHook(); + } + @Bean @ConditionalOnMissingBean public PublisherHandlerStrategy publisherHandlerStrategy() { diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java index a2c3a5a57..7748369b4 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHook.java @@ -36,33 +36,26 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; +import javax.annotation.PostConstruct; import org.apache.commons.collections.CollectionUtils; import org.glassfish.jersey.internal.guava.Sets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; /** Default implementation of {@link ClientRegistrationHook}. */ public class DefaultClientRegistrationHook implements ClientRegistrationHook { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClientRegistrationHook.class); - private final SessionServerConfig sessionServerConfig; - private final FirePushService firePushService; - private final PushSwitchService pushSwitchService; - private final ConfigProvideDataWatcher configProvideDataWatcher; - private final Watchers sessionWatchers; - - public DefaultClientRegistrationHook( - SessionServerConfig sessionServerConfig, - FirePushService firePushService, - PushSwitchService pushSwitchService, - ConfigProvideDataWatcher configProvideDataWatcher, - Watchers sessionWatchers) { - this.sessionServerConfig = sessionServerConfig; - this.firePushService = firePushService; - this.pushSwitchService = pushSwitchService; - this.configProvideDataWatcher = configProvideDataWatcher; - this.sessionWatchers = sessionWatchers; + @Autowired protected SessionServerConfig sessionServerConfig; + @Autowired protected FirePushService firePushService; + @Autowired protected PushSwitchService pushSwitchService; + @Autowired protected ConfigProvideDataWatcher configProvideDataWatcher; + @Autowired protected Watchers sessionWatchers; + + @PostConstruct + public void init() { ConcurrentUtils.createDaemonThread( "watcher-scan-dog", new LoopRunnable() { diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java index 28104109c..6f49774cc 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/registry/SessionRegistry.java @@ -97,19 +97,12 @@ public class SessionRegistry implements Registry { @Autowired protected ConfigProvideDataWatcher configProvideDataWatcher; + @Autowired protected ClientRegistrationHook clientRegistrationHook; + private final VersionWatchDog versionWatchDog = new VersionWatchDog(); - private ClientRegistrationHook clientRegistrationHook; @PostConstruct public void init() { - this.clientRegistrationHook = - new DefaultClientRegistrationHook( - sessionServerConfig, - firePushService, - pushSwitchService, - configProvideDataWatcher, - sessionWatchers); - ConcurrentUtils.createDaemonThread("SessionVerWatchDog", versionWatchDog).start(); ConcurrentUtils.createDaemonThread("SessionClientWatchDog", new ClientWatchDog()).start(); } diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultAppRevisionHandlerStrategy.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultAppRevisionHandlerStrategy.java similarity index 98% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultAppRevisionHandlerStrategy.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultAppRevisionHandlerStrategy.java index bdd196493..af6bffbb0 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultAppRevisionHandlerStrategy.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultAppRevisionHandlerStrategy.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.strategy.impl; +package com.alipay.sofa.registry.server.session.strategy; import com.alipay.sofa.registry.common.model.appmeta.InterfaceMapping; import com.alipay.sofa.registry.common.model.client.pb.AppList; @@ -29,7 +29,6 @@ import com.alipay.sofa.registry.server.session.converter.pb.AppRevisionConvertor; import com.alipay.sofa.registry.server.session.metadata.MetadataCacheRegistry; import com.alipay.sofa.registry.server.session.push.PushSwitchService; -import com.alipay.sofa.registry.server.session.strategy.AppRevisionHandlerStrategy; import com.alipay.sofa.registry.util.ParaCheckUtil; import com.alipay.sofa.registry.util.StringFormatter; import com.google.common.annotations.VisibleForTesting; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultPublisherHandlerStrategy.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultPublisherHandlerStrategy.java similarity index 97% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultPublisherHandlerStrategy.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultPublisherHandlerStrategy.java index 5f1ba08e2..17aaf2604 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultPublisherHandlerStrategy.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultPublisherHandlerStrategy.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.strategy.impl; +package com.alipay.sofa.registry.server.session.strategy; import static com.alipay.sofa.registry.common.model.constants.ValueConstants.DEFAULT_INSTANCE_ID; @@ -29,7 +29,6 @@ import com.alipay.sofa.registry.remoting.Channel; import com.alipay.sofa.registry.server.session.converter.PublisherConverter; import com.alipay.sofa.registry.server.session.registry.Registry; -import com.alipay.sofa.registry.server.session.strategy.PublisherHandlerStrategy; import com.alipay.sofa.registry.server.shared.remoting.RemotingHelper; import com.alipay.sofa.registry.server.shared.util.DatumUtils; import org.apache.commons.lang.StringUtils; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSubscriberHandlerStrategy.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultSubscriberHandlerStrategy.java similarity index 97% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSubscriberHandlerStrategy.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultSubscriberHandlerStrategy.java index 998512277..69d82f5e6 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultSubscriberHandlerStrategy.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultSubscriberHandlerStrategy.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.strategy.impl; +package com.alipay.sofa.registry.server.session.strategy; import static com.alipay.sofa.registry.common.model.constants.ValueConstants.DEFAULT_INSTANCE_ID; @@ -30,7 +30,6 @@ import com.alipay.sofa.registry.remoting.bolt.BoltUtil; import com.alipay.sofa.registry.server.session.converter.SubscriberConverter; import com.alipay.sofa.registry.server.session.registry.Registry; -import com.alipay.sofa.registry.server.session.strategy.SubscriberHandlerStrategy; import com.alipay.sofa.registry.server.shared.remoting.RemotingHelper; import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.core.async.Hack; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultWatcherHandlerStrategy.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultWatcherHandlerStrategy.java similarity index 97% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultWatcherHandlerStrategy.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultWatcherHandlerStrategy.java index ecd9f2f1a..dab92447a 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultWatcherHandlerStrategy.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/DefaultWatcherHandlerStrategy.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.strategy.impl; +package com.alipay.sofa.registry.server.session.strategy; import static com.alipay.sofa.registry.common.model.constants.ValueConstants.DEFAULT_INSTANCE_ID; @@ -29,7 +29,6 @@ import com.alipay.sofa.registry.remoting.bolt.BoltUtil; import com.alipay.sofa.registry.server.session.converter.SubscriberConverter; import com.alipay.sofa.registry.server.session.registry.Registry; -import com.alipay.sofa.registry.server.session.strategy.WatcherHandlerStrategy; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/Metrics.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/Metrics.java similarity index 98% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/Metrics.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/Metrics.java index 8db593a56..563872365 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/Metrics.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/Metrics.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.strategy.impl; +package com.alipay.sofa.registry.server.session.strategy; import com.alipay.sofa.registry.common.model.InterestGroup; import io.prometheus.client.Counter; diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/RegisterLogs.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/RegisterLogs.java similarity index 96% rename from server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/RegisterLogs.java rename to server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/RegisterLogs.java index 6cf63c6a8..55f3d2900 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/impl/RegisterLogs.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/strategy/RegisterLogs.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.strategy.impl; +package com.alipay.sofa.registry.server.session.strategy; import com.alipay.sofa.registry.core.model.BaseRegister; import com.alipay.sofa.registry.core.model.RegisterResponse; diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHookTest.java similarity index 55% rename from server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java rename to server/server/session/src/test/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHookTest.java index 7b91dbabf..2d9e69b91 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/DefaultClientRegistrationHookTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/registry/DefaultClientRegistrationHookTest.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.strategy.impl; +package com.alipay.sofa.registry.server.session.registry; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; @@ -33,7 +33,6 @@ import com.alipay.sofa.registry.server.session.providedata.ConfigProvideDataWatcher; import com.alipay.sofa.registry.server.session.push.FirePushService; import com.alipay.sofa.registry.server.session.push.PushSwitchService; -import com.alipay.sofa.registry.server.session.registry.DefaultClientRegistrationHook; import com.alipay.sofa.registry.server.session.store.Watchers; import com.google.common.collect.Sets; import java.util.Collections; @@ -47,97 +46,65 @@ public class DefaultClientRegistrationHookTest extends AbstractSessionServerTestBase { private final String dataId = "testWatcherDataId"; + private DefaultClientRegistrationHook clientRegistrationHook = + new DefaultClientRegistrationHook(); @Before public void before() { sessionServerConfig.setWatchConfigEnable(false); sessionServerConfig.setScanWatcherIntervalMillis(10); + + clientRegistrationHook.sessionServerConfig = sessionServerConfig; + clientRegistrationHook.firePushService = mock(FirePushService.class); + clientRegistrationHook.pushSwitchService = mock(PushSwitchService.class); + clientRegistrationHook.sessionWatchers = mock(Watchers.class); + clientRegistrationHook.configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); } @Test public void testAfterPublisherRegister() { - DefaultClientRegistrationHook clientRegistrationHook = - new DefaultClientRegistrationHook( - sessionServerConfig, - mock(FirePushService.class), - mock(PushSwitchService.class), - mock(ConfigProvideDataWatcher.class), - mock(Watchers.class)); + DefaultClientRegistrationHook clientRegistrationHook = new DefaultClientRegistrationHook(); clientRegistrationHook.afterClientRegister(new Publisher()); } @Test public void testAfterWatcherRegisterDisable() { - FirePushService firePushService = mock(FirePushService.class); - PushSwitchService pushSwitchService = mock(PushSwitchService.class); - Watchers sessionWatchers = mock(Watchers.class); - ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); - DefaultClientRegistrationHook clientRegistrationHook = - new DefaultClientRegistrationHook( - sessionServerConfig, - firePushService, - pushSwitchService, - configProvideDataWatcher, - sessionWatchers); - Watcher w = TestUtils.newWatcher(dataId); clientRegistrationHook.afterClientRegister(w); - verify(firePushService, times(0)).fireOnWatcher(any(), any()); + verify(clientRegistrationHook.firePushService, times(0)).fireOnWatcher(any(), any()); - when(pushSwitchService.canIpPush(anyString())).thenReturn(true); + when(clientRegistrationHook.pushSwitchService.canIpPush(anyString())).thenReturn(true); clientRegistrationHook.afterClientRegister(w); - verify(firePushService, times(1)).fireOnWatcher(any(), any()); - verify(configProvideDataWatcher, times(0)).watch(any()); + verify(clientRegistrationHook.firePushService, times(1)).fireOnWatcher(any(), any()); + verify(clientRegistrationHook.configProvideDataWatcher, times(0)).watch(any()); } @Test public void testAfterWatcherRegisterEnable() { sessionServerConfig.setWatchConfigEnable(true); - FirePushService firePushService = mock(FirePushService.class); - PushSwitchService pushSwitchService = mock(PushSwitchService.class); - Watchers sessionWatchers = mock(Watchers.class); - ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); - DefaultClientRegistrationHook clientRegistrationHook = - new DefaultClientRegistrationHook( - sessionServerConfig, - firePushService, - pushSwitchService, - configProvideDataWatcher, - sessionWatchers); Watcher w = TestUtils.newWatcher(dataId); clientRegistrationHook.afterClientRegister(w); - verify(configProvideDataWatcher, times(1)).watch(any()); - verify(firePushService, times(0)).fireOnWatcher(any(), any()); + verify(clientRegistrationHook.configProvideDataWatcher, times(1)).watch(any()); + verify(clientRegistrationHook.firePushService, times(0)).fireOnWatcher(any(), any()); - when(pushSwitchService.canIpPush(anyString())).thenReturn(true); + when(clientRegistrationHook.pushSwitchService.canIpPush(anyString())).thenReturn(true); clientRegistrationHook.afterClientRegister(w); - verify(firePushService, times(0)).fireOnWatcher(any(), any()); + verify(clientRegistrationHook.firePushService, times(0)).fireOnWatcher(any(), any()); - when(configProvideDataWatcher.get(anyString())) + when(clientRegistrationHook.configProvideDataWatcher.get(anyString())) .thenReturn(new ProvideData(null, "dataId", 100L)); clientRegistrationHook.afterClientRegister(w); - verify(firePushService, times(1)).fireOnWatcher(any(), any()); + verify(clientRegistrationHook.firePushService, times(1)).fireOnWatcher(any(), any()); } @Test public void testFilter() { - FirePushService firePushService = mock(FirePushService.class); - PushSwitchService pushSwitchService = mock(PushSwitchService.class); - Watchers sessionWatchers = mock(Watchers.class); - ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); - DefaultClientRegistrationHook clientRegistrationHook = - new DefaultClientRegistrationHook( - sessionServerConfig, - firePushService, - pushSwitchService, - configProvideDataWatcher, - sessionWatchers); - Assert.assertNull(clientRegistrationHook.filter()); Watcher w = TestUtils.newWatcher(dataId); - when(sessionWatchers.getDataList()).thenReturn(Collections.singletonList(w)); + when(clientRegistrationHook.sessionWatchers.getDataList()) + .thenReturn(Collections.singletonList(w)); Tuple, List> t = clientRegistrationHook.filter(); Assert.assertEquals(t.o1, Sets.newHashSet(w.getDataInfoId())); Assert.assertEquals(t.o2.get(0), w); @@ -155,21 +122,9 @@ public void testFilter() { @Test public void testProcess() { - FirePushService firePushService = mock(FirePushService.class); - PushSwitchService pushSwitchService = mock(PushSwitchService.class); - Watchers sessionWatchers = mock(Watchers.class); - ConfigProvideDataWatcher configProvideDataWatcher = mock(ConfigProvideDataWatcher.class); - DefaultClientRegistrationHook clientRegistrationHook = - new DefaultClientRegistrationHook( - sessionServerConfig, - firePushService, - pushSwitchService, - configProvideDataWatcher, - sessionWatchers); - Watcher w = TestUtils.newWatcher(dataId); Assert.assertTrue(clientRegistrationHook.processWatchWhenWatchConfigDisable(w)); - verify(firePushService, times(1)).fireOnWatcher(any(), any()); + verify(clientRegistrationHook.firePushService, times(1)).fireOnWatcher(any(), any()); w.updatePushedVersion(10); Assert.assertFalse(clientRegistrationHook.processWatchWhenWatchConfigDisable(w)); @@ -177,18 +132,18 @@ public void testProcess() { w = TestUtils.newWatcher(dataId); Assert.assertFalse(clientRegistrationHook.processWatchWhenWatchConfigEnable(w)); ProvideData data = new ProvideData(null, dataId, 10L); - when(configProvideDataWatcher.get(anyString())).thenReturn(data); + when(clientRegistrationHook.configProvideDataWatcher.get(anyString())).thenReturn(data); Assert.assertTrue(clientRegistrationHook.processWatchWhenWatchConfigEnable(w)); - verify(firePushService, times(2)).fireOnWatcher(any(), any()); + verify(clientRegistrationHook.firePushService, times(2)).fireOnWatcher(any(), any()); w.updatePushedVersion(10); Assert.assertFalse(clientRegistrationHook.processWatchWhenWatchConfigEnable(w)); - verify(firePushService, times(2)).fireOnWatcher(any(), any()); + verify(clientRegistrationHook.firePushService, times(2)).fireOnWatcher(any(), any()); data = new ProvideData(null, dataId, 20L); - when(configProvideDataWatcher.get(anyString())).thenReturn(data); + when(clientRegistrationHook.configProvideDataWatcher.get(anyString())).thenReturn(data); Assert.assertTrue(clientRegistrationHook.processWatchWhenWatchConfigEnable(w)); - verify(firePushService, times(3)).fireOnWatcher(any(), any()); + verify(clientRegistrationHook.firePushService, times(3)).fireOnWatcher(any(), any()); w.updatePushedVersion(20); Assert.assertFalse(clientRegistrationHook.processWatch(w, false)); Assert.assertFalse(clientRegistrationHook.processWatch(w, true)); diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/ServiceAppMappingPbHandlerTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/ServiceAppMappingPbHandlerTest.java index bd7f0276e..f0e7da60d 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/ServiceAppMappingPbHandlerTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/remoting/handler/ServiceAppMappingPbHandlerTest.java @@ -29,7 +29,7 @@ import com.alipay.sofa.registry.server.session.bootstrap.ExecutorManager; import com.alipay.sofa.registry.server.session.push.PushSwitchService; import com.alipay.sofa.registry.server.session.strategy.AppRevisionHandlerStrategy; -import com.alipay.sofa.registry.server.session.strategy.impl.DefaultAppRevisionHandlerStrategy; +import com.alipay.sofa.registry.server.session.strategy.DefaultAppRevisionHandlerStrategy; import org.assertj.core.util.Lists; import org.junit.Assert; import org.junit.Test; diff --git a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/MetricsTest.java b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/MetricsTest.java similarity index 93% rename from server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/MetricsTest.java rename to server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/MetricsTest.java index 35e845c0c..5429d69cd 100644 --- a/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/impl/MetricsTest.java +++ b/server/server/session/src/test/java/com/alipay/sofa/registry/server/session/strategy/MetricsTest.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.registry.server.session.strategy.impl; +package com.alipay.sofa.registry.server.session.strategy; import org.junit.Test; From 8bb6273ce39fa5626ff3a02e84c60b3f9ac1b9a9 Mon Sep 17 00:00:00 2001 From: linxin Date: Thu, 25 May 2023 17:45:16 +0800 Subject: [PATCH 17/17] fix cr --- .../store/engine/SimpleMemoryStoreEngine.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngine.java b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngine.java index fecd38713..cc4331423 100644 --- a/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngine.java +++ b/server/server/session/src/main/java/com/alipay/sofa/registry/server/session/store/engine/SimpleMemoryStoreEngine.java @@ -39,17 +39,8 @@ public SimpleMemoryStoreEngine(int initialSize) { @Override public Pair putIfAbsent(T storeData) { String dataInfoId = storeData.getDataInfoId(); - ClientsGroup clientsGroup = groups.get(dataInfoId); - if (clientsGroup == null) { - clientsGroup = new ClientsGroup<>(dataInfoId, 128); - ClientsGroup exist = groups.putIfAbsent(dataInfoId, clientsGroup); - if (exist != null) { - // 如果之前已经存在了,直接复用之前的ClientGroups,并向其中加入新的StoreData - // 如果exist == null,意味着新的ClientGroups被添加进去了,向新的ClientGroups加入StoreData - clientsGroup = exist; - } - } - + ClientsGroup clientsGroup = + groups.computeIfAbsent(dataInfoId, s -> new ClientsGroup<>(dataInfoId, 128)); return clientsGroup.putIfAbsent(storeData); }