Per the io.Writer documentation:
type Writer interface {
Write(p []byte) (n int, err error)
}
[...]
Implementations must not retain p.
While the implementations:
|
func (w *readStreamWriter) Write(p []byte) (int, error) { |
|
if err := w.out.Send(&bytestream.ReadResponse{Data: p}); err != nil { |
|
return 0, err |
|
} |
|
return len(p), nil |
|
} |
|
func (w *zstdByteStreamWriter) Write(p []byte) (int, error) { |
|
if err := w.client.Send(&bytestream.WriteRequest{ |
|
ResourceName: w.resourceName, |
|
WriteOffset: w.writeOffset, |
|
Data: p, |
|
}); err != nil { |
|
return 0, err |
|
} |
|
w.writeOffset += int64(len(p)) |
|
w.resourceName = "" |
|
return len(p), nil |
|
} |
call ByteStream_ReadServer.Send and ByteStream_WriteClient.Send which in turn call ServerStream.SendMsg and ClientStream.SendMsg both of which document:
// It is not safe to modify the message after calling SendMsg. Tracing
// libraries and stats handlers may use the message lazily.
Thus these implementations are unsound.
It is not possible to soundly implement io.Writer on top of ClientStream.SendMsg or ServerStream.SendMsg without internally copying (and allocating, because grpc never lets us know when buffers passed into it can be safely reused).
Per the
io.Writerdocumentation:While the implementations:
bb-storage/pkg/blobstore/grpcservers/byte_stream_server.go
Lines 83 to 88 in 37f0e8b
bb-storage/pkg/blobstore/grpcclients/cas_blob_access.go
Lines 122 to 133 in 37f0e8b
call
ByteStream_ReadServer.SendandByteStream_WriteClient.Sendwhich in turn callServerStream.SendMsgandClientStream.SendMsgboth of which document:Thus these implementations are unsound.
It is not possible to soundly implement
io.Writeron top ofClientStream.SendMsgorServerStream.SendMsgwithout internally copying (and allocating, because grpc never lets us know when buffers passed into it can be safely reused).