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:
authorAlejandro Rodríguez <alejorro70@gmail.com>2016-12-23 03:12:39 +0300
committerAlejandro Rodríguez <alejorro70@gmail.com>2016-12-23 03:12:39 +0300
commite554214aaa8ab3c5186c817781d8c83428f60f0c (patch)
treeefe661f0ca5ab4220f5ef0d5c341c78517b0da50
parent577ed944fadf424e28e08f83e5f6784d8ea57d98 (diff)
Add function to cache calls to git-upload-pack and git-receive-packinfo-refs
-rw-r--r--caching/refs.go82
-rw-r--r--caching/resf_test.go23
2 files changed, 97 insertions, 8 deletions
diff --git a/caching/refs.go b/caching/refs.go
index dd0d6fa3a..252ecea66 100644
--- a/caching/refs.go
+++ b/caching/refs.go
@@ -1,7 +1,12 @@
package caching
import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
"os"
+ "os/exec"
"path"
"syscall"
@@ -11,8 +16,7 @@ import (
type RefsCache struct {
repositoryPath string
cacheDir string
- uploadCachePath string
- receiveCachePath string
+ cachePaths map[string]string
lockFd int
}
@@ -43,8 +47,10 @@ func NewRefsCache(repositoryPath string) *RefsCache {
repositoryPath: repositoryPath,
cacheDir: cacheDir,
lockFd: lockFd,
- uploadCachePath: path.Join(cacheDir, "upload-pack"),
- receiveCachePath: path.Join(cacheDir, "receive-pack"),
+ cachePaths: map[string]string {
+ "upload-pack": path.Join(cacheDir, "upload-pack"),
+ "receive-pack": path.Join(cacheDir, "receive-pack"),
+ },
}
}
@@ -68,6 +74,18 @@ func (r *RefsCache) Unlock() {
}
}
+func (r *RefsCache) GetLockUuid() string {
+ var buf [4096]byte
+
+ syscall.Seek(r.lockFd, 0, 0) // Rewind to the start of the file
+ n, err := syscall.Read(r.lockFd, buf[:])
+ if err != nil {
+ panic(err)
+ }
+
+ return string(buf[:n])
+}
+
func (r *RefsCache) InvalidateCache() {
r.Lock()
defer r.Unlock()
@@ -79,6 +97,58 @@ func (r *RefsCache) InvalidateCache() {
syscall.Write(r.lockFd, []byte(newUuid.String()))
// Remove cache files
- os.Remove(r.uploadCachePath)
- os.Remove(r.receiveCachePath)
+ for _, cachePath := range r.cachePaths {
+ os.Remove(cachePath)
+ }
+}
+
+func (r *RefsCache) ExecuteToFile(command string, f *os.File) {
+ var out bytes.Buffer
+ cmd := exec.Command("git", command, "--stateless-rpc", "--advertise-refs", r.repositoryPath)
+ cmd.Stdout = &out
+
+ err := cmd.Run()
+ if err != nil {
+ panic(err)
+ }
+
+ // Print to Stdout
+ out.WriteTo(os.Stdout)
+
+ // Print to file
+ _, err = f.Write(out.Bytes())
+ if err != nil {
+ panic(err)
+ }
+}
+
+func (r *RefsCache) Cache(command string) error {
+ if command != "upload-pack" && command != "receive-pack" {
+ return fmt.Errorf("Invalid command")
+ }
+
+ r.Lock()
+ defer r.Unlock()
+
+ currentUuid := r.GetLockUuid()
+ fmt.Printf(path.Join(os.TempDir(), "command_output"))
+ tempFile, err := ioutil.TempFile(os.TempDir(), "command_output")
+ if err != nil {
+ panic(err)
+ }
+ defer tempFile.Close()
+
+ r.ExecuteToFile(command, tempFile)
+
+ if newUuid := r.GetLockUuid(); currentUuid == newUuid {
+ cacheFile, err := os.Create(r.cachePaths[command])
+ if err != nil {
+ panic(err)
+ }
+ defer cacheFile.Close()
+ tempFile.Seek(0, 0) // Reset tempFile to the start of the file
+ io.Copy(cacheFile, tempFile)
+ }
+
+ return nil
}
diff --git a/caching/resf_test.go b/caching/resf_test.go
index 565d63860..ca3ab580b 100644
--- a/caching/resf_test.go
+++ b/caching/resf_test.go
@@ -3,6 +3,7 @@ package caching
import (
"io/ioutil"
"os"
+ "os/exec"
"path"
"syscall"
"testing"
@@ -36,10 +37,28 @@ func TestInvalidateCache(t *testing.T) {
t.Error("Expected InvalidateCache to rewrite lock")
}
- if _, err := os.Stat(r.uploadCachePath); !os.IsNotExist(err) {
+ if _, err := os.Stat(r.cachePaths["upload-pack"]); !os.IsNotExist(err) {
t.Error("Expected InvalidateCache to remove upload-pack cache")
}
- if _, err := os.Stat(r.receiveCachePath); !os.IsNotExist(err) {
+ if _, err := os.Stat(r.cachePaths["receive-pack"]); !os.IsNotExist(err) {
t.Error("Expected InvalidateCache to remove receive-pack cache")
}
}
+
+func TestCache(t *testing.T) {
+ source := "https://gitlab.com/gitlab-org/gitlab-test.git"
+ repoDir := path.Join(tmpDir, "gitlab-test")
+ exec.Command("git", "clone", "--bare", source, repoDir).Run()
+ r := NewRefsCache(repoDir)
+ defer os.RemoveAll(tmpDir)
+
+ if err := r.Cache("non-existing-command"); err.Error() != "Invalid command" {
+ t.Error("Expected Cache to fail with \"Invalid command\"")
+ }
+
+ r.Cache("upload-pack")
+
+ if _, err := os.Stat(r.cachePaths["upload-pack"]); os.IsNotExist(err) {
+ t.Error("Expected Cache to create upload-pack cache")
+ }
+}