Config: Use mutex when resolving the path of external binaries
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
parent
9a3015a818
commit
38722e72c8
5 changed files with 29 additions and 19 deletions
|
@ -4,7 +4,7 @@ import "github.com/photoprism/photoprism/internal/ffmpeg"
|
|||
|
||||
// FFmpegBin returns the ffmpeg executable file name.
|
||||
func (c *Config) FFmpegBin() string {
|
||||
return findExecutable(c.options.FFmpegBin, "ffmpeg")
|
||||
return findBin(c.options.FFmpegBin, "ffmpeg")
|
||||
}
|
||||
|
||||
// FFmpegEnabled checks if FFmpeg is enabled for video transcoding.
|
||||
|
|
|
@ -8,40 +8,50 @@ import (
|
|||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// binPaths stores known executable paths.
|
||||
var binPaths = make(map[string]string, 8)
|
||||
var tempPath = ""
|
||||
var (
|
||||
binPaths = make(map[string]string, 8)
|
||||
binMu = sync.RWMutex{}
|
||||
tempPath = ""
|
||||
)
|
||||
|
||||
// findExecutable searches binaries by their name.
|
||||
func findExecutable(configBin, defaultBin string) (binPath string) {
|
||||
// Cached?
|
||||
// findBin resolves the absolute file path of external binaries.
|
||||
func findBin(configBin, defaultBin string) (binPath string) {
|
||||
cacheKey := defaultBin + configBin
|
||||
if cached, ok := binPaths[cacheKey]; ok {
|
||||
binMu.RLock()
|
||||
cached, found := binPaths[cacheKey]
|
||||
binMu.RUnlock()
|
||||
|
||||
// Already found?
|
||||
if found {
|
||||
return cached
|
||||
}
|
||||
|
||||
// Default if config value is empty.
|
||||
// Default binary name?
|
||||
if configBin == "" {
|
||||
binPath = defaultBin
|
||||
} else {
|
||||
binPath = configBin
|
||||
}
|
||||
|
||||
// Search.
|
||||
// Search for binary.
|
||||
if path, err := exec.LookPath(binPath); err == nil {
|
||||
binPath = path
|
||||
}
|
||||
|
||||
// Exists?
|
||||
// Found?
|
||||
if !fs.FileExists(binPath) {
|
||||
binPath = ""
|
||||
} else {
|
||||
binMu.Lock()
|
||||
binPaths[cacheKey] = binPath
|
||||
binMu.Unlock()
|
||||
}
|
||||
|
||||
return binPath
|
||||
|
@ -481,17 +491,17 @@ func (c *Config) TestdataPath() string {
|
|||
|
||||
// MysqlBin returns the mysql executable file name.
|
||||
func (c *Config) MysqlBin() string {
|
||||
return findExecutable("", "mysql")
|
||||
return findBin("", "mysql")
|
||||
}
|
||||
|
||||
// MysqldumpBin returns the mysqldump executable file name.
|
||||
func (c *Config) MysqldumpBin() string {
|
||||
return findExecutable("", "mysqldump")
|
||||
return findBin("", "mysqldump")
|
||||
}
|
||||
|
||||
// SqliteBin returns the sqlite executable file name.
|
||||
func (c *Config) SqliteBin() string {
|
||||
return findExecutable("", "sqlite3")
|
||||
return findBin("", "sqlite3")
|
||||
}
|
||||
|
||||
// AlbumsPath returns the storage path for album YAML files.
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
func TestConfig_FindExecutable(t *testing.T) {
|
||||
assert.Equal(t, "", findExecutable("yyy", "xxx"))
|
||||
assert.Equal(t, "", findBin("yyy", "xxx"))
|
||||
}
|
||||
|
||||
func TestConfig_SidecarPath(t *testing.T) {
|
||||
|
|
|
@ -7,7 +7,7 @@ func (c *Config) ExifBruteForce() bool {
|
|||
|
||||
// ExifToolBin returns the exiftool executable file name.
|
||||
func (c *Config) ExifToolBin() string {
|
||||
return findExecutable(c.options.ExifToolBin, "exiftool")
|
||||
return findBin(c.options.ExifToolBin, "exiftool")
|
||||
}
|
||||
|
||||
// ExifToolJson checks if creating JSON metadata sidecar files with Exiftool is enabled.
|
||||
|
|
|
@ -18,7 +18,7 @@ func (c *Config) RawPresets() bool {
|
|||
|
||||
// DarktableBin returns the darktable-cli executable file name.
|
||||
func (c *Config) DarktableBin() string {
|
||||
return findExecutable(c.options.DarktableBin, "darktable-cli")
|
||||
return findBin(c.options.DarktableBin, "darktable-cli")
|
||||
}
|
||||
|
||||
// DarktableBlacklist returns the darktable file extension blacklist.
|
||||
|
@ -73,7 +73,7 @@ func (c *Config) DarktableEnabled() bool {
|
|||
|
||||
// RawtherapeeBin returns the rawtherapee-cli executable file name.
|
||||
func (c *Config) RawtherapeeBin() string {
|
||||
return findExecutable(c.options.RawtherapeeBin, "rawtherapee-cli")
|
||||
return findBin(c.options.RawtherapeeBin, "rawtherapee-cli")
|
||||
}
|
||||
|
||||
// RawtherapeeBlacklist returns the RawTherapee file extension blacklist.
|
||||
|
@ -93,7 +93,7 @@ func (c *Config) SipsEnabled() bool {
|
|||
|
||||
// SipsBin returns the SIPS executable file name.
|
||||
func (c *Config) SipsBin() string {
|
||||
return findExecutable(c.options.SipsBin, "sips")
|
||||
return findBin(c.options.SipsBin, "sips")
|
||||
}
|
||||
|
||||
// SipsBlacklist returns the Sips file extension blacklist.
|
||||
|
@ -103,7 +103,7 @@ func (c *Config) SipsBlacklist() string {
|
|||
|
||||
// HeifConvertBin returns the heif-convert executable file name.
|
||||
func (c *Config) HeifConvertBin() string {
|
||||
return findExecutable(c.options.HeifConvertBin, "heif-convert")
|
||||
return findBin(c.options.HeifConvertBin, "heif-convert")
|
||||
}
|
||||
|
||||
// HeifConvertEnabled checks if heif-convert is enabled for HEIF conversion.
|
||||
|
|
Loading…
Reference in a new issue