Open chaunsin opened 1 year ago
有这样一个场景,我有一个for死循环以指定时间间隔去调用GetBlockByNumber()方法,大概运行一天左右发现这个方法阻塞住了,通过读取代码发现,貌似会存在通道阻塞得问题,我们得代码逻辑片段如下:
for { select { case <-ctx.Done(): log.Warnf("[event] %v is exit", lis.Id) return nil default: // 调用区块高度查询,如果如果有新区块产生则offset+1,没有则睡眠3s等待下次执行 block, err := s.adapter.RawClient().GetBlockByNumber(ctx, int64(offset), true) if err != nil { time.Sleep(time.Second * 3) log.Warnf("[event] loop GetBlockByNumber(%d) err:%s", offset, err) continue } var blockNum = common.HexToHash(block.Number).Big().Uint64() for _, v := range block.Transactions { ... 省略校验逻辑与判断 receipt, err := s.adapter.TransactionReceipt(ctx, hash) if err != nil { log.Warnf("[event] TransactionReceipt(%s): %w", hash, err) continue } ... // 注意此处log,下文会提及,如果打印了此日志说明已经查询到了区块交易 log.Infof("[event] listener data {appId:%v,id:%v,srcChainId:%v,listenContract:%v,listenEvent:%v,state:%v,blockNum:%v curBlock:%v curTxId:%v logs:%v}", lis.AppId, lis.LinkId, lis.ChainId, lis.ListenContract, lis.ListenEvent, lis.Status, lis.BlockNum, blockNum, hash, receipt.Logs) // 发送交易具体业务逻辑 s.send(ctx, lis, receipt, parse, &_abi, contractAddr) } log.Infof("[event] block offset %d++", offset) offset++ } }
然后我们采集了服务日志
我们自己打印得日志,此日志对应上述代码片段打印得日志,已提取主要内容,以下展示得是GetBlockByNumber()最后几次打印得情况:
ps: [event] listener data {appId:%v,id:%v,srcChainId:%v,listenContract:%v,listenEvent:%v,state:%v,blockNum:%v curBlock:%v curTxId:%v logs:%v} 日志打印我们并没有查询到,说明没有执行到block.Transactions for循环当中得逻辑
[event] listener data {appId:%v,id:%v,srcChainId:%v,listenContract:%v,listenEvent:%v,state:%v,blockNum:%v curBlock:%v curTxId:%v logs:%v}
go-sdk 打印得日志:
红线上面得日志请求时间和我们自己打印得日志时间能一一对应上,红线下面部分是我们单次调用GetBlockByNumber()方法所产生得日志记录,对应得日志记录如下:
ps: 我们区块高度还没达到9999因此报错,这不影响我们所说得问题,从调用结果可以看出我们得链是通得
接收响应请求
向通道内写入请求响应
ok到这我有以下几个疑问?
我们是根据消息id也就是上述图片当中msg.uuid作为消息读取映射得,在写入数据得时候,那么会不会存在这种情况,当sdk收不到相应得msg.uuid消息时,则图片一中的<-Response.Notify会一直阻塞?
还是基于问题一,在我们排查sdk日志得时候发现打印了很多decodeChannelMessage error:uncomplete message 错误描述信息,也就是代码channel.go 1127行打印的日志,执行到此处时continue就不会继续执行下去了,那么会不会有这样情况当前decode失败得数据正是我们当前GetBlockByNumber()方法对应得数据?如果是那么就会存在阻塞问题。
decodeChannelMessage error:uncomplete message
msg.uuid链服务端会不会出现重复问题,或者某些规则导致服务端不会返回对应得msg.uuid相应消息,从而造成<-Response.Notify一直阻塞?
ok到这基本上已经把情况说明,请求帮助谢谢!!!
请使用这个分支的最新代码验证下,https://github.com/FISCO-BCOS/go-sdk/tree/master-FISCO-BCOS-v2 有可能是这个PR解决的问题,对应issue
多谢
版本
问题
有这样一个场景,我有一个for死循环以指定时间间隔去调用GetBlockByNumber()方法,大概运行一天左右发现这个方法阻塞住了,通过读取代码发现,貌似会存在通道阻塞得问题,我们得代码逻辑片段如下:
然后我们采集了服务日志
我们自己打印得日志,此日志对应上述代码片段打印得日志,已提取主要内容,以下展示得是GetBlockByNumber()最后几次打印得情况:
ps:
[event] listener data {appId:%v,id:%v,srcChainId:%v,listenContract:%v,listenEvent:%v,state:%v,blockNum:%v curBlock:%v curTxId:%v logs:%v}
日志打印我们并没有查询到,说明没有执行到block.Transactions for循环当中得逻辑go-sdk 打印得日志:
红线上面得日志请求时间和我们自己打印得日志时间能一一对应上,红线下面部分是我们单次调用GetBlockByNumber()方法所产生得日志记录,对应得日志记录如下:
ps: 我们区块高度还没达到9999因此报错,这不影响我们所说得问题,从调用结果可以看出我们得链是通得
代码分析
接收响应请求
向通道内写入请求响应
ok到这我有以下几个疑问?
问题一
我们是根据消息id也就是上述图片当中msg.uuid作为消息读取映射得,在写入数据得时候,那么会不会存在这种情况,当sdk收不到相应得msg.uuid消息时,则图片一中的<-Response.Notify会一直阻塞?
问题二
还是基于问题一,在我们排查sdk日志得时候发现打印了很多
decodeChannelMessage error:uncomplete message
错误描述信息,也就是代码channel.go 1127行打印的日志,执行到此处时continue就不会继续执行下去了,那么会不会有这样情况当前decode失败得数据正是我们当前GetBlockByNumber()方法对应得数据?如果是那么就会存在阻塞问题。问题三
msg.uuid链服务端会不会出现重复问题,或者某些规则导致服务端不会返回对应得msg.uuid相应消息,从而造成<-Response.Notify一直阻塞?
ok到这基本上已经把情况说明,请求帮助谢谢!!!