Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <psteinhardt@gitlab.com>2021-11-12 13:01:46 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2021-11-15 10:44:51 +0300
commit9053c88cff96fc2e5eeebcddfec0edcd096ddfb0 (patch)
tree5c957d9509df55f760b8968eb41948ad96df055d
parent3dbe00d31b26f0cf0d3d247664d7b4e977297144 (diff)
catfile: Use buffered writes to queue requests
When requesting objects or object info from the request queues, we're writing the request directly into the command's pipe. This thus amounts to one syscall per request, which is excessive and causes problems in production due to the resulting context switches. Convert the code to instead use a buffered writer to batch several requests into a single write. Flushing the request queue is extended to also flush out this buffered writer. Changelog: performance
-rw-r--r--internal/git/catfile/object_info_reader.go2
-rw-r--r--internal/git/catfile/object_reader.go2
-rw-r--r--internal/git/catfile/request_queue.go15
3 files changed, 14 insertions, 5 deletions
diff --git a/internal/git/catfile/object_info_reader.go b/internal/git/catfile/object_info_reader.go
index c551b9777..a6f7d4db7 100644
--- a/internal/git/catfile/object_info_reader.go
+++ b/internal/git/catfile/object_info_reader.go
@@ -150,7 +150,7 @@ func newObjectInfoReader(
counter: counter,
queue: requestQueue{
stdout: bufio.NewReader(batchCmd),
- stdin: batchCmd,
+ stdin: bufio.NewWriter(batchCmd),
},
}
go func() {
diff --git a/internal/git/catfile/object_reader.go b/internal/git/catfile/object_reader.go
index b1ed8650f..44dee1ddc 100644
--- a/internal/git/catfile/object_reader.go
+++ b/internal/git/catfile/object_reader.go
@@ -82,7 +82,7 @@ func newObjectReader(
queue: requestQueue{
isObjectQueue: true,
stdout: bufio.NewReader(batchCmd),
- stdin: batchCmd,
+ stdin: bufio.NewWriter(batchCmd),
},
}
go func() {
diff --git a/internal/git/catfile/request_queue.go b/internal/git/catfile/request_queue.go
index 178d29fbc..72ac794e0 100644
--- a/internal/git/catfile/request_queue.go
+++ b/internal/git/catfile/request_queue.go
@@ -17,7 +17,7 @@ type requestQueue struct {
isObjectQueue bool
stdout *bufio.Reader
- stdin io.Writer
+ stdin *bufio.Writer
// outstandingRequests is the number of requests which have been queued up. Gets incremented
// on request, and decremented when starting to read an object (not when that object has
@@ -76,9 +76,14 @@ func (q *requestQueue) RequestRevision(revision git.Revision) error {
atomic.AddInt64(&q.outstandingRequests, 1)
- if _, err := fmt.Fprintln(q.stdin, revision.String()); err != nil {
+ if _, err := q.stdin.WriteString(revision.String()); err != nil {
atomic.AddInt64(&q.outstandingRequests, -1)
- return fmt.Errorf("requesting revision: %w", err)
+ return fmt.Errorf("writing object request: %w", err)
+ }
+
+ if err := q.stdin.WriteByte('\n'); err != nil {
+ atomic.AddInt64(&q.outstandingRequests, -1)
+ return fmt.Errorf("terminating object request: %w", err)
}
return nil
@@ -89,6 +94,10 @@ func (q *requestQueue) Flush() error {
return fmt.Errorf("cannot flush: %w", os.ErrClosed)
}
+ if err := q.stdin.Flush(); err != nil {
+ return fmt.Errorf("flushing: %w", err)
+ }
+
return nil
}