You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2022/12/25 16:32:18 UTC
[dubbo-go-samples] branch master updated: async rpc samples (#479)
This is an automated email from the ASF dual-hosted git repository.
alexstocks pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-go-samples.git
The following commit(s) were added to refs/heads/master by this push:
new df89852d async rpc samples (#479)
df89852d is described below
commit df89852dbba4a3e66f34a08a1443b7e2b80cf3dd
Author: Wenkang Huang <52...@users.noreply.github.com>
AuthorDate: Mon Dec 26 00:32:14 2022 +0800
async rpc samples (#479)
Co-authored-by: huangwenkang <64...@qq>
---
async/README.md | 16 +++++
async/README_zh.md | 14 ++++
async/go-client/cmd/client.go | 84 ++++++++++++++++++++++++
async/go-client/conf/dubbogo.yml | 17 +++++
async/go-client/pkg/user.go | 113 ++++++++++++++++++++++++++++++++
async/go-server/cmd/server.go | 84 ++++++++++++++++++++++++
async/go-server/conf/dubbogo.yml | 18 +++++
async/go-server/pkg/user.go | 109 ++++++++++++++++++++++++++++++
async/go-server/pkg/user_provider.go | 49 ++++++++++++++
async/go-server/pkg/user_provider_v2.go | 33 ++++++++++
10 files changed, 537 insertions(+)
diff --git a/async/README.md b/async/README.md
new file mode 100644
index 00000000..7ade4ee5
--- /dev/null
+++ b/async/README.md
@@ -0,0 +1,16 @@
+# Async RPC Dubbo for Dubbo-go
+
+For api definition and go client and server startup, please refer to [dubbo-go 3.0 quickstart](https://dubbogo.github.io/zh-cn/docs/user/quickstart/3.0/quickstart.html)
+
+## Instructions
+### 1. Start zookeeper
+Execute the command `docker run --rm -p 2181:2181 zookeeper` or `make -f $DUBBO_GO_SAMPLES_ROOT_PATH/build/Makefile docker-up`.
+ If you choose the second way, please ensure that you have set the environment $DUBBO_GO_SAMPLES_ROOT_PATH.
+
+### 2. Start the server
+
+Use goland to start async/go-server/cmd/server.go
+
+### 3. Start the client
+
+Use goland to start async/go-client/cmd/client.go
\ No newline at end of file
diff --git a/async/README_zh.md b/async/README_zh.md
new file mode 100644
index 00000000..c538649e
--- /dev/null
+++ b/async/README_zh.md
@@ -0,0 +1,14 @@
+# 异步 RPC Dubbo for Dubbo-go 3.0
+
+api 定义以及 go 客户端、服务端启动,可以参考 [dubbo-go 3.0 快速开始](https://dubbogo.github.io/zh-cn/docs/user/quickstart/3.0/quickstart.html)
+
+## 使用方法
+1. 启动 zookeeper
+
+2. 启动服务端
+
+使用 goland 启动 async/go-server/cmd/server.go
+
+3. 启动客户端
+
+使用 goland 启动 async/go-client/com/client.go
diff --git a/async/go-client/cmd/client.go b/async/go-client/cmd/client.go
new file mode 100644
index 00000000..40a49659
--- /dev/null
+++ b/async/go-client/cmd/client.go
@@ -0,0 +1,84 @@
+/*
+ * 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 main
+
+import (
+ "context"
+ "time"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/config"
+ _ "dubbo.apache.org/dubbo-go/v3/imports"
+
+ hessian "github.com/apache/dubbo-go-hessian2"
+
+ "github.com/dubbogo/gost/log/logger"
+)
+
+import (
+ "github.com/apache/dubbo-go-samples/async/go-client/pkg"
+)
+
+var (
+ userProvider = &pkg.UserProvider{}
+ userProviderV2 = &pkg.UserProviderV2{}
+)
+
+// need to setup environment variable "DUBBO_GO_CONFIG_PATH" to "conf/dubbogo.yml" before run
+func main() {
+ hessian.RegisterJavaEnum(pkg.MAN)
+ hessian.RegisterJavaEnum(pkg.WOMAN)
+ hessian.RegisterPOJO(&pkg.User{})
+
+ config.SetConsumerService(userProvider)
+ config.SetConsumerService(userProviderV2)
+
+ err := config.Load()
+ if err != nil {
+ panic(err)
+ }
+
+ testAsync()
+ testAsyncOneWay()
+}
+
+// two-way
+func testAsync() {
+ reqUser := &pkg.User{}
+ reqUser.ID = "003"
+ _, err := userProvider.GetUser(context.TODO(), reqUser)
+ if err != nil {
+ panic(err)
+ }
+
+ // Mock do something else
+ logger.Info("non-blocking before async callback resp: do something ... ")
+
+ // Wait for Callback
+ time.Sleep(time.Second)
+}
+
+// one-way
+func testAsyncOneWay() {
+ err := userProviderV2.SayHello(context.TODO(), "003")
+ if err != nil {
+ panic(err)
+ }
+ logger.Info("test end")
+}
diff --git a/async/go-client/conf/dubbogo.yml b/async/go-client/conf/dubbogo.yml
new file mode 100644
index 00000000..6f115620
--- /dev/null
+++ b/async/go-client/conf/dubbogo.yml
@@ -0,0 +1,17 @@
+# dubbo client yaml configure file
+
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ consumer:
+ references:
+ UserProvider:
+ protocol: dubbo
+ interface: org.apache.dubbo.sample.UserProvider
+ async: true
+ UserProviderV2:
+ protocol: dubbo
+ interface: org.apache.dubbo.sample.UserProviderV2
+ async: true
\ No newline at end of file
diff --git a/async/go-client/pkg/user.go b/async/go-client/pkg/user.go
new file mode 100644
index 00000000..9e5a88ef
--- /dev/null
+++ b/async/go-client/pkg/user.go
@@ -0,0 +1,113 @@
+/*
+ * 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 pkg
+
+import (
+ "context"
+ "dubbo.apache.org/dubbo-go/v3/common"
+ "dubbo.apache.org/dubbo-go/v3/protocol"
+ "dubbo.apache.org/dubbo-go/v3/remoting"
+ "fmt"
+ gxlog "github.com/dubbogo/gost/log"
+ "strconv"
+ "time"
+)
+
+import (
+ hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+type Gender hessian.JavaEnum
+
+const (
+ MAN Gender = iota
+ WOMAN
+)
+
+var genderName = map[Gender]string{
+ MAN: "MAN",
+ WOMAN: "WOMAN",
+}
+
+var genderValue = map[string]Gender{
+ "MAN": MAN,
+ "WOMAN": WOMAN,
+}
+
+func (g Gender) JavaClassName() string {
+ return "org.apache.dubbo.sample.Gender"
+}
+
+func (g Gender) String() string {
+ s, ok := genderName[g]
+ if ok {
+ return s
+ }
+
+ return strconv.Itoa(int(g))
+}
+
+func (g Gender) EnumValue(s string) hessian.JavaEnum {
+ v, ok := genderValue[s]
+ if ok {
+ return hessian.JavaEnum(v)
+ }
+
+ return hessian.InvalidJavaEnum
+}
+
+type User struct {
+ // !!! Cannot define lowercase names of variable
+ ID string `hessian:"id"`
+ Name string
+ Age int32
+ Time time.Time
+ Sex Gender // notice: java enum Object <--> go string
+}
+
+func (u User) String() string {
+ return fmt.Sprintf(
+ "User{ID:%s, Name:%s, Age:%d, Time:%s, Sex:%s}",
+ u.ID, u.Name, u.Age, u.Time, u.Sex,
+ )
+}
+
+func (u *User) JavaClassName() string {
+ return "org.apache.dubbo.sample.User"
+}
+
+type UserProvider struct {
+ GetUser func(ctx context.Context, req *User) (*User, error)
+}
+
+// CallBack for async callback
+func (u *UserProvider) CallBack(response common.CallbackResponse) {
+ resp := response.(remoting.AsyncCallbackResponse).Reply.(*remoting.Response)
+ if resp.Error != nil {
+ panic(resp.Error)
+ }
+
+ user := resp.Result.(*protocol.RPCResult).Rest.(*User)
+ gxlog.CInfo("async callback response! got result :%v\n", user)
+ return
+}
+
+// UserProviderV2 for one way
+type UserProviderV2 struct {
+ SayHello func(ctx context.Context, name string) error
+}
diff --git a/async/go-server/cmd/server.go b/async/go-server/cmd/server.go
new file mode 100644
index 00000000..5af5df70
--- /dev/null
+++ b/async/go-server/cmd/server.go
@@ -0,0 +1,84 @@
+/*
+ * 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 main
+
+import (
+ "fmt"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/config"
+ _ "dubbo.apache.org/dubbo-go/v3/imports"
+
+ hessian "github.com/apache/dubbo-go-hessian2"
+
+ "github.com/dubbogo/gost/log/logger"
+)
+
+import (
+ "github.com/apache/dubbo-go-samples/async/go-server/pkg"
+)
+
+var (
+ survivalTimeout = int(3e9)
+)
+
+// need to setup environment variable "DUBBO_GO_CONFIG_PATH" to "conf/dubbogo.yml" before run
+func main() {
+
+ // ------for hessian2------
+ hessian.RegisterJavaEnum(pkg.MAN)
+ hessian.RegisterJavaEnum(pkg.WOMAN)
+ hessian.RegisterPOJO(&pkg.User{})
+ config.SetProviderService(&pkg.UserProvider{})
+ config.SetProviderService(&pkg.UserProviderV2{})
+ // ------------
+
+ if err := config.Load(); err != nil {
+ panic(err)
+ }
+
+ initSignal()
+}
+
+func initSignal() {
+ signals := make(chan os.Signal, 1)
+ // It is not possible to block SIGKILL or syscall.SIGSTOP
+ signal.Notify(signals, os.Interrupt, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
+ for {
+ sig := <-signals
+ logger.Infof("get signal %s", sig.String())
+ switch sig {
+ case syscall.SIGHUP:
+ // reload()
+ default:
+ time.AfterFunc(time.Duration(survivalTimeout), func() {
+ logger.Warnf("app exit now by force...")
+ os.Exit(1)
+ })
+
+ // The program exits normally or timeout forcibly exits.
+ fmt.Println("provider app exit now...")
+ return
+ }
+ }
+}
diff --git a/async/go-server/conf/dubbogo.yml b/async/go-server/conf/dubbogo.yml
new file mode 100644
index 00000000..511b62e9
--- /dev/null
+++ b/async/go-server/conf/dubbogo.yml
@@ -0,0 +1,18 @@
+# dubbo server yaml configure file
+
+dubbo:
+ registries:
+ demoZK:
+ protocol: zookeeper
+ timeout: 3s
+ address: 127.0.0.1:2181
+ protocols:
+ dubbo:
+ name: dubbo
+ port: 20000
+ provider:
+ services:
+ UserProvider:
+ interface: org.apache.dubbo.sample.UserProvider
+ UserProviderV2:
+ interface: org.apache.dubbo.sample.UserProviderV2
\ No newline at end of file
diff --git a/async/go-server/pkg/user.go b/async/go-server/pkg/user.go
new file mode 100644
index 00000000..ca9f763f
--- /dev/null
+++ b/async/go-server/pkg/user.go
@@ -0,0 +1,109 @@
+/*
+ * 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 pkg
+
+import (
+ "fmt"
+ "strconv"
+ "time"
+)
+
+import (
+ hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+type Gender hessian.JavaEnum
+
+const (
+ MAN Gender = iota
+ WOMAN
+)
+
+var genderName = map[Gender]string{
+ MAN: "MAN",
+ WOMAN: "WOMAN",
+}
+
+var genderValue = map[string]Gender{
+ "MAN": MAN,
+ "WOMAN": WOMAN,
+}
+
+func (g Gender) JavaClassName() string {
+ return "org.apache.dubbo.sample.Gender"
+}
+
+func (g Gender) String() string {
+ s, ok := genderName[g]
+ if ok {
+ return s
+ }
+
+ return strconv.Itoa(int(g))
+}
+
+func (g Gender) EnumValue(s string) hessian.JavaEnum {
+ v, ok := genderValue[s]
+ if ok {
+ return hessian.JavaEnum(v)
+ }
+
+ return hessian.InvalidJavaEnum
+}
+
+type (
+ User struct {
+ // !!! Cannot define lowercase names of variable
+ ID string `hessian:"id"`
+ Name string
+ Age int32
+ Time time.Time
+ Sex Gender // notice: java enum Object <--> go string
+ }
+)
+
+var (
+ DefaultUser = User{
+ ID: "000", Name: "Alex Stocks", Age: 31,
+ Sex: MAN,
+ }
+
+ userMap = make(map[string]User)
+)
+
+func init() {
+ userMap["000"] = DefaultUser
+ userMap["001"] = User{ID: "001", Name: "ZhangSheng", Age: 18, Sex: MAN}
+ userMap["002"] = User{ID: "002", Name: "Lily", Age: 20, Sex: WOMAN}
+ userMap["003"] = User{ID: "113", Name: "Moorse", Age: 30, Sex: WOMAN}
+ for k, v := range userMap {
+ v.Time = time.Now()
+ userMap[k] = v
+ }
+}
+
+func (u User) String() string {
+ return fmt.Sprintf(
+ "User{ID:%s, Name:%s, Age:%d, Time:%s, Sex:%s}",
+ u.ID, u.Name, u.Age, u.Time, u.Sex,
+ )
+}
+
+func (u User) JavaClassName() string {
+ return "org.apache.dubbo.sample.User"
+}
diff --git a/async/go-server/pkg/user_provider.go b/async/go-server/pkg/user_provider.go
new file mode 100644
index 00000000..79792457
--- /dev/null
+++ b/async/go-server/pkg/user_provider.go
@@ -0,0 +1,49 @@
+/*
+ * 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 pkg
+
+import (
+ "context"
+ "fmt"
+ gxlog "github.com/dubbogo/gost/log"
+)
+
+type UserProvider struct {
+}
+
+func (u *UserProvider) getUser(userID string) (*User, error) {
+ if user, ok := userMap[userID]; ok {
+ return &user, nil
+ }
+
+ return nil, fmt.Errorf("invalid user id:%s", userID)
+}
+
+func (u *UserProvider) GetUser(ctx context.Context, req *User) (*User, error) {
+ var (
+ err error
+ user *User
+ )
+
+ gxlog.CInfo("req:%#v", req)
+ user, err = u.getUser(req.ID)
+ if err == nil {
+ gxlog.CInfo("rsp:%#v", user)
+ }
+ return user, err
+}
diff --git a/async/go-server/pkg/user_provider_v2.go b/async/go-server/pkg/user_provider_v2.go
new file mode 100644
index 00000000..0e92db0a
--- /dev/null
+++ b/async/go-server/pkg/user_provider_v2.go
@@ -0,0 +1,33 @@
+package pkg
+
+import (
+ "context"
+ "fmt"
+ gxlog "github.com/dubbogo/gost/log"
+)
+
+type UserProviderV2 struct {
+}
+
+func (u *UserProviderV2) getUser(userID string) (*User, error) {
+ if user, ok := userMap[userID]; ok {
+ return &user, nil
+ }
+
+ return nil, fmt.Errorf("invalid user id:%s", userID)
+}
+
+func (u *UserProviderV2) SayHello(ctx context.Context, userID string) error {
+ var (
+ err error
+ user *User
+ )
+
+ user, err = u.getUser(userID)
+ if err != nil {
+ panic(err)
+ }
+
+ gxlog.CInfo("hello, %s", user.Name)
+ return nil
+}