Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong return count from function created by MakeFunc #2

Open
WillemJiang opened this issue Aug 31, 2019 · 3 comments
Open

Wrong return count from function created by MakeFunc #2

WillemJiang opened this issue Aug 31, 2019 · 3 comments

Comments

@WillemJiang
Copy link

Here is a user issue apache/servicecomb-pack#548 in ServiceComb-Pack about using go-client to connect the alpha server.
@jeremyxu2010 Could you take a look at it?

2019-08-30T01:34:55.291Z error /usr/share/httpd/go/pkg/mod/github.com/grpc-ecosystem/go-grpc-middleware@v1.0.0/logging/zap/server_interceptors.go:40 finished unary call with code Internal {"serviceName": "demo", "grpc.start_time": "2019-08-30T01:34:55Z", "system": "grpc", "span.kind": "server", "grpc.service": "api.StatementGrpc", "grpc.method": "CreateStatementBatch", "error": "rpc error: code = Internal desc = reflect: wrong return count from function created by MakeFunc", "grpc.code": "Internal", "grpc.time_ms": 5.015999794006348}
github.com/grpc-ecosystem/go-grpc-middleware/logging/zap.UnaryServerInterceptor.func1
/usr/share/httpd/go/pkg/mod/github.com/grpc-ecosystem/go-grpc-middleware@v1.0.0/logging/zap/server_interceptors.go:40
github.com/grpc-ecosystem/go-grpc-middleware.ChainUnaryServer.func1
/usr/share/httpd/go/pkg/mod/github.com/grpc-ecosystem/go-grpc-middleware@v1.0.0/chain.go:39
statement-svc/api._StatementGrpc_CreateStatementBatch_Handler
/opt/jenkins/workspace/Youlanai-statement-svc-test/api/statement.pb.go:390
google.golang.org/grpc.(*Server).processUnaryRPC
/usr/share/httpd/go/pkg/mod/google.golang.org/grpc@v1.21.1/server.go:998
google.golang.org/grpc.(*Server).handleStream
/usr/share/httpd/go/pkg/mod/google.golang.org/grpc@v1.21.1/server.go:1278
google.golang.org/grpc.(*Server).serveStreams.func1.1
/usr/share/httpd/go/pkg/mod/google.golang.org/grpc@v1.21.1/server.go:717

@jeremyxu2010
Copy link
Owner

jeremyxu2010 commented Sep 1, 2019

很抱歉,由于目前在忙别的工作,确实很久没有更新该client库了。

servicecomb-pack项目的向前兼容做得很好,我试着跑了下测试用例,暂时还是可正常工作的。

从上述报错信息来看,应该是使用saga.DecorateSagaStartMethodsaga.DecorateCompensableMethod装饰的方法返回值个数不正确,被装饰的方法签名必须与声明的装饰方法签名相同,见参考测试用例

你也可以按以下指引先跑一遍测试用例看看

# 克隆并编译servicecomb-pack项目
$ git clone https://github.com/apache/servicecomb-pack.git
$ cd servicecomb-pack
$ mvn clean install -P 'mysql,!docker' -DskipTests=true

# 初始化alpha-server依赖的数据库
$ mysql -uroot -proot -h127.0.0.1 -P3306
MariaDB [(none)]> create database saga;
Query OK, 1 row affected (0.005 sec)

MariaDB [(none)]> grant all privileges on saga.* to saga@'localhost' identified by 'saga';
Query OK, 0 rows affected (0.045 sec)

MariaDB [(none)]> flush privileges;

MariaDB [(none)]> use saga
Database changed

MariaDB [saga]> source alpha/alpha-server/src/main/resources/schema-mysql.sql

MariaDB [saga]> exit
Bye

# 启动alpha-server
$ java -Dspring.profiles.active=mysql -D"spring.datasource.url=jdbc:mysql://127.0.0.1:3306/saga?useSSL=false" -D"spring.datasource.password=saga" -jar alpha/alpha-server/target/saga/alpha-server-0.6.0-SNAPSHOT-exec.jar

另开一个shell终端,执行以下命令:

# 克隆matrix-go-client项目并切换工作目录至matrix-saga-go目录
$ git clone https://github.com/jeremyxu2010/matrix-saga-go.git
$ cd matrix-saga-go
# 使用go mod下载go module依赖
$ go mod download
# 运行测试用例,可以看到转帐过程中,foo和bar的帐户余额出现了短暂的不一致,但后面又达到了最终一致性,符合saga分布式事务的设计理念
$ go run test/sagatx_demo.go
foo balance: 500, bar balance: 500
foo balance: 400, bar balance: 500
foo balance: 500, bar balance: 500
foo balance: 500, bar balance: 500
......

这个go client库是一年前做的,当时servicecomb-pack的版本还是0.2.0版本。这一年时间servicecomb-pack发展挺快,有了不少变化,实现了相当多新的功能特性(TCC模式、AlphaServer HA、SagaEnd支持等)。后续我会抽时间,参考新版本的omega逐步完善本go client库,尽可能补上相关功能特性。

@xfye
Copy link

xfye commented Mar 20, 2021

我这边的原因是:
在decorator.go中,如果before func失败,那么返回值列表就是空,而被修饰的函数的返回值列表不是空,那么就会抛异常。比如当omega往alpha发送子事务启动event,但是alpha拒绝的话,那么就会出现这种情况。

    if before != nil {
        if m, ok := metadata.FromContext(ctx); ok {
            m[constants.KEY_FUNCTION_CALL_ARGS] = in
        }   
        beforeOut := beforeFunc.Call([]reflect.Value{reflect.ValueOf(ctx)})
        if !beforeOut[0].IsNil() {
            return
        }
    }

@jeremyxu2010
Copy link
Owner

我这边的原因是:
在decorator.go中,如果before func失败,那么返回值列表就是空,而被修饰的函数的返回值列表不是空,那么就会抛异常。比如当omega往alpha发送子事务启动event,但是alpha拒绝的话,那么就会出现这种情况。

    if before != nil {
        if m, ok := metadata.FromContext(ctx); ok {
            m[constants.KEY_FUNCTION_CALL_ARGS] = in
        }   
        beforeOut := beforeFunc.Call([]reflect.Value{reflect.ValueOf(ctx)})
        if !beforeOut[0].IsNil() {
            return
        }
    }

@xfye 你说得对,这里如发现是错误结果,应该将错误返回,以阻止继续执行targetFunc。还有几处类似的错误处理也有问题,这两天我抽空处理一下。感谢你的反馈!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants