What happened:
如果调用 setCompress(compressNone),会出现坏流现象,
原因:setCompress 会使得 gettyTCPconn 的 writer and reader 封装成 flate 压缩算法的接口,而 Send 函数判定CompressNone 会直接让他走系统底层 writev,这样导致读写格式不一致,代码如下
if t.compress == CompressNone {
netBuf := net.Buffers(buffers)
lg, err = netBuf.WriteTo(t.conn)
}
func (t *gettyTCPConn) SetCompressType(c CompressType) {
switch c {
case CompressNone, CompressZip, CompressBestSpeed, CompressBestCompression, CompressHuffman:
ioReader := io.Reader(t.conn)
t.reader = flate.NewReader(ioReader)
ioWriter := io.Writer(t.conn)
w, err := flate.NewWriter(ioWriter, int(c))
if err != nil {
panic(fmt.Sprintf("flate.NewReader(flate.DefaultCompress) = err(%s)", err))
}
t.writer = &writeFlusher{flusher: w}
case CompressSnappy:
ioReader := io.Reader(t.conn)
t.reader = snappy.NewReader(ioReader)
ioWriter := io.Writer(t.conn)
t.writer = newSnappyWriteFlusher(snappy.NewBufferedWriter(ioWriter))
default:
panic(fmt.Sprintf("illegal comparess type %d", c))
}
t.compress = c
What you expected to happen
统一读写,避免坏流
How to reproduce it (as minimally and precisely as possible):
方案一:给 Send 函数 if t.CompressType = CompressNone 加上判定,改为
if t.CompressType = CompressNone{
// 判定 t.writer 有没有被封装成 flate
if _, isRaw := t.writer.(net.Conn); isRaw {
.....
}
}
方案二:改回 PR#102,加回 iscompress 字段判定
Anything else we need to know?:
或许可以对性能进一步优化
目前其他分支太慢了:
for _, b := range buffers {
var n int
n, err = t.writer.Write(b)
if err != nil {
break
}
lg += int64(n)
}
是否可以改用 flush?将每一个模式都封装一个函数,写入字节下沉到 writer?
What happened:
如果调用 setCompress(compressNone),会出现坏流现象,
原因:setCompress 会使得 gettyTCPconn 的 writer and reader 封装成 flate 压缩算法的接口,而 Send 函数判定CompressNone 会直接让他走系统底层 writev,这样导致读写格式不一致,代码如下
What you expected to happen
统一读写,避免坏流
How to reproduce it (as minimally and precisely as possible):
方案一:给 Send 函数 if t.CompressType = CompressNone 加上判定,改为
方案二:改回 PR#102,加回 iscompress 字段判定
Anything else we need to know?:
或许可以对性能进一步优化
目前其他分支太慢了:
是否可以改用 flush?将每一个模式都封装一个函数,写入字节下沉到 writer?