Skip to content

Commit 4923be8

Browse files
committed
Revert "[cachetools] Buffer writes in UploadWriter" (#9352)
Reverts #9294
1 parent 3180821 commit 4923be8

File tree

3 files changed

+68
-253
lines changed

3 files changed

+68
-253
lines changed

server/remote_cache/cachetools/BUILD

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ go_library(
1313
"//server/interfaces",
1414
"//server/metrics",
1515
"//server/remote_cache/digest",
16-
"//server/util/bytebufferpool",
1716
"//server/util/compression",
1817
"//server/util/ioutil",
1918
"//server/util/log",
@@ -40,12 +39,10 @@ go_test(
4039
"//server/interfaces",
4140
"//server/remote_cache/digest",
4241
"//server/testutil/testcache",
43-
"//server/testutil/testdigest",
4442
"//server/testutil/testenv",
4543
"//server/util/random",
4644
"//server/util/status",
4745
"//server/util/testing/flags",
48-
"@com_github_google_go_cmp//cmp",
4946
"@com_github_stretchr_testify//assert",
5047
"@com_github_stretchr_testify//require",
5148
"@org_golang_google_genproto_googleapis_bytestream//:bytestream",

server/remote_cache/cachetools/cachetools.go

Lines changed: 68 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"github.com/buildbuddy-io/buildbuddy/server/interfaces"
1919
"github.com/buildbuddy-io/buildbuddy/server/metrics"
2020
"github.com/buildbuddy-io/buildbuddy/server/remote_cache/digest"
21-
"github.com/buildbuddy-io/buildbuddy/server/util/bytebufferpool"
2221
"github.com/buildbuddy-io/buildbuddy/server/util/compression"
2322
"github.com/buildbuddy-io/buildbuddy/server/util/ioutil"
2423
"github.com/buildbuddy-io/buildbuddy/server/util/log"
@@ -50,8 +49,6 @@ var (
5049
acRPCTimeout = flag.Duration("cache.client.ac_rpc_timeout", 15*time.Second, "Maximum time a single Action Cache RPC can take.")
5150
filecacheTreeSalt = flag.String("cache.filecache_tree_salt", "20250304", "A salt to invalidate filecache tree hashes, if/when needed.")
5251
requestCachedSubtreeDigests = flag.Bool("cache.request_cached_subtree_digests", true, "If true, GetTree requests will set send_cached_subtree_digests.")
53-
54-
uploadBufPool = bytebufferpool.FixedSize(uploadBufSizeBytes)
5552
)
5653

5754
func retryOptions(name string) *retry.Options {
@@ -258,29 +255,19 @@ func uploadFromReader(ctx context.Context, bsClient bspb.ByteStreamClient, r *di
258255
}
259256

260257
if r.GetCompressor() == repb.Compressor_IDENTITY {
261-
w, err := NewUploadWriter(ctx, bsClient, r)
258+
w, err := newUploadWriteCloser(ctx, bsClient, r)
262259
if err != nil {
263260
return nil, 0, err
264261
}
265-
defer w.Close()
266-
bytesRead, err := w.ReadFrom(in)
262+
bytesUploaded, err := w.ReadFrom(in)
267263
if err != nil {
264+
w.Close()
268265
return nil, 0, err
269266
}
270-
if err := w.Commit(); err != nil {
271-
return nil, 0, err
272-
}
273-
// Either the write succeeded or was short-circuited, but in
274-
// either case, the remoteSize for uncompressed uploads should
275-
// match the file size.
276-
committedSize, err := w.GetCommittedSize()
277-
if err != nil {
267+
if err := w.Close(); err != nil {
278268
return nil, 0, err
279269
}
280-
if committedSize != r.GetDigest().GetSizeBytes() {
281-
return nil, 0, status.DataLossErrorf("Remote size (%d) != uploaded size: (%d)", committedSize, r.GetDigest().GetSizeBytes())
282-
}
283-
return r.GetDigest(), bytesRead, nil
270+
return r.GetDigest(), bytesUploaded, nil
284271
}
285272

286273
stream, err := bsClient.Write(ctx)
@@ -336,15 +323,24 @@ func uploadFromReader(ctx context.Context, bsClient bspb.ByteStreamClient, r *di
336323
return nil, 0, err
337324
}
338325

339-
committedSize := rsp.GetCommittedSize()
340-
// -1 is returned if the blob already exists, otherwise the
341-
// remoteSize should agree with what we uploaded.
342-
if committedSize != bytesUploaded && committedSize != -1 {
343-
return nil, 0, status.DataLossErrorf("Remote size (%d) != uploaded size: (%d)", committedSize, r.GetDigest().GetSizeBytes())
326+
remoteSize := rsp.GetCommittedSize()
327+
if r.GetCompressor() == repb.Compressor_IDENTITY {
328+
// Either the write succeeded or was short-circuited, but in
329+
// either case, the remoteSize for uncompressed uploads should
330+
// match the file size.
331+
if remoteSize != r.GetDigest().GetSizeBytes() {
332+
return nil, 0, status.DataLossErrorf("Remote size (%d) != uploaded size: (%d)", remoteSize, r.GetDigest().GetSizeBytes())
333+
}
334+
} else {
335+
// -1 is returned if the blob already exists, otherwise the
336+
// remoteSize should agree with what we uploaded.
337+
if remoteSize != bytesUploaded && remoteSize != -1 {
338+
return nil, 0, status.DataLossErrorf("Remote size (%d) != uploaded size: (%d)", remoteSize, r.GetDigest().GetSizeBytes())
339+
}
344340
}
345341

346342
// At this point, a remote size of -1 means nothing new was uploaded.
347-
if committedSize == -1 {
343+
if remoteSize == -1 {
348344
bytesUploaded = 0
349345
}
350346

@@ -1117,130 +1113,91 @@ func maybeSetCompressor(rn *digest.CASResourceName) {
11171113
}
11181114
}
11191115

1120-
type UploadWriter struct {
1116+
type uploadWriteCloser struct {
11211117
ctx context.Context
11221118
stream bspb.ByteStream_WriteClient
11231119
sender rpcutil.Sender[*bspb.WriteRequest]
1120+
resource *digest.CASResourceName
11241121
uploadString string
11251122

11261123
bytesUploaded int64
1127-
finished bool
1128-
committedSize int64
1129-
closed bool
1130-
1131-
buf []byte
1132-
bytesBuffered int
11331124
}
11341125

1135-
// Assert that UploadWriter implements CommittedWriteCloser
1136-
var _ interfaces.CommittedWriteCloser = (*UploadWriter)(nil)
1137-
1138-
func (uw *UploadWriter) Write(p []byte) (int, error) {
1139-
if uw.finished || uw.closed {
1140-
return 0, status.FailedPreconditionError("Cannot write to UploadWriter after it is finished or closed")
1141-
}
1126+
func (cwc *uploadWriteCloser) Write(p []byte) (int, error) {
11421127
written := 0
11431128
for len(p) > 0 {
1144-
n := copy(uw.buf[uw.bytesBuffered:], p)
1145-
uw.bytesBuffered += n
1146-
if uw.bytesBuffered == uploadBufSizeBytes {
1147-
if err := uw.flush(false /* finish */); err != nil {
1148-
return written, err
1129+
n := min(len(p), uploadBufSizeBytes)
1130+
req := &bspb.WriteRequest{
1131+
Data: p[:n],
1132+
ResourceName: cwc.uploadString,
1133+
WriteOffset: cwc.bytesUploaded + int64(written),
1134+
FinishWrite: false,
1135+
}
1136+
1137+
err := cwc.sender.SendWithTimeoutCause(req, *casRPCTimeout, status.DeadlineExceededError("Timed out sending Write request"))
1138+
if err != nil {
1139+
if err == io.EOF {
1140+
break
11491141
}
1142+
cwc.bytesUploaded += int64(written)
1143+
return written, err
11501144
}
11511145
written += n
11521146
p = p[n:]
11531147
}
1148+
cwc.bytesUploaded += int64(written)
11541149
return written, nil
11551150
}
11561151

1157-
func (uw *UploadWriter) flush(finish bool) error {
1158-
if uw.finished || uw.closed {
1159-
return status.FailedPreconditionError("UploadWriteCloser already finished or closed, cannot flush")
1160-
}
1161-
req := &bspb.WriteRequest{
1162-
Data: uw.buf[:uw.bytesBuffered],
1163-
ResourceName: uw.uploadString,
1164-
WriteOffset: uw.bytesUploaded,
1165-
FinishWrite: finish,
1166-
}
1167-
err := uw.sender.SendWithTimeoutCause(req, *casRPCTimeout, status.DeadlineExceededError("Timed out sending Write request"))
1168-
if err != nil {
1169-
return err
1170-
}
1171-
uw.bytesUploaded += int64(uw.bytesBuffered)
1172-
uw.bytesBuffered = 0
1173-
uw.finished = finish
1174-
return nil
1175-
}
1176-
1177-
func (uw *UploadWriter) ReadFrom(r io.Reader) (int64, error) {
1178-
if uw.finished || uw.closed {
1179-
return 0, status.FailedPreconditionError("UploadWriter cannot ReadFrom after it is finished or closed")
1180-
}
1181-
bytesRead := int64(0)
1152+
func (cwc *uploadWriteCloser) ReadFrom(r io.Reader) (int64, error) {
1153+
buf := make([]byte, uploadBufSizeBytes)
1154+
var bytesUploaded int64
11821155
for {
1183-
n, err := ioutil.ReadTryFillBuffer(r, uw.buf[uw.bytesBuffered:])
1184-
uw.bytesBuffered += n
1185-
bytesRead += int64(n)
1156+
n, err := ioutil.ReadTryFillBuffer(r, buf)
11861157
done := err == io.EOF
11871158
if err != nil && !done {
1188-
return bytesRead, err
1159+
return bytesUploaded, err
11891160
}
1190-
if uw.bytesBuffered == uploadBufSizeBytes {
1191-
if err := uw.flush(false /* finish */); err != nil {
1192-
return bytesRead, err
1193-
}
1161+
written, err := cwc.Write(buf[:n])
1162+
if err != nil {
1163+
return bytesUploaded + int64(written), err
11941164
}
1165+
bytesUploaded += int64(written)
11951166
if done {
11961167
break
11971168
}
11981169
}
1199-
return bytesRead, nil
1170+
return bytesUploaded, nil
12001171
}
12011172

1202-
func (uw *UploadWriter) Commit() error {
1203-
if uw.closed {
1204-
return status.FailedPreconditionError("UploadWriteCloser already closed, cannot commit")
1205-
}
1206-
if uw.finished {
1207-
return status.FailedPreconditionError("UploadWriteCloser already committed, cannot commit again")
1208-
}
1209-
if err := uw.flush(true /* finish */); err != nil {
1210-
return err
1173+
func (cwc *uploadWriteCloser) Close() error {
1174+
req := &bspb.WriteRequest{
1175+
ResourceName: cwc.uploadString,
1176+
WriteOffset: cwc.bytesUploaded,
1177+
FinishWrite: true,
12111178
}
1212-
rsp, err := uw.stream.CloseAndRecv()
1179+
1180+
err := cwc.sender.SendWithTimeoutCause(req, *casRPCTimeout, status.DeadlineExceededError("Timed out sending Write request"))
12131181
if err != nil {
12141182
return err
12151183
}
1216-
uw.committedSize = rsp.GetCommittedSize()
1217-
return nil
1218-
}
12191184

1220-
func (uw *UploadWriter) Close() error {
1221-
if uw.closed {
1222-
return status.FailedPreconditionError("UploadWriteCloser already closed, cannot close again")
1185+
rsp, err := cwc.stream.CloseAndRecv()
1186+
if err != nil {
1187+
return err
12231188
}
1224-
uw.closed = true
1225-
uploadBufPool.Put(uw.buf)
1226-
return uw.stream.CloseSend()
1227-
}
12281189

1229-
func (uw *UploadWriter) GetCommittedSize() (int64, error) {
1230-
if !uw.finished {
1231-
return 0, status.FailedPreconditionError("UploadWriter not committed, cannot get committed size")
1190+
remoteSize := rsp.GetCommittedSize()
1191+
// Either the write succeeded or was short-circuited, but in
1192+
// either case, the remoteSize for uncompressed uploads should
1193+
// match the file size.
1194+
if remoteSize != cwc.resource.GetDigest().GetSizeBytes() {
1195+
return status.DataLossErrorf("Remote size (%d) != uploaded size: (%d)", remoteSize, cwc.resource.GetDigest().GetSizeBytes())
12321196
}
1233-
return uw.committedSize, nil
1234-
}
1235-
1236-
func (uw *UploadWriter) GetBytesUploaded() int64 {
1237-
return uw.bytesUploaded
1197+
return nil
12381198
}
12391199

1240-
// NewUploadWriter returns an UploadWriter that writes to the CAS for the specific resource name.
1241-
// The blob is guaranteed to be written to the CAS only if all Write(...) calls and the Close() call succeed.
1242-
// The caller is responsible for checking data integrity using GetCommittedSize() and GetBytesUploaded().
1243-
func NewUploadWriter(ctx context.Context, bsClient bspb.ByteStreamClient, r *digest.CASResourceName) (*UploadWriter, error) {
1200+
func newUploadWriteCloser(ctx context.Context, bsClient bspb.ByteStreamClient, r *digest.CASResourceName) (*uploadWriteCloser, error) {
12441201
if bsClient == nil {
12451202
return nil, status.FailedPreconditionError("ByteStreamClient not configured")
12461203
}
@@ -1252,11 +1209,11 @@ func NewUploadWriter(ctx context.Context, bsClient bspb.ByteStreamClient, r *dig
12521209
return nil, err
12531210
}
12541211
sender := rpcutil.NewSender[*bspb.WriteRequest](ctx, stream)
1255-
return &UploadWriter{
1212+
return &uploadWriteCloser{
12561213
ctx: ctx,
12571214
stream: stream,
12581215
sender: sender,
1216+
resource: r,
12591217
uploadString: r.NewUploadString(),
1260-
buf: uploadBufPool.Get(),
12611218
}, nil
12621219
}

0 commit comments

Comments
 (0)