in src/main/java/build/buildfarm/server/WriteStreamObserver.java [293:357]
private void handleWrite(String resourceName, long offset, ByteString data, boolean finishWrite)
throws EntryLimitException {
long committedSize;
try {
committedSize = getCommittedSizeForWrite();
} catch (IOException e) {
errorResponse(e);
return;
}
if (offset != 0 && offset > committedSize) {
// we are synchronized here for delivery, but not for asynchronous completion
// of the write - if it has completed already, and that is the source of the
// offset mismatch, perform nothing further and release sync to allow the
// callback to complete the write
//
// ABORTED response is specific to encourage the client to retry
errorResponse(
ABORTED
.withDescription(
format("offset %d does not match committed size %d", offset, committedSize))
.asException());
} else if (!resourceName.equals(name)) {
errorResponse(
INVALID_ARGUMENT
.withDescription(
format(
"request resource_name %s does not match previous resource_name %s",
resourceName, name))
.asException());
} else {
if (offset == 0 && offset != committedSize) {
write.reset();
committedSize = 0;
}
if (earliestOffset < 0 || offset < earliestOffset) {
earliestOffset = offset;
}
// we may have a committedSize that is larger than our offset, in which case we want
// to skip the data bytes until the committedSize. This is practical with our streams,
// since they should be the same content between offset and committedSize
int bytesToWrite = data.size();
if (bytesToWrite == 0 || committedSize - offset >= bytesToWrite) {
requestNextIfReady();
} else {
// constrained to be within bytesToWrite
bytesToWrite -= (int) (committedSize - offset);
int skipBytes = data.size() - bytesToWrite;
if (skipBytes != 0) {
data = data.substring(skipBytes);
}
logger.log(
Level.FINER,
format(
"writing %d to %s at %d%s",
bytesToWrite, name, offset, finishWrite ? " with finish_write" : ""));
writeData(data);
requestCount++;
requestBytes += data.size();
}
if (finishWrite) {
close();
}
}
}