Skip to content

Commit

Permalink
use hardlinks for plugin cache copy to save resources
Browse files Browse the repository at this point in the history
  • Loading branch information
asiyani committed Dec 31, 2024
1 parent 9be57dd commit 86cdde4
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 25 deletions.
2 changes: 1 addition & 1 deletion integration_test/module_controller_with_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ var _ = Describe("Module controller with Runner", func() {
var dst string
testRepos.EXPECT().Clone(gomock.Any(), "https://host.xy/dummy/repo.git", gomock.AssignableToTypeOf(dst), "HEAD", "", true).
DoAndReturn(func(ctx context.Context, remote, dst, branch, pathspec string, rmGitDir bool) (string, error) {
return "commit124", sysutil.CopyDir(context.TODO(), filepath.Join("src", "modules"), dst, true)
return "commit124", sysutil.CopyDirWithHardLinks(context.TODO(), filepath.Join("src", "modules"), dst)
}).AnyTimes()

testMetrics.EXPECT().UpdateModuleRunDuration(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
Expand Down
4 changes: 2 additions & 2 deletions runner/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (pcp *pluginCache) new() string {
pcp.RLock()
defer pcp.RUnlock()

if err := sysutil.CopyDir(ctx, pcp.main, tmpPC, true); err != nil {
if err := sysutil.CopyDirWithHardLinks(ctx, pcp.main, tmpPC); err != nil {
pcp.log.Error("unable to create copy providers to plugin cache dir", "err", err)
sysutil.RemoveAll(tmpPC)
return ""
Expand All @@ -94,7 +94,7 @@ func (pcp *pluginCache) done(tmpPC string) {
pcp.Lock()
defer pcp.Unlock()

if err := sysutil.CopyDir(ctx, tmpPC, pcp.main, false); err != nil {
if err := sysutil.CopyDirWithHardLinks(ctx, tmpPC, pcp.main); err != nil {
pcp.log.Error("unable to create copy tmp to main dir", "err", err)
}
}
33 changes: 13 additions & 20 deletions sysutil/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,29 @@ func RemoveAll(dir string) error {
return cmd.Run()
}

// CopyFile copies a file
func CopyFile(src, dst string, withReplace bool) error {
// HardLinkFile creates hard link if dst doesn't exits
func HardLinkFile(src, dst string) error {
var err error
var srcInfo os.FileInfo

if srcInfo, err = os.Stat(src); err != nil {
return err
}

if !withReplace {
// skip if dst file already exits
if dstInfo, err := os.Stat(dst); err == nil {
if srcInfo.Name() == dstInfo.Name() &&
srcInfo.Size() == dstInfo.Size() {
return nil
}
// skip if dst file already exits
if dstInfo, err := os.Stat(dst); err == nil {
if srcInfo.Name() == dstInfo.Name() {
return nil
}
}

// create hard link to save cpu/mem/disk io
// once plugin binary is downloaded it will not be modified hence
// we can use hard link instead of copy to save resources and time.
return os.Link(src, dst)
}

// CopyDir copies a dir recursively
func CopyDir(ctx context.Context, src string, dst string, withReplace bool) error {
// CopyDirWithHardLinks creates hard links of files from src recursively at dst
func CopyDirWithHardLinks(ctx context.Context, src string, dst string) error {
var err error
var fileDescriptors []os.DirEntry
var srcInfo os.FileInfo
Expand All @@ -66,17 +64,12 @@ func CopyDir(ctx context.Context, src string, dst string, withReplace bool) erro
dstPath := path.Join(dst, fd.Name())

if fd.IsDir() {
if err := CopyDir(ctx, srcPath, dstPath, withReplace); err != nil {
if err := CopyDirWithHardLinks(ctx, srcPath, dstPath); err != nil {
return err
}
} else {
select {
case <-ctx.Done():
return ctx.Err()
default:
if err := CopyFile(srcPath, dstPath, withReplace); err != nil {
return err
}
if err := HardLinkFile(srcPath, dstPath); err != nil {
return err
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions sysutil/filesystem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestCopyDirWithReplace(t *testing.T) {
}

// Copy the directory.
err := CopyDir(context.TODO(), srcDir, dstDir, true)
err := CopyDirWithHardLinks(context.TODO(), srcDir, dstDir)
if err != nil {
t.Fatalf("error copying directory: %v", err)
}
Expand Down Expand Up @@ -123,7 +123,7 @@ func TestCopyDirWithoutReplace(t *testing.T) {
}

// Copy the directory.
err := CopyDir(context.TODO(), srcDir, dstDir, false)
err := CopyDirWithHardLinks(context.TODO(), srcDir, dstDir)
if err != nil {
t.Fatalf("error copying directory: %v", err)
}
Expand Down

0 comments on commit 86cdde4

Please sign in to comment.