diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2021-11-12 13:01:46 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2021-11-15 10:44:51 +0300 |
commit | 9053c88cff96fc2e5eeebcddfec0edcd096ddfb0 (patch) | |
tree | 5c957d9509df55f760b8968eb41948ad96df055d | |
parent | 3dbe00d31b26f0cf0d3d247664d7b4e977297144 (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.go | 2 | ||||
-rw-r--r-- | internal/git/catfile/object_reader.go | 2 | ||||
-rw-r--r-- | internal/git/catfile/request_queue.go | 15 |
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 } |