This is an automated email from the ASF dual-hosted git repository.

jerrick pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo-website.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 8142ed0  add dubbo-invoke (#91)
8142ed0 is described below

commit 8142ed0abdc00b7f1a67e66bc09b2d4ecf211405
Author: Zoe-Hou <137178...@qq.com>
AuthorDate: Wed Aug 15 11:52:56 2018 +0800

    add dubbo-invoke (#91)
---
 blog/en-us/dubbo-invoke.md               | 216 +++++++++++++++++++++++++++++++
 blog/zh-cn/dubbo-invoke.md               |  12 +-
 docs/zh-cn/user/demos/logger-strategy.md |  16 +--
 docs/zh-cn/user/demos/static-service.md  |   2 +-
 4 files changed, 231 insertions(+), 15 deletions(-)

diff --git a/blog/en-us/dubbo-invoke.md b/blog/en-us/dubbo-invoke.md
new file mode 100644
index 0000000..ab51e2d
--- /dev/null
+++ b/blog/en-us/dubbo-invoke.md
@@ -0,0 +1,216 @@
+
+# Dubbo: Several ways about synchronous/asynchronous invoke
+
+As we all know,Dubbo adopts a single large join protocol by default and takes 
the NIO asynchronous communication mechanism of Netty as the low-level 
implementation. Based on this mechanism, Dubbo implements several invocation 
modes as follows:
+
+* synchronous invoke
+* asynchronous invoke
+* parameters callback
+* event notification
+
+### Synchronous invoke
+
+Synchronous invoke is a kind of blocking invocation mode, that is the Consumer 
keeps blocking and waiting, until the Provider returns.
+
+Generally, a typical synchronous invocation process is as follows:
+
+1. Consumer service thread invokes the remote API and sends requests to the 
Provider. Meanwhile, the current service thread stays in blocking state;
+2. Provider process relative request after receiving it from Consumer. Then 
returns the results to Consumer;
+3. After Consumer receiving results, the current thread continues to execute.
+
+Here are two problems:
+
+1. How does Consumer service thread turn into `blocking` state?
+2. How does the service thread be awaked to execute after Consumer receiving 
results?
+
+In fact, the low-level I/O operations of Dubbo are all asynchronous. The 
Consumer gets a Future object after invoking the Provider. For synchronous 
invoke, the service thread takes advantage of `Future#get(timeout)` to block 
and wait for Provider returning results, with the 'timeout' indicating the 
timeout defined by Consumer. When the result returns, the Future will be set 
and the blocked service thread will be awaked. The service thread will return 
an exception if there is no result af [...]
+
+### Asynchronous invoke
+
+For scenarios that Provider has a long response time, it's necessary to 
implement asynchronous invoke based on Dubbo's underlying asynchronous NIO. It 
could utilize the resource of Consumer effectively, and costs less than using 
multi-thread for Consumer.
+
+Asynchronous invoke does not need specific configuration for Provider. In the 
example,the API of Provider is defined as follow:
+
+```java
+public interface AsyncService {
+    String goodbye(String name);
+}
+```
+
+##### Consumer configuration
+
+```xml
+<dubbo:reference id="asyncService" 
interface="com.alibaba.dubbo.samples.async.api.AsyncService">
+    <dubbo:method name="goodbye" async="true"/>
+</dubbo:reference>
+```
+
+Notice that if we need an asynchronous revoke method, we must use 
`<dubbo:method/>` label to describe it.
+
+##### Consumer triggers invocation
+
+```java
+AsyncService service = ...;
+String result = service.goodbye("samples");// returns NULL and DO NOT use!
+Future<String> future = RpcContext.getContext().getFuture();
+... // other service thread logic
+result = future.get(); // could use get(timeout, unit) to configure timeout, 
when it needs to get the asynchronous result
+```
+
+After Dubbo Consumer triggers invocation, it uses 
`RpcContext.getContext().getFuture()` to get the relative `Future` object, and 
then it could start executing other tasks. Anytime when we need results, 
`future.get(timeout)` is supposed to be called.
+
+Under several special conditions, it could be set whether to wait for sending 
the request, to accelerate the return of invocation:
+
+* `sent="true"` Waiting for sending the request, and return an exception if it 
fails;
+* `sent="false"` Do not wait for the request, and returns immediately after 
putting the request to the I/O queue.
+
+We set it to `false` by default. And detailed configuration is as follows:
+
+```xml
+<dubbo:method name="goodbye" async="true" sent="true" />
+```
+
+If you only want to be asynchronous, then omit the result thoroughly, 
`return="false"` could be set to reduce the creation and management cost of 
Future:
+
+```xml
+<dubbo:method name="goodbye" async="true" return="false"/>
+```
+
+At this time,`RpcContext.getContext().getFuture()` will return `null`。
+
+The complete sequence diagram of asynchronous invoke is as follow:
+
+![Asynchronous invoke](../../img/blog/dubbo-async.svg)
+
+The sample locates 
at:https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-async
+
+### Parameters callback
+
+The parameter Callback is somewhat similar to the local Callback mechanism, 
but Callback is not an inner class or interface of Dubbo. Instead, it is 
defined by the Provider. Dubbo will generate a reverse proxy based on the long 
connection, so as to implement the logic of calling the Consumer from the 
Provider.
+
+##### Service and Callback definition of Provider
+
+```java
+public interface CallbackService {
+    void addListener(String key, CallbackListener listener);
+}
+
+public interface CallbackListener {
+    void changed(String msg);
+}
+```
+
+##### Service implementation of Provider
+
+```java
+public class CallbackServiceImpl implements CallbackService {
+
+    private final Map<String, CallbackListener> listeners = new 
ConcurrentHashMap<String, CallbackListener>();
+
+    public CallbackServiceImpl() {
+        Thread t = new Thread(new Runnable() {
+            public void run() {
+                while (true) {
+                    try {
+                        for (Map.Entry<String, CallbackListener> entry : 
listeners.entrySet()) {
+                            try {
+                                
entry.getValue().changed(getChanged(entry.getKey()));
+                            } catch (Throwable t) {
+                                listeners.remove(entry.getKey());
+                            }
+                        }
+                        Thread.sleep(5000); // timely trigger change event
+                    } catch (Throwable t) {
+                        t.printStackTrace();
+                    }
+                }
+            }
+        });
+        t.setDaemon(true);
+        t.start();
+    }
+
+    public void addListener(String key, CallbackListener listener) {
+        listeners.put(key, listener);
+        listener.changed(getChanged(key)); // send notification for change
+    }
+
+    private String getChanged(String key) {
+        return "Changed: " + new SimpleDateFormat("yyyy-MM-dd 
HH:mm:ss").format(new Date());
+    }
+}
+```
+
+##### Service exposure of Provider
+
+```xml
+<bean id="callbackService" 
class="com.alibaba.dubbo.samples.callback.impl.CallbackServiceImpl"/>
+
+<dubbo:service 
interface="com.alibaba.dubbo.samples.callback.api.CallbackService" 
ref="callbackService" connections="1" callbacks="1000">
+    <dubbo:method name="addListener">
+        <dubbo:argument index="1" callback="true"/>
+        <!--<dubbo:argument type="com.demo.CallbackListener" callback="true" 
/>-->
+    </dubbo:method>
+</dubbo:service>
+```
+
+Here,Provider needs to declare which parameter is the Callback parameter in 
the method.
+
+##### Callback interface implementation of Consumer
+
+```java
+CallbackService callbackService = ...;
+callbackService.addListener("foo.bar", new CallbackListener() {
+        public void changed(String msg) {
+            System.out.println("callback1:" + msg);
+        }
+});
+```
+
+The implementation class of the Callback interface is on the Consumer, which 
automatically exports a Callback service when the method is called. Thus during 
Provider processing the call, if the parameter is determined as Callback, it 
will generate a proxy. Therefore, when the service implementation class calling 
the Callback method, it will be passed to the Consumer to execute the code.
+
+The sample code above is located 
at:https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-callback
+
+This invocation mode is somewhat like message publishing and subscribing, but 
there is a little difference. For example, when the Consumer completes the 
export of Callback service, if it restarts later, then the Provider will fail 
to adjust. Meanwhile it is also a problem for the Provider to clean up the 
proxy.
+
+### Event notification
+
+Event notification allows the Consumer triggering three events,particularly 
`oninvoke`, `onreturn`, `onthrow` before calling, after calling or occurring 
exceptions.
+
+You can specify which events need to be notified during configuring Consumer, 
such as:
+
+```xml
+<bean id="demoCallback" 
class="com.alibaba.dubbo.samples.notify.impl.NotifyImpl" />
+
+<dubbo:reference id="demoService" check="false" 
interface="com.alibaba.dubbo.samples.notify.api.DemoService" version="1.0.0" 
group="cn">
+    <dubbo:method name="sayHello" onreturn="demoCallback.onreturn" 
onthrow="demoCallback.onthrow"/>
+</dubbo:reference>
+```
+
+Among them,the code of NotifyImpl is as follow:
+
+```java
+public class NotifyImpl implements Notify{
+
+    public Map<Integer, String> ret = new HashMap<Integer, String>();
+
+    public void onreturn(String name, int id) {
+        ret.put(id, name);
+        System.out.println("onreturn: " + name);
+    }
+
+    public void onthrow(Throwable ex, String name, int id) {
+        System.out.println("onthrow: " + name);
+    }
+}
+```
+
+Here we address that the parameter rules of three methods in the custom Notify 
interface are as follows:
+
+* `oninvoke` method's parameters are the same as the calling method parameters;
+* `onreturn` method's first parameter is the returned value of calling 
method,and the others are the same as the calling method;
+* `onthrow` method's first parameter is an invoked exception,and the others 
are the same as the calling method.
+
+In the above configuration, `sayHello` method is an asynchronous invocation, 
so the execution of event notification method is also synchronous. You can 
configure the `async = true` to make method invocation asynchronous, at this 
moment, event notification method is executed asynchronously. Especially 
emphasize that `oninvoke` method is executed synchronously, whether is an 
asynchronous call or not.
+
+Please refer to the sample code for event 
notification:https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-notify
\ No newline at end of file
diff --git a/blog/zh-cn/dubbo-invoke.md b/blog/zh-cn/dubbo-invoke.md
index 16aa78e..01568f3 100644
--- a/blog/zh-cn/dubbo-invoke.md
+++ b/blog/zh-cn/dubbo-invoke.md
@@ -20,7 +20,7 @@
 这里有 2 个问题:
 
 1. Consumer 业务线程是怎么进入`阻塞`状态的?
-2. Consumer 收到结果后,如果唤醒业务线程往后执行的?
+2. Consumer 收到结果后,如何唤醒业务线程往后执行的?
 
 其实,Dubbo 的底层 IO 操作都是异步的。Consumer 端发起调用后,得到一个 Future 
对象。对于同步调用,业务线程通过`Future#get(timeout)`,阻塞等待 Provider 端将结果返回;`timeout`则是 Consumer 
端定义的超时时间。当结果返回后,会设置到此 Future,并唤醒阻塞的业务线程;当超时时间到结果还未返回时,业务线程将会异常返回。
 
@@ -63,13 +63,13 @@ Dubbo Consumer 端发起调用后,同时通过`RpcContext.getContext().getFutu
 * `sent="true"` 等待消息发出,消息发送失败将抛出异常;
 * `sent="false"` 不等待消息发出,将消息放入 IO 队列,即刻返回。
 
-默认为`fase`。配置方式如下:
+默认为`false`。配置方式如下:
 
 ```xml
 <dubbo:method name="goodbye" async="true" sent="true" />
 ```
 
-如果你只是想异步,完全忽略返回值,可以配置 `return="false"`,以减少 Future 对象的创建和管理成本:
+如果你只是想异步,完全忽略返回值,可以配置 `return="false"`,以减少 Future 对象的创建和管理成本:
 
 ```xml
 <dubbo:method name="goodbye" async="true" return="false"/>
@@ -168,13 +168,13 @@ callbackService.addListener("foo.bar", new 
CallbackListener() {
 
 Callback 接口的实现类在 Consumer 端,当方法发生调用时,Consumer 端会自动 export 一个 Callback 服务。而 
Provider 端在处理调用时,判断如果参数是 Callback,则生成了一个 proxy,因此服务实现类里在调用 Callback 方法的时候,会被传递到 
Consumer 端执行 Callback 实现类的代码。
 
-上述示例代码位于:此示例代码位于:https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-callback
+上述示例代码位于:https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-callback
 
 这种调用方式有点像消息的发布和订阅,但又有区别。比如当 Consumer 端 完成了Callback 服务的 export 后,如果后续重启了,这时 
Provider 端就会调不通;同时 Provider 端如何清理掉这个 proxy 也是一个问题。
 
 ### 事件通知
 
-事件通知允许 Consumer 端在调用之前、调用正常返回之后或调用出现异常时,触发 `oninvoke`、`onreturn`、`onthrow` 
三个事件。
+事件通知允许 Consumer 端在调用之前、调用之后或出现异常时,触发 `oninvoke`、`onreturn`、`onthrow` 三个事件。
 
 可以通过在配置 Consumer 时,指定事件需要通知的方法,如:
 
@@ -212,4 +212,4 @@ public class NotifyImpl implements Notify{
 
 上述配置中,`sayHello`方法为同步调用,因此事件通知方法的执行也是同步执行。可以配置 
`async=true`让方法调用为异步,这时事件通知的方法也是异步执行的。特别强调一下,`oninvoke`方法不管是否异步调用,都是同步执行的。
 
-事件通知的示例代码请参考:https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-notify
+事件通知的示例代码请参考:https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-notify
\ No newline at end of file
diff --git a/docs/zh-cn/user/demos/logger-strategy.md 
b/docs/zh-cn/user/demos/logger-strategy.md
index ccc6111..f3050b9 100644
--- a/docs/zh-cn/user/demos/logger-strategy.md
+++ b/docs/zh-cn/user/demos/logger-strategy.md
@@ -1,23 +1,23 @@
 # 日志适配
 
-自 `2.2.1` 开始,dubbo 开始内置 log4j、slf4j、jcl、jdk 这些日志框架的适配 [^1],也可以通过以下方式显示配置日志输出策略:
+自 `2.2.1` 开始,dubbo 开始内置 log4j、slf4j、jcl、jdk 这些日志框架的适配[1],也可以通过以下方式显示配置日志输出策略:
 
 0. 命令行
 
     ```sh
-java -Ddubbo.application.logger=log4j
-```
+      java -Ddubbo.application.logger=log4j
+    ```
 
 0. 在 `dubbo.properties` 中指定
 
     ```
-dubbo.application.logger=log4j
-```
+      dubbo.application.logger=log4j
+    ```
 
 0. 在 `dubbo.xml` 中配置
 
     ```xml
-<dubbo:application logger="log4j" />
-```
+      <dubbo:application logger="log4j" />
+    ```
 
-[^1]: 
自定义扩展可以参考[日志适配扩展](http://dubbo.apache.org/books/dubbo-dev-book/impls/logger-adapter.html)
+[1]: 自定义扩展可以参考 
[日志适配扩展](http://dubbo.apache.org/books/dubbo-dev-book/impls/logger-adapter.html)
\ No newline at end of file
diff --git a/docs/zh-cn/user/demos/static-service.md 
b/docs/zh-cn/user/demos/static-service.md
index 7814b66..9b3b570 100644
--- a/docs/zh-cn/user/demos/static-service.md
+++ b/docs/zh-cn/user/demos/static-service.md
@@ -14,7 +14,7 @@
 
 服务提供者初次注册时为禁用状态,需人工启用。断线时,将不会被自动删除,需人工禁用。
 
-如果是一个第三方独立提供者,比如 memcached,可以直接向注册中心写入提供者地址信息,消费者正常使用 [^1]:
+如果是一个第三方服务提供者,比如 memcached,可以直接向注册中心写入提供者地址信息,消费者正常使用 [^1]:
 
 ```java
 RegistryFactory registryFactory = 
ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();

Reply via email to