update design doc

This commit is contained in:
lyyyuna 2021-06-03 23:30:01 +08:00
parent 18c4c4a2da
commit dca67829b6
4 changed files with 60 additions and 43 deletions

View File

@ -10,7 +10,7 @@ goc build/install/run 会尽可能的模仿 go 原生的方式去处理参数。
## 主要问题
1. goc 使用 cobra 库来组织各个子命令。cobra 对 flag 处理采用的是 posix 风格(两个短横线),和 go 的 flag 处理差异很大(一个短横线)。
1. goc 使用 cobra 库来组织各个子命令。cobra 对 flag 处理采用的是 posix 风格(两个短横线),和 go 的 flag 处理差异很大(一个短横线)。
2. go 命令中 args 和 flags 有着严格先后顺序。而 cobra 库对 flags 和 args 的位置没有要求。
3. 参数中 `[packages]` 有多种组合情况,会影响到插桩的起始位置。
4. goc 还有自己参数,且需要和**非** goc build/install/run 的子命令保持一致(两个短横线)。

49
doc/protocol.md Normal file
View File

@ -0,0 +1,49 @@
# 通信协议设计
## 背景
v1 版本中,被插桩的服务会暴露一个 HTTP 接口,由 goc server 来访问获取覆盖率。
该方式要求被插桩的服务要有一个外界可访问的 ip + port。
如果被测服务躲在 NAT 网络下,该方式就不可行了,典型的就是被测服务由 docker 拉起,而 goc server 部署在另外的网络。
## 新设计选择
新设计只需要暴露 goc server 的地址,由插桩服务发起链接,然后保持长链接,在该长链接上构建 goc 自己的业务逻辑。
### 自行设计 TCP 应用层协议
go 语言做网络编程非常适合,非阻塞地处理“粘包”也不麻烦。但设计出来不管是纯二进制的、还是类似 HTTP 的,都不会是通用协议,后续维护和扩展估计是个大坑。
### websocket + jsonrpc2
websocket + jsonrpc2 有流式调用,消息边界。非常适合
我找到 `github.com/goriila/websocket``github.com/sourcegraph/jsonrpc2` 库,后者 import 了前者,前者没有 import 任何其它外部库,全是标准库。把两个库的代码合并一下:`github.com/lyyyuna/jsonrpc2` 就是一个无任何外部库引用的 jsonrpc 实现。
这非常适合由插桩代码来使用,因为该库没有再引用其它库,**不会污染原服务的依赖关系**。
### gRPC
老实说 gRPC 在这里更适合作为通信协议来使用,更快更通用,流式调用也有,上一小节的 `github.com/sourcegraph/jsonrpc2` 使用广度就很低。
但 gRPC 的 go 实现有一个很大的缺点,用了一些非标准库,且有版本依赖。我们不清楚原服务是不是有特定 gRPC 要求,或是 goc 插入的 gRPC 库会导致编译依赖冲突,或者是编译后运行冲突。
所以不适合。
### 结论
先使用 websocket + jsonrpc2 来做吧。
## 协议内容
### 注册
### 获取覆盖率
### 清空覆盖率
### watch
### 异常处理

View File

@ -1,2 +1,12 @@
# 返回 error 还是原地 fatal
哪种好呢?在一个纯命令行应用中,及时 fatal并能在 Panic 中打印出堆栈对调试即为有意。
若是返回 error虽然看起来
1. 对每种异常处理都定义的很清楚(有明确的错误消息)
2. 写单测也更容易
但是 Go 的错误处理,导致 error 被一层层返回,以至于在最上层拿到 error 时你都分不清有几层了 -_-,虽然 Go 1.13 的 error wrap 一定程度消减了这个问题,但还是不如 Panic 来的好调试。
而且 goc 并不是一个供大家使用的库,目前来看 fatal 还是更适合。

View File

@ -1,42 +0,0 @@
/*
Copyright 2020 Qiniu Cloud (qiniu.com)
Licensed 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 websocket
import (
"context"
"net/http"
"net/url"
"time"
)
// Dialer contains all options for connecting to a specified websocket server
type Dialer struct {
Proxy func(*http.Request) (*url.URL, error)
HandshakeTimeout time.Duration
Subprotocols []string
}
// DefaultDialer is dialer with all necessary fields set to default value
var DefaultDialer = &Dialer{
Proxy: http.ProxyFromEnvironment,
HandshakeTimeout: 45 * time.Second,
}
func (d *Dialer) Dial() {
}
func (d *Dialer) DialContext(ctx context.Context) {
}