dubbo-go
dubbo-go copied to clipboard
invoking EchoInt8 based on dubbo protocol failed
Environment
- Server: Dubbo-go, v3.1.0
- Client: Dubbo-go, v3.1.0
- Protocol: Dubbo
Issue description
Provided Api EchoInt8:
type UserProvider struct {
EchoInt8 func(ctx context.Context, req int8) (int8, error)
}
func (u *UserProvider) EchoInt8(ctx context.Context, req int8) (int8, error) {
return req, nil
}
After invoking, srv-side returns error "reflect: Call using int32 as type int8"
Logs
Click me to check logs
cli-side
2023-08-19 09:07:32 INFO logger/logging.go:42 The following profiles are active: [default]
2023-08-19 09:07:32 INFO config/root_config.go:137 [Config Center] Config center doesn't start
2023-08-19 09:07:32 INFO config/reference_config.go:136 URL specified explicitly dubbo://127.0.0.1:20000
2023-08-19 09:07:32 INFO dubbo/dubbo_protocol.go:99 [DUBBO Protocol] Refer service: dubbo://127.0.0.1:20000/org.apache.dubbo.UserProvider?app.version=&application=dubbo.io&async=false&bean.name=UserProvider&cluster=failover&config.tracing=&environment=&generic=&group=&interface=org.apache.dubbo.UserProvider&loadbalance=&metadata-type=local&module=sample&name=dubbo.io&organization=dubbo-go&owner=dubbo-go&peer=true&provided-by=&reference.filter=cshutdown®istry.role=0&release=dubbo-golang-3.0.4&remote.timestamp=&retries=&serialization=&side=consumer&sticky=false×tamp=1692407252&version=
2023-08-19 09:07:32 WARN proxy/proxy.go:209 [CallProxy] invoke service throw exception: reflect: Call using int32 as type int8 , stackTraceElements: []
src-side
2023-08-19 09:07:32 ERROR proxy_factory/default.go:146 Invoke function error: reflect: Call using int32 as type int8
dubbo.apache.org/dubbo-go/v3/proxy/proxy_factory.callLocalMethod.func1.1
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/proxy/proxy_factory/utils.go:42
runtime.gopanic
/usr/local/go/src/runtime/panic.go:884
reflect.Value.call
/usr/local/go/src/reflect/value.go:442
reflect.Value.Call
/usr/local/go/src/reflect/value.go:370
dubbo.apache.org/dubbo-go/v3/proxy/proxy_factory.callLocalMethod.func1
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/proxy/proxy_factory/utils.go:49
dubbo.apache.org/dubbo-go/v3/proxy/proxy_factory.callLocalMethod
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/proxy/proxy_factory/utils.go:50
dubbo.apache.org/dubbo-go/v3/proxy/proxy_factory.(*ProxyInvoker).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/proxy/proxy_factory/default.go:143
dubbo.apache.org/dubbo-go/v3/filter/graceful_shutdown.(*providerGracefulShutdownFilter).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/filter/graceful_shutdown/provider_filter.go:80
dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper.(*FilterInvoker).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/protocol/protocolwrapper/protocol_filter_wrapper.go:127
dubbo.apache.org/dubbo-go/v3/filter/exec_limit.(*executeLimitFilter).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/filter/exec_limit/filter.go:119
dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper.(*FilterInvoker).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/protocol/protocolwrapper/protocol_filter_wrapper.go:127
dubbo.apache.org/dubbo-go/v3/filter/generic.(*genericServiceFilter).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/filter/generic/service_filter.go:64
dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper.(*FilterInvoker).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/protocol/protocolwrapper/protocol_filter_wrapper.go:127
dubbo.apache.org/dubbo-go/v3/filter/tps.(*tpsLimitFilter).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/filter/tps/filter.go:96
dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper.(*FilterInvoker).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/protocol/protocolwrapper/protocol_filter_wrapper.go:127
dubbo.apache.org/dubbo-go/v3/filter/accesslog.(*Filter).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/filter/accesslog/filter.go:113
dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper.(*FilterInvoker).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/protocol/protocolwrapper/protocol_filter_wrapper.go:127
dubbo.apache.org/dubbo-go/v3/filter/token.(*tokenFilter).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/filter/token/filter.go:94
dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper.(*FilterInvoker).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/protocol/protocolwrapper/protocol_filter_wrapper.go:127
dubbo.apache.org/dubbo-go/v3/filter/metrics.(*Filter).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/filter/metrics/filter.go:55
dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper.(*FilterInvoker).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/protocol/protocolwrapper/protocol_filter_wrapper.go:127
dubbo.apache.org/dubbo-go/v3/filter/echo.(*echoFilter).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/filter/echo/filter.go:64
dubbo.apache.org/dubbo-go/v3/protocol/protocolwrapper.(*FilterInvoker).Invoke
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/protocol/protocolwrapper/protocol_filter_wrapper.go:127
dubbo.apache.org/dubbo-go/v3/protocol/dubbo.doHandleRequest
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/protocol/dubbo/dubbo_protocol.go:161
dubbo.apache.org/dubbo-go/v3/protocol/dubbo.(*DubboProtocol).openServer.func1
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/protocol/dubbo/dubbo_protocol.go:128
dubbo.apache.org/dubbo-go/v3/remoting/getty.(*RpcServerHandler).OnMessage
/Users/wangyuxuan/go/pkg/mod/dubbo.apache.org/dubbo-go/[email protected]/remoting/getty/listener.go:275
github.com/apache/dubbo-getty.(*session).addTask.func1
/Users/wangyuxuan/go/pkg/mod/github.com/apache/[email protected]/session.go:565
github.com/dubbogo/gost/sync.(*taskPoolSimple).worker
/Users/wangyuxuan/go/pkg/mod/github.com/dubbogo/[email protected]/sync/task_pool.go:305
runtime.goexit
/usr/local/go/src/runtime/asm_arm64.s:1172, service: &common.URL{noCopy:common.noCopy{}, baseURL:common.baseURL{Protocol:"dubbo", Location:":20000", Ip:"", Port:"20000", PrimitiveURL:""}, paramsLock:sync.RWMutex{w:sync.Mutex{state:0, sema:0x0}, writerSem:0x0, readerSem:0x0, readerCount:atomic.Int32{_:atomic.noCopy{}, v:0}, readerWait:atomic.Int32{_:atomic.noCopy{}, v:0}}, params:url.Values{"accesslog":[]string{""}, "app.version":[]string{""}, "application":[]string{"dubbo.io"}, "auth":[]string{""}, "bean.name":[]string{"UserProvider"}, "cluster":[]string{"failover"}, "config.tracing":[]string{""}, "environment":[]string{""}, "execute.limit":[]string{""}, "execute.limit.rejected.handler":[]string{""}, "export":[]string{"true"}, "interface":[]string{"org.apache.dubbo.UserProvider"}, "loadbalance":[]string{"random"}, "max-server-recv-msg-size":[]string{"4mib"}, "max-server-send-msg-size":[]string{""}, "metadata-type":[]string{"local"}, "module":[]string{"sample"}, "name":[]string{"dubbo.io"}, "organization":[]string{"dubbo-go"}, "owner":[]string{"dubbo-go"}, "param.sign":[]string{""}, "pid":[]string{"17878"}, "registry.role":[]string{"3"}, "release":[]string{"dubbo-golang-3.0.4"}, "retries":[]string{""}, "serialization":[]string{""}, "service.filter":[]string{"echo,metrics,token,accesslog,tps,generic_service,execute,pshutdown"}, "side":[]string{"provider"}, "timestamp":[]string{"1692407033"}, "tps.limit.interval":[]string{""}, "tps.limit.rate":[]string{""}, "tps.limit.rejected.handler":[]string{""}, "tps.limit.strategy":[]string{""}, "tps.limiter":[]string{""}, "warmup":[]string{""}}, Path:"/org.apache.dubbo.UserProvider", Username:"", Password:"", Methods:[]string{"EchoInt", "EchoInt8", "GetUser"}, SubURL:(*common.URL)(nil)}
Analyzing
For cli-side, dubbo-go make use of Hessian2 to encode int8. After encoding, int8 becomes int32. Refer https://github.com/apache/dubbo-go-hessian2/blob/f0fbe40e207cc5ba0cb76b1dcc0c8db2aee877bf/encode.go#L112
case int8:
e.buffer = encInt32(e.buffer, int32(val))
For srv-side, dubbo-go uses Hessian2 to decode and get int32. It does not do any compatibility and truncation processing, just pass int32 to user business logic. As a result, it panics.
Hi, @tiltwind. This is a hessian-releated issue. Could you take a look at this? Thanks!
@justxuewei In hessian2 protocol, int
type (32bit) is the minimal number type, so hessian2 will encode int8 to int32.
Then the other side of dubbo rpc will decode and get the int32 value, and use the value as argument to call the function.
But the type of the value does not match the type of the parameter,so it panics.
I think the solution is checking whether or not the type of the argument matches the type of the parameter before calling the function, if not matching, try to convert the argument value to a matching one.
And another solution, is changing the definition of the function, using int32 as the type of the parameter.
@justxuewei there is another option.
Change the calling of function from decoder.Decode()
to decoder.decToDest(dest)
arg, err = decoder.Decode()
// change to the following
argDest:= reflect.new(argType)
err = decoder.decToDest(argDest) // the func decToDest must export first
arg = argDest.Interface()
@tiltwind Thanks for your suggestions!
Convert the arg to the target type:
dec, err = decoder.Decode()
if argType != dec.Type {
decValue := hessian.EnsurePackValue(dec)
argDest:= reflect.new(argType)
hessian.SetValue(argDest, decValue)
arg = argDest.Interface()
}
else
{
arg = dec
}