请教个select...case...问题,烦恼了好几天了

orthoc · · 376 次点击 · 开始浏览    置顶
共有两台服务器A跟B,它们使用一条grpc长链接进行交互,A是grpc服务端,在公网;B是客户端,在内网。 服务器A的代码里有两个协程,分别监听http和grpc,用一个同步channel进行通信。 我的业务流程: 1、用户通过http接口访问A,A需要调用B的程序,此时使用Send(*Response) error把必要的参数发送过去; 2、B通过Recv()监听到A发来的请示,把运算结果通过Send()发送回A; 3、A通过Recv()收到运算结果,把结果输入到同步channel,http服务结束同步阻塞,返回http response给用户。 现在我要在步骤1加上30秒超时的限制,却出现了奇怪的问题,伪代码如下: ``` A.Send("data...") go func() { time.Sleep(30e9) timeoutChan <- true }() select { case <-timeoutChan: // 返回超时错误信息 case resp := <-respChan: // 正常返回数据 } ``` 按照我的想法,应该是用户访问A的http接口时,如果超过30秒,会得到个超时错误。但却产生以下问题,有并发请示时(假设恰好请示1和请示2),请示1得到的http response是请示2的运算结果,请示2得到的http response是请示1的运算结果。 我回滚到原代码,(即去掉了超时限制功能,没有上边的go func(){time.Sleep()}和select... case...),只使用同步channel一直阻塞等待返回结果,进行压力测试,并不会出上以上问题,http request跟response都能对应。所以现在想不通,为何select... case...会出现以上问题,我需要做什么改进。

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:1006366459

376 次点击  
加入收藏 微博
1 回复  |  直到 2020-10-20 15:39:13
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传