You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by "MieAh (via GitHub)" <gi...@apache.org> on 2023/02/11 08:26:13 UTC
[GitHub] [dubbo] MieAh opened a new pull request, #11531: Support choose local invoke in runtime instead of startup
MieAh opened a new pull request, #11531:
URL: https://github.com/apache/dubbo/pull/11531
## What is the purpose of the change
Finish issue#11013.To support choose local invoke in runtime instead of startup
## Brief changelog
In this change, I added ScopeClusterInvoker, and the mode similar to MockClusterInvoker put the judgment of local call in the runtime. However, when initializing the subscription, the local call will be judged in the original way.
## Verifying this change
<!-- Follow this checklist to help us incorporate your contribution quickly and easily: -->
## Checklist
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change (usually before you start working on it). Trivial changes like typos do not require a GitHub issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
- [ ] Each commit in the pull request should have a meaningful subject line and body.
- [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
- [ ] Check if is necessary to patch to Dubbo 3 if you are work on Dubbo 2.7
- [ ] Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
- [ ] Add some description to [dubbo-website](https://github.com/apache/dubbo-website) project if you are requesting to add a feature.
- [ ] GitHub Actions works fine on your own branch.
- [ ] If this contribution is large, please follow the [Software Donation Guide](https://github.com/apache/dubbo/wiki/Software-donation-guide).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] codecov-commenter commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "codecov-commenter (via GitHub)" <gi...@apache.org>.
codecov-commenter commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1464819114
## [Codecov](https://codecov.io/gh/apache/dubbo/pull/11531?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) Report
> Merging [#11531](https://codecov.io/gh/apache/dubbo/pull/11531?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (14a4d0d) into [3.2](https://codecov.io/gh/apache/dubbo/commit/a8a8eda38f3a279a2661cb15b3285735ce5339d9?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (a8a8eda) will **increase** coverage by `0.15%`.
> The diff coverage is `n/a`.
```diff
@@ Coverage Diff @@
## 3.2 #11531 +/- ##
============================================
+ Coverage 68.77% 68.92% +0.15%
+ Complexity 339 2 -337
============================================
Files 1454 1534 +80
Lines 74887 63621 -11266
Branches 12960 9323 -3637
============================================
- Hits 51501 43849 -7652
+ Misses 18731 15511 -3220
+ Partials 4655 4261 -394
```
[see 2988 files with indirect coverage changes](https://codecov.io/gh/apache/dubbo/pull/11531/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] AlbumenJ merged pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "AlbumenJ (via GitHub)" <gi...@apache.org>.
AlbumenJ merged PR #11531:
URL: https://github.com/apache/dubbo/pull/11531
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] sonarcloud[bot] commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "sonarcloud[bot] (via GitHub)" <gi...@apache.org>.
sonarcloud[bot] commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1464864418
SonarCloud Quality Gate failed. [](https://sonarcloud.io/dashboard?id=apache_dubbo&pullRequest=11531)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [2 Bugs](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY)
[](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [6 Code Smells](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list) [57.1% Coverage](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list) [3.2% Duplication](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] sonarcloud[bot] commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "sonarcloud[bot] (via GitHub)" <gi...@apache.org>.
sonarcloud[bot] commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1460544887
SonarCloud Quality Gate failed. [](https://sonarcloud.io/dashboard?id=apache_dubbo&pullRequest=11531)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [2 Bugs](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY)
[](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [6 Code Smells](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list) [56.2% Coverage](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list) [3.2% Duplication](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] MieAh commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "MieAh (via GitHub)" <gi...@apache.org>.
MieAh commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1124195024
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equals(getRegistryUrl().getProtocol())) {
+ isExported.compareAndSet(false, true);
+ injvmInvoker = invoker;
+ }
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension("injvm");
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ }
+
+ @Override
+ public URL getUrl() {
+ return directory.getConsumerUrl();
+ }
+
+ @Override
+ public URL getRegistryUrl() {
+ return directory.getUrl();
+ }
+
+ @Override
+ public Directory<T> getDirectory() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return directory.isDestroyed();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (injvmExporterListener == null) {
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension(LOCAL_PROTOCOL);
+ }
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ return isExported.get() || directory.isAvailable();
+ }
+
+ @Override
+ public void destroy() {
+ if (injvmExporterListener != null) {
+ injvmExporterListener.removeExporterChangeListener(getUrl().getServiceKey());
+ }
+ this.invoker.destroy();
+ }
+
+ @Override
+ public Class<T> getInterface() {
+ return directory.getInterface();
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ if (peer != null && peer) {
+ return invoker.invoke(invocation);
+ }
+ String scope = getUrl().getParameter(SCOPE_KEY);
+ if (shouldInvokeInjvm(getUrl().getParameter(LOCAL_PROTOCOL), scope)) {
+ return injvmInvoker.invoke(invocation);
+ }
+ return invoker.invoke(invocation);
+ }
+
+ private boolean shouldInvokeInjvm(String isInjvm, String scope) {
+ if (Boolean.TRUE.toString().equals(isInjvm)) {
+ return isInjvmExported(scope);
+ } else if (isInjvm == null) {
+ return isInjvmExportedAndNotRemoteOrGeneric(scope);
+ }
+ return false;
+ }
+
+ private boolean isInjvmExportedAndNotRemoteOrGeneric(String scope) {
+ return !SCOPE_REMOTE.equalsIgnoreCase(scope) &&
+ !getUrl().getParameter(GENERIC_KEY, false) && isInjvmExported(scope);
+ }
+
+ private boolean isInjvmExported(String scope) {
+ if (!isExported.get() && SCOPE_LOCAL.equalsIgnoreCase(scope)) {
+ throw new RpcException("Local service has not been exposed yet!");
+ }
+ return isExported.get();
+ }
+
+
+ private Invoker<T> createInjvmInvoker() {
+ URL url = new ServiceConfigURL(LOCAL_PROTOCOL, NetUtils.getLocalHost(), getUrl().getPort(), getInterface().getName(), getUrl().getParameters());
+ url = url.setScopeModel(getUrl().getScopeModel());
+ url = url.setServiceModel(getUrl().getServiceModel());
+ return protocolSPI.refer(getInterface(), url);
+ }
+
+ @Override
+ public void onExporterChangeExport(Exporter<?> exporter) {
+ if (isExported.get()) {
+ return;
+ }
+ if (getUrl().getServiceKey().equals(exporter.getInvoker().getUrl().getServiceKey())
+ && exporter.getInvoker().getUrl().getProtocol().equals(LOCAL_PROTOCOL)) {
+ isExported.compareAndSet(false, true);
+ }
+ if (isExported.get() && injvmInvoker == null) {
+ if (injvmInvoker == null) {
+ synchronized (createLock) {
+ if (injvmInvoker == null) {
+ injvmInvoker = createInjvmInvoker();
+ }
+ }
+ }
+ }
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] MieAh commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "MieAh (via GitHub)" <gi...@apache.org>.
MieAh commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1134467960
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,211 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.Cluster;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private boolean peerFlag;
+
+ private boolean injvmFlag;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ String isInjvm = getUrl().getParameter(LOCAL_PROTOCOL);
+ if (peer != null && peer) {
+ peerFlag = true;
+ return;
+ }
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equalsIgnoreCase(getRegistryUrl().getProtocol())) {
+ injvmInvoker = invoker;
+ isExported.compareAndSet(false, true);
+ injvmFlag = true;
+ return;
+ }
+ if (Boolean.TRUE.toString().equalsIgnoreCase(isInjvm) || LOCAL_KEY.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY))) {
+ injvmFlag = true;
+ } else if (isInjvm == null) {
+ injvmFlag = isNotRemoteOrGeneric();
+ }
+ if (injvmFlag) {
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension(LOCAL_PROTOCOL);
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] AlbumenJ commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "AlbumenJ (via GitHub)" <gi...@apache.org>.
AlbumenJ commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1446205842
Please fix conflicts
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] MieAh commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "MieAh (via GitHub)" <gi...@apache.org>.
MieAh commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1124068240
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equals(getRegistryUrl().getProtocol())) {
+ isExported.compareAndSet(false, true);
+ injvmInvoker = invoker;
+ }
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension("injvm");
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ }
+
+ @Override
+ public URL getUrl() {
+ return directory.getConsumerUrl();
+ }
+
+ @Override
+ public URL getRegistryUrl() {
+ return directory.getUrl();
+ }
+
+ @Override
+ public Directory<T> getDirectory() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return directory.isDestroyed();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (injvmExporterListener == null) {
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension(LOCAL_PROTOCOL);
+ }
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ return isExported.get() || directory.isAvailable();
+ }
+
+ @Override
+ public void destroy() {
+ if (injvmExporterListener != null) {
+ injvmExporterListener.removeExporterChangeListener(getUrl().getServiceKey());
+ }
+ this.invoker.destroy();
+ }
+
+ @Override
+ public Class<T> getInterface() {
+ return directory.getInterface();
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ if (peer != null && peer) {
+ return invoker.invoke(invocation);
+ }
+ String scope = getUrl().getParameter(SCOPE_KEY);
+ if (shouldInvokeInjvm(getUrl().getParameter(LOCAL_PROTOCOL), scope)) {
Review Comment:
done
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equals(getRegistryUrl().getProtocol())) {
+ isExported.compareAndSet(false, true);
+ injvmInvoker = invoker;
+ }
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension("injvm");
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ }
+
+ @Override
+ public URL getUrl() {
+ return directory.getConsumerUrl();
+ }
+
+ @Override
+ public URL getRegistryUrl() {
+ return directory.getUrl();
+ }
+
+ @Override
+ public Directory<T> getDirectory() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return directory.isDestroyed();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (injvmExporterListener == null) {
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension(LOCAL_PROTOCOL);
+ }
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ return isExported.get() || directory.isAvailable();
+ }
+
+ @Override
+ public void destroy() {
+ if (injvmExporterListener != null) {
+ injvmExporterListener.removeExporterChangeListener(getUrl().getServiceKey());
+ }
+ this.invoker.destroy();
+ }
+
+ @Override
+ public Class<T> getInterface() {
+ return directory.getInterface();
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ if (peer != null && peer) {
+ return invoker.invoke(invocation);
+ }
+ String scope = getUrl().getParameter(SCOPE_KEY);
+ if (shouldInvokeInjvm(getUrl().getParameter(LOCAL_PROTOCOL), scope)) {
+ return injvmInvoker.invoke(invocation);
+ }
+ return invoker.invoke(invocation);
+ }
+
+ private boolean shouldInvokeInjvm(String isInjvm, String scope) {
+ if (Boolean.TRUE.toString().equals(isInjvm)) {
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] MieAh commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "MieAh (via GitHub)" <gi...@apache.org>.
MieAh commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1428120937
@AlbumenJ PTAL
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] AlbumenJ commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "AlbumenJ (via GitHub)" <gi...@apache.org>.
AlbumenJ commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1133882809
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,211 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.Cluster;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private boolean peerFlag;
+
+ private boolean injvmFlag;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ String isInjvm = getUrl().getParameter(LOCAL_PROTOCOL);
+ if (peer != null && peer) {
+ peerFlag = true;
+ return;
+ }
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equalsIgnoreCase(getRegistryUrl().getProtocol())) {
+ injvmInvoker = invoker;
+ isExported.compareAndSet(false, true);
+ injvmFlag = true;
+ return;
+ }
+ if (Boolean.TRUE.toString().equalsIgnoreCase(isInjvm) || LOCAL_KEY.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY))) {
+ injvmFlag = true;
+ } else if (isInjvm == null) {
+ injvmFlag = isNotRemoteOrGeneric();
+ }
+ if (injvmFlag) {
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension(LOCAL_PROTOCOL);
Review Comment:
Convert ExporterListener into a scope bean.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] MieAh commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "MieAh (via GitHub)" <gi...@apache.org>.
MieAh commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1124068777
##########
dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/InjvmExporterListener.java:
##########
@@ -0,0 +1,66 @@
+/*
+ * 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 org.apache.dubbo.rpc.listener;
+
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.RpcException;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class InjvmExporterListener extends ExporterListenerAdapter {
+
+ private final Map<String, ExporterChangeListener> exporterChangeListeners = new ConcurrentHashMap<>();
+
+ private final Map<String, Exporter<?>> exporters = new ConcurrentHashMap<>();
+
+ @Override
+ public void exported(Exporter<?> exporter) throws RpcException {
+ String serviceKey = exporter.getInvoker().getUrl().getServiceKey();
+ exporters.putIfAbsent(exporter.getInvoker().getUrl().getServiceKey(), exporter);
Review Comment:
这里不应该是只考虑本地调用吗,也不需要经过网络传输,InjvmExporter 只会被当前的服务引用所订阅,理应不会出现多个订阅者的情况。而且每个服务只会暴露一个 InjvmExporter 实例,因此也不存在同一个服务多个 InjvmExporter 实例的情况
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] MieAh commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "MieAh (via GitHub)" <gi...@apache.org>.
MieAh commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1109835344
##########
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java:
##########
@@ -420,8 +420,9 @@ private Map<String, String> appendConfig() {
@SuppressWarnings({"unchecked"})
private T createProxy(Map<String, String> referenceParameters) {
+ URL curUrl;
if (shouldJvmRefer(referenceParameters)) {
- createInvokerForLocal(referenceParameters);
+ curUrl = createInvokerForLocal(referenceParameters);
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] MieAh commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "MieAh (via GitHub)" <gi...@apache.org>.
MieAh commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1126477373
##########
dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/InjvmExporterListener.java:
##########
@@ -0,0 +1,66 @@
+/*
+ * 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 org.apache.dubbo.rpc.listener;
+
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.RpcException;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class InjvmExporterListener extends ExporterListenerAdapter {
+
+ private final Map<String, ExporterChangeListener> exporterChangeListeners = new ConcurrentHashMap<>();
+
+ private final Map<String, Exporter<?>> exporters = new ConcurrentHashMap<>();
+
+ @Override
+ public void exported(Exporter<?> exporter) throws RpcException {
+ String serviceKey = exporter.getInvoker().getUrl().getServiceKey();
+ exporters.putIfAbsent(exporter.getInvoker().getUrl().getServiceKey(), exporter);
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] AlbumenJ commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "AlbumenJ (via GitHub)" <gi...@apache.org>.
AlbumenJ commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1477479084
Please update related docs in apache/dubbo-website
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] MieAh commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "MieAh (via GitHub)" <gi...@apache.org>.
MieAh commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1471729056
> LGTM.
>
> We can add some apis like `RpcContext.getServiceContext().setLocalInvoke(false)` to judge if use local invoker for each invocation.
You mean that we can provide such an api to change the calling behavior, right?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] AlbumenJ commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "AlbumenJ (via GitHub)" <gi...@apache.org>.
AlbumenJ commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1105336060
##########
dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java:
##########
@@ -420,8 +420,9 @@ private Map<String, String> appendConfig() {
@SuppressWarnings({"unchecked"})
private T createProxy(Map<String, String> referenceParameters) {
+ URL curUrl;
if (shouldJvmRefer(referenceParameters)) {
- createInvokerForLocal(referenceParameters);
+ curUrl = createInvokerForLocal(referenceParameters);
Review Comment:
Remove create local invoker here
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] sonarcloud[bot] commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "sonarcloud[bot] (via GitHub)" <gi...@apache.org>.
sonarcloud[bot] commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1466811642
Kudos, SonarCloud Quality Gate passed! [](https://sonarcloud.io/dashboard?id=apache_dubbo&pullRequest=11531)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY)
[](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [8 Code Smells](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list) [59.7% Coverage](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list) [2.9% Duplication](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] AlbumenJ commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "AlbumenJ (via GitHub)" <gi...@apache.org>.
AlbumenJ commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1466081353
@CrazyHZM @chickenlj PTAL
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] AlbumenJ commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "AlbumenJ (via GitHub)" <gi...@apache.org>.
AlbumenJ commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1123839147
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equals(getRegistryUrl().getProtocol())) {
+ isExported.compareAndSet(false, true);
+ injvmInvoker = invoker;
+ }
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension("injvm");
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ }
+
+ @Override
+ public URL getUrl() {
+ return directory.getConsumerUrl();
+ }
+
+ @Override
+ public URL getRegistryUrl() {
+ return directory.getUrl();
+ }
+
+ @Override
+ public Directory<T> getDirectory() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return directory.isDestroyed();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (injvmExporterListener == null) {
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension(LOCAL_PROTOCOL);
+ }
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ return isExported.get() || directory.isAvailable();
+ }
+
+ @Override
+ public void destroy() {
+ if (injvmExporterListener != null) {
+ injvmExporterListener.removeExporterChangeListener(getUrl().getServiceKey());
+ }
+ this.invoker.destroy();
+ }
+
+ @Override
+ public Class<T> getInterface() {
+ return directory.getInterface();
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ if (peer != null && peer) {
+ return invoker.invoke(invocation);
+ }
+ String scope = getUrl().getParameter(SCOPE_KEY);
+ if (shouldInvokeInjvm(getUrl().getParameter(LOCAL_PROTOCOL), scope)) {
+ return injvmInvoker.invoke(invocation);
+ }
+ return invoker.invoke(invocation);
+ }
+
+ private boolean shouldInvokeInjvm(String isInjvm, String scope) {
+ if (Boolean.TRUE.toString().equals(isInjvm)) {
Review Comment:
equalsIgnoreCase
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equals(getRegistryUrl().getProtocol())) {
+ isExported.compareAndSet(false, true);
+ injvmInvoker = invoker;
+ }
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension("injvm");
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ }
+
+ @Override
+ public URL getUrl() {
+ return directory.getConsumerUrl();
+ }
+
+ @Override
+ public URL getRegistryUrl() {
+ return directory.getUrl();
+ }
+
+ @Override
+ public Directory<T> getDirectory() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return directory.isDestroyed();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (injvmExporterListener == null) {
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension(LOCAL_PROTOCOL);
+ }
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ return isExported.get() || directory.isAvailable();
+ }
+
+ @Override
+ public void destroy() {
+ if (injvmExporterListener != null) {
+ injvmExporterListener.removeExporterChangeListener(getUrl().getServiceKey());
+ }
+ this.invoker.destroy();
+ }
+
+ @Override
+ public Class<T> getInterface() {
+ return directory.getInterface();
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ if (peer != null && peer) {
+ return invoker.invoke(invocation);
+ }
+ String scope = getUrl().getParameter(SCOPE_KEY);
+ if (shouldInvokeInjvm(getUrl().getParameter(LOCAL_PROTOCOL), scope)) {
+ return injvmInvoker.invoke(invocation);
+ }
+ return invoker.invoke(invocation);
+ }
+
+ private boolean shouldInvokeInjvm(String isInjvm, String scope) {
+ if (Boolean.TRUE.toString().equals(isInjvm)) {
+ return isInjvmExported(scope);
+ } else if (isInjvm == null) {
+ return isInjvmExportedAndNotRemoteOrGeneric(scope);
+ }
+ return false;
+ }
+
+ private boolean isInjvmExportedAndNotRemoteOrGeneric(String scope) {
+ return !SCOPE_REMOTE.equalsIgnoreCase(scope) &&
+ !getUrl().getParameter(GENERIC_KEY, false) && isInjvmExported(scope);
+ }
+
+ private boolean isInjvmExported(String scope) {
+ if (!isExported.get() && SCOPE_LOCAL.equalsIgnoreCase(scope)) {
+ throw new RpcException("Local service has not been exposed yet!");
+ }
+ return isExported.get();
+ }
+
+
+ private Invoker<T> createInjvmInvoker() {
+ URL url = new ServiceConfigURL(LOCAL_PROTOCOL, NetUtils.getLocalHost(), getUrl().getPort(), getInterface().getName(), getUrl().getParameters());
+ url = url.setScopeModel(getUrl().getScopeModel());
+ url = url.setServiceModel(getUrl().getServiceModel());
+ return protocolSPI.refer(getInterface(), url);
+ }
+
+ @Override
+ public void onExporterChangeExport(Exporter<?> exporter) {
+ if (isExported.get()) {
+ return;
+ }
+ if (getUrl().getServiceKey().equals(exporter.getInvoker().getUrl().getServiceKey())
+ && exporter.getInvoker().getUrl().getProtocol().equals(LOCAL_PROTOCOL)) {
+ isExported.compareAndSet(false, true);
+ }
+ if (isExported.get() && injvmInvoker == null) {
+ if (injvmInvoker == null) {
+ synchronized (createLock) {
+ if (injvmInvoker == null) {
+ injvmInvoker = createInjvmInvoker();
+ }
+ }
+ }
+ }
Review Comment:
这里的时序问题可能导致 invoke 的时候 NPE
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equals(getRegistryUrl().getProtocol())) {
+ isExported.compareAndSet(false, true);
+ injvmInvoker = invoker;
+ }
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension("injvm");
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ }
+
+ @Override
+ public URL getUrl() {
+ return directory.getConsumerUrl();
+ }
+
+ @Override
+ public URL getRegistryUrl() {
+ return directory.getUrl();
+ }
+
+ @Override
+ public Directory<T> getDirectory() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return directory.isDestroyed();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (injvmExporterListener == null) {
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension(LOCAL_PROTOCOL);
+ }
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ return isExported.get() || directory.isAvailable();
+ }
+
+ @Override
+ public void destroy() {
+ if (injvmExporterListener != null) {
+ injvmExporterListener.removeExporterChangeListener(getUrl().getServiceKey());
+ }
+ this.invoker.destroy();
+ }
+
+ @Override
+ public Class<T> getInterface() {
+ return directory.getInterface();
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ if (peer != null && peer) {
+ return invoker.invoke(invocation);
+ }
+ String scope = getUrl().getParameter(SCOPE_KEY);
+ if (shouldInvokeInjvm(getUrl().getParameter(LOCAL_PROTOCOL), scope)) {
Review Comment:
`peer`, `scope` 和 `local` 这几个 key 的判断是不是可以提前到 init 做
##########
dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/InjvmExporterListener.java:
##########
@@ -0,0 +1,66 @@
+/*
+ * 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 org.apache.dubbo.rpc.listener;
+
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.RpcException;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class InjvmExporterListener extends ExporterListenerAdapter {
+
+ private final Map<String, ExporterChangeListener> exporterChangeListeners = new ConcurrentHashMap<>();
+
+ private final Map<String, Exporter<?>> exporters = new ConcurrentHashMap<>();
+
+ @Override
+ public void exported(Exporter<?> exporter) throws RpcException {
+ String serviceKey = exporter.getInvoker().getUrl().getServiceKey();
+ exporters.putIfAbsent(exporter.getInvoker().getUrl().getServiceKey(), exporter);
Review Comment:
需要考虑同一个服务多订阅的情况
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equals(getRegistryUrl().getProtocol())) {
+ isExported.compareAndSet(false, true);
+ injvmInvoker = invoker;
+ }
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension("injvm");
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ }
+
+ @Override
+ public URL getUrl() {
+ return directory.getConsumerUrl();
+ }
+
+ @Override
+ public URL getRegistryUrl() {
+ return directory.getUrl();
+ }
+
+ @Override
+ public Directory<T> getDirectory() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return directory.isDestroyed();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (injvmExporterListener == null) {
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension(LOCAL_PROTOCOL);
+ }
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ return isExported.get() || directory.isAvailable();
+ }
+
+ @Override
+ public void destroy() {
+ if (injvmExporterListener != null) {
+ injvmExporterListener.removeExporterChangeListener(getUrl().getServiceKey());
+ }
+ this.invoker.destroy();
+ }
+
+ @Override
+ public Class<T> getInterface() {
+ return directory.getInterface();
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ if (peer != null && peer) {
+ return invoker.invoke(invocation);
+ }
+ String scope = getUrl().getParameter(SCOPE_KEY);
+ if (shouldInvokeInjvm(getUrl().getParameter(LOCAL_PROTOCOL), scope)) {
+ return injvmInvoker.invoke(invocation);
+ }
+ return invoker.invoke(invocation);
+ }
+
+ private boolean shouldInvokeInjvm(String isInjvm, String scope) {
+ if (Boolean.TRUE.toString().equals(isInjvm)) {
+ return isInjvmExported(scope);
+ } else if (isInjvm == null) {
+ return isInjvmExportedAndNotRemoteOrGeneric(scope);
+ }
+ return false;
+ }
+
+ private boolean isInjvmExportedAndNotRemoteOrGeneric(String scope) {
+ return !SCOPE_REMOTE.equalsIgnoreCase(scope) &&
+ !getUrl().getParameter(GENERIC_KEY, false) && isInjvmExported(scope);
+ }
+
+ private boolean isInjvmExported(String scope) {
+ if (!isExported.get() && SCOPE_LOCAL.equalsIgnoreCase(scope)) {
+ throw new RpcException("Local service has not been exposed yet!");
+ }
+ return isExported.get();
+ }
+
+
+ private Invoker<T> createInjvmInvoker() {
+ URL url = new ServiceConfigURL(LOCAL_PROTOCOL, NetUtils.getLocalHost(), getUrl().getPort(), getInterface().getName(), getUrl().getParameters());
+ url = url.setScopeModel(getUrl().getScopeModel());
+ url = url.setServiceModel(getUrl().getServiceModel());
+ return protocolSPI.refer(getInterface(), url);
+ }
+
+ @Override
+ public void onExporterChangeExport(Exporter<?> exporter) {
+ if (isExported.get()) {
+ return;
+ }
+ if (getUrl().getServiceKey().equals(exporter.getInvoker().getUrl().getServiceKey())
+ && exporter.getInvoker().getUrl().getProtocol().equals(LOCAL_PROTOCOL)) {
+ isExported.compareAndSet(false, true);
+ }
+ if (isExported.get() && injvmInvoker == null) {
+ if (injvmInvoker == null) {
+ synchronized (createLock) {
+ if (injvmInvoker == null) {
+ injvmInvoker = createInjvmInvoker();
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onExporterChangeUnExport(Exporter<?> exporter) {
+ if (getUrl().getServiceKey().equals(exporter.getInvoker().getUrl().getServiceKey())
+ && exporter.getInvoker().getUrl().getProtocol().equals(LOCAL_PROTOCOL)) {
+ isExported.compareAndSet(true, false);
Review Comment:
需要销毁已有的 injvmInvoker
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] AlbumenJ commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "AlbumenJ (via GitHub)" <gi...@apache.org>.
AlbumenJ commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1459982416

Please fix failed test cases
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] sonarcloud[bot] commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "sonarcloud[bot] (via GitHub)" <gi...@apache.org>.
sonarcloud[bot] commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1464818105
SonarCloud Quality Gate failed. [](https://sonarcloud.io/dashboard?id=apache_dubbo&pullRequest=11531)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [3 Bugs](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY)
[](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list) [56.9% Coverage](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list) [3.2% Duplication](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] MieAh commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "MieAh (via GitHub)" <gi...@apache.org>.
MieAh commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1139914803
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,213 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.Cluster;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private boolean peerFlag;
+
+ private boolean injvmFlag;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ String isInjvm = getUrl().getParameter(LOCAL_PROTOCOL);
+ if (peer != null && peer) {
+ peerFlag = true;
+ return;
+ }
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equalsIgnoreCase(getRegistryUrl().getProtocol())) {
+ injvmInvoker = invoker;
+ isExported.compareAndSet(false, true);
+ injvmFlag = true;
+ return;
+ }
+ if (Boolean.TRUE.toString().equalsIgnoreCase(isInjvm) || LOCAL_KEY.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY))) {
+ injvmFlag = true;
+ } else if (isInjvm == null) {
+ injvmFlag = isNotRemoteOrGeneric();
+ }
+
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = getUrl().getOrDefaultFrameworkModel().getBeanFactory().getBean(InjvmExporterListener.class);
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ }
+
+ @Override
+ public URL getUrl() {
+ return directory.getConsumerUrl();
+ }
+
+ @Override
+ public URL getRegistryUrl() {
+ return directory.getUrl();
+ }
+
+ @Override
+ public Directory<T> getDirectory() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return directory.isDestroyed();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return isExported.get() || directory.isAvailable();
+ }
+
+ @Override
+ public void destroy() {
+ if (injvmExporterListener != null) {
+ injvmExporterListener.removeExporterChangeListener(this, getUrl().getServiceKey());
+ }
+ destroyInjvmInvoker();
+ this.invoker.destroy();
+ }
+
+ @Override
+ public Class<T> getInterface() {
+ return directory.getInterface();
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ if (peerFlag) {
+ return invoker.invoke(invocation);
+ }
+ if (isInjvmExported() && injvmFlag) {
+ return injvmInvoker.invoke(invocation);
+ }
+ return invoker.invoke(invocation);
+ }
+
+ private boolean isNotRemoteOrGeneric() {
+ return !SCOPE_REMOTE.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY)) &&
+ !getUrl().getParameter(GENERIC_KEY, false);
+ }
+
+ private boolean isInjvmExported() {
+ Boolean localInvoke = RpcContext.getServiceContext().getLocalInvoke();
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] sonarcloud[bot] commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "sonarcloud[bot] (via GitHub)" <gi...@apache.org>.
sonarcloud[bot] commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1474336335
Kudos, SonarCloud Quality Gate passed! [](https://sonarcloud.io/dashboard?id=apache_dubbo&pullRequest=11531)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY)
[](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [9 Code Smells](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list) [58.1% Coverage](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list) [2.8% Duplication](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] AlbumenJ commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "AlbumenJ (via GitHub)" <gi...@apache.org>.
AlbumenJ commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1139767783
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,213 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.Cluster;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private boolean peerFlag;
+
+ private boolean injvmFlag;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ String isInjvm = getUrl().getParameter(LOCAL_PROTOCOL);
+ if (peer != null && peer) {
+ peerFlag = true;
+ return;
+ }
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equalsIgnoreCase(getRegistryUrl().getProtocol())) {
+ injvmInvoker = invoker;
+ isExported.compareAndSet(false, true);
+ injvmFlag = true;
+ return;
+ }
+ if (Boolean.TRUE.toString().equalsIgnoreCase(isInjvm) || LOCAL_KEY.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY))) {
+ injvmFlag = true;
+ } else if (isInjvm == null) {
+ injvmFlag = isNotRemoteOrGeneric();
+ }
+
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = getUrl().getOrDefaultFrameworkModel().getBeanFactory().getBean(InjvmExporterListener.class);
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ }
+
+ @Override
+ public URL getUrl() {
+ return directory.getConsumerUrl();
+ }
+
+ @Override
+ public URL getRegistryUrl() {
+ return directory.getUrl();
+ }
+
+ @Override
+ public Directory<T> getDirectory() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return directory.isDestroyed();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return isExported.get() || directory.isAvailable();
+ }
+
+ @Override
+ public void destroy() {
+ if (injvmExporterListener != null) {
+ injvmExporterListener.removeExporterChangeListener(this, getUrl().getServiceKey());
+ }
+ destroyInjvmInvoker();
+ this.invoker.destroy();
+ }
+
+ @Override
+ public Class<T> getInterface() {
+ return directory.getInterface();
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ if (peerFlag) {
+ return invoker.invoke(invocation);
+ }
+ if (isInjvmExported() && injvmFlag) {
+ return injvmInvoker.invoke(invocation);
+ }
+ return invoker.invoke(invocation);
+ }
+
+ private boolean isNotRemoteOrGeneric() {
+ return !SCOPE_REMOTE.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY)) &&
+ !getUrl().getParameter(GENERIC_KEY, false);
+ }
+
+ private boolean isInjvmExported() {
+ Boolean localInvoke = RpcContext.getServiceContext().getLocalInvoke();
Review Comment:
`RpcContext.getServiceContext().getLocalInvoke()` here should only effect **one** invocation.
If `null`, ignore.
If `false`, force remote.
If `true`, force local.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] sonarcloud[bot] commented on pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "sonarcloud[bot] (via GitHub)" <gi...@apache.org>.
sonarcloud[bot] commented on PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#issuecomment-1465125689
SonarCloud Quality Gate failed. [](https://sonarcloud.io/dashboard?id=apache_dubbo&pullRequest=11531)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG) [2 Bugs](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=BUG)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=VULNERABILITY)
[](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_dubbo&pullRequest=11531&resolved=false&types=SECURITY_HOTSPOT)
[](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL) [6 Code Smells](https://sonarcloud.io/project/issues?id=apache_dubbo&pullRequest=11531&resolved=false&types=CODE_SMELL)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list) [58.2% Coverage](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_coverage&view=list)
[](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list) [3.2% Duplication](https://sonarcloud.io/component_measures?id=apache_dubbo&pullRequest=11531&metric=new_duplicated_lines_density&view=list)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org
[GitHub] [dubbo] MieAh commented on a diff in pull request #11531: Support choose local invoke in runtime instead of startup
Posted by "MieAh (via GitHub)" <gi...@apache.org>.
MieAh commented on code in PR #11531:
URL: https://github.com/apache/dubbo/pull/11531#discussion_r1124068381
##########
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java:
##########
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.listener.ExporterChangeListener;
+import org.apache.dubbo.rpc.listener.InjvmExporterListener;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
+
+/**
+ * A ClusterInvoker that selects between local and remote invokers at runtime.
+ */
+public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChangeListener {
+
+ private Protocol protocolSPI;
+ private final Directory<T> directory;
+ private final Invoker<T> invoker;
+ private final AtomicBoolean isExported;
+ private volatile Invoker<T> injvmInvoker;
+ private volatile InjvmExporterListener injvmExporterListener;
+
+ private final Object createLock = new Object();
+
+
+ public ScopeClusterInvoker(Directory<T> directory, Invoker<T> invoker) {
+ this.directory = directory;
+ this.invoker = invoker;
+ this.isExported = new AtomicBoolean(false);
+ init();
+ }
+
+ private void init() {
+ if (injvmInvoker == null && LOCAL_PROTOCOL.equals(getRegistryUrl().getProtocol())) {
+ isExported.compareAndSet(false, true);
+ injvmInvoker = invoker;
+ }
+ protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension("injvm");
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ }
+
+ @Override
+ public URL getUrl() {
+ return directory.getConsumerUrl();
+ }
+
+ @Override
+ public URL getRegistryUrl() {
+ return directory.getUrl();
+ }
+
+ @Override
+ public Directory<T> getDirectory() {
+ return directory;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return directory.isDestroyed();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (injvmExporterListener == null) {
+ injvmExporterListener = (InjvmExporterListener) getUrl().getApplicationModel().getExtensionLoader(ExporterListener.class).getExtension(LOCAL_PROTOCOL);
+ }
+ injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey());
+ return isExported.get() || directory.isAvailable();
+ }
+
+ @Override
+ public void destroy() {
+ if (injvmExporterListener != null) {
+ injvmExporterListener.removeExporterChangeListener(getUrl().getServiceKey());
+ }
+ this.invoker.destroy();
+ }
+
+ @Override
+ public Class<T> getInterface() {
+ return directory.getInterface();
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY);
+ if (peer != null && peer) {
+ return invoker.invoke(invocation);
+ }
+ String scope = getUrl().getParameter(SCOPE_KEY);
+ if (shouldInvokeInjvm(getUrl().getParameter(LOCAL_PROTOCOL), scope)) {
+ return injvmInvoker.invoke(invocation);
+ }
+ return invoker.invoke(invocation);
+ }
+
+ private boolean shouldInvokeInjvm(String isInjvm, String scope) {
+ if (Boolean.TRUE.toString().equals(isInjvm)) {
+ return isInjvmExported(scope);
+ } else if (isInjvm == null) {
+ return isInjvmExportedAndNotRemoteOrGeneric(scope);
+ }
+ return false;
+ }
+
+ private boolean isInjvmExportedAndNotRemoteOrGeneric(String scope) {
+ return !SCOPE_REMOTE.equalsIgnoreCase(scope) &&
+ !getUrl().getParameter(GENERIC_KEY, false) && isInjvmExported(scope);
+ }
+
+ private boolean isInjvmExported(String scope) {
+ if (!isExported.get() && SCOPE_LOCAL.equalsIgnoreCase(scope)) {
+ throw new RpcException("Local service has not been exposed yet!");
+ }
+ return isExported.get();
+ }
+
+
+ private Invoker<T> createInjvmInvoker() {
+ URL url = new ServiceConfigURL(LOCAL_PROTOCOL, NetUtils.getLocalHost(), getUrl().getPort(), getInterface().getName(), getUrl().getParameters());
+ url = url.setScopeModel(getUrl().getScopeModel());
+ url = url.setServiceModel(getUrl().getServiceModel());
+ return protocolSPI.refer(getInterface(), url);
+ }
+
+ @Override
+ public void onExporterChangeExport(Exporter<?> exporter) {
+ if (isExported.get()) {
+ return;
+ }
+ if (getUrl().getServiceKey().equals(exporter.getInvoker().getUrl().getServiceKey())
+ && exporter.getInvoker().getUrl().getProtocol().equals(LOCAL_PROTOCOL)) {
+ isExported.compareAndSet(false, true);
+ }
+ if (isExported.get() && injvmInvoker == null) {
+ if (injvmInvoker == null) {
+ synchronized (createLock) {
+ if (injvmInvoker == null) {
+ injvmInvoker = createInjvmInvoker();
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onExporterChangeUnExport(Exporter<?> exporter) {
+ if (getUrl().getServiceKey().equals(exporter.getInvoker().getUrl().getServiceKey())
+ && exporter.getInvoker().getUrl().getProtocol().equals(LOCAL_PROTOCOL)) {
+ isExported.compareAndSet(true, false);
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org