From 5ce387a7d18d5818137f5cd346f526a2bafc827e Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sun, 28 Apr 2024 22:17:46 +0800 Subject: [PATCH] Remove single_instance module and refactor existing instance check The single_instance module has been removed, which included the deletion of multiple related files. The method to check if an instance of the application is already running has been refactored in the main.go file. Additionally, a timeout was added for the "PickFiles" method in ui_impl.go to prevent unnecessary waiting. This leads to cleaner code and potentially faster execution times. --- Wox/go.mod | 1 - Wox/go.sum | 2 - Wox/main.go | 60 ++++++++++++++----- Wox/ui/ui_impl.go | 7 ++- Wox/util/location.go | 2 +- Wox/util/single_instance/README.md | 1 - Wox/util/single_instance/single_instance.go | 28 --------- .../single_instance/single_instance_posix.go | 32 ---------- .../single_instance_windows.go | 52 ---------------- 9 files changed, 53 insertions(+), 132 deletions(-) delete mode 100644 Wox/util/single_instance/README.md delete mode 100644 Wox/util/single_instance/single_instance.go delete mode 100644 Wox/util/single_instance/single_instance_posix.go delete mode 100644 Wox/util/single_instance/single_instance_windows.go diff --git a/Wox/go.mod b/Wox/go.mod index b5a870045..36d62267a 100644 --- a/Wox/go.mod +++ b/Wox/go.mod @@ -38,7 +38,6 @@ require ( github.com/tidwall/pretty v1.2.1 github.com/tmc/langchaingo v0.1.8 github.com/wissance/stringFormatter v1.2.0 - github.com/xeonx/timeago v1.0.0-rc5 go.uber.org/zap v1.27.0 golang.design/x/hotkey v0.4.1 golang.org/x/image v0.15.0 diff --git a/Wox/go.sum b/Wox/go.sum index 84d75f616..1468a070a 100644 --- a/Wox/go.sum +++ b/Wox/go.sum @@ -181,8 +181,6 @@ github.com/vcaesar/tt v0.20.0 h1:9t2Ycb9RNHcP0WgQgIaRKJBB+FrRdejuaL6uWIHuoBA= github.com/vcaesar/tt v0.20.0/go.mod h1:GHPxQYhn+7OgKakRusH7KJ0M5MhywoeLb8Fcffs/Gtg= github.com/wissance/stringFormatter v1.2.0 h1:lB0zcJkTA1O4Eb2qSTJmyapla/LihQt6NpJLghwWSb0= github.com/wissance/stringFormatter v1.2.0/go.mod h1:H7Mz15+5i8ypmv6bLknM/uD+U1teUW99PlW0DNCNscA= -github.com/xeonx/timeago v1.0.0-rc5 h1:pwcQGpaH3eLfPtXeyPA4DmHWjoQt0Ea7/++FwpxqLxg= -github.com/xeonx/timeago v1.0.0-rc5/go.mod h1:qDLrYEFynLO7y5Ho7w3GwgtYgpy5UfhcXIIQvMKVDkA= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= diff --git a/Wox/main.go b/Wox/main.go index dd87150ab..01f1f32bc 100644 --- a/Wox/main.go +++ b/Wox/main.go @@ -1,9 +1,12 @@ package main import ( + "context" "fmt" "golang.design/x/hotkey/mainthread" + "os" "runtime" + "strconv" "strings" "time" "wox/i18n" @@ -13,7 +16,6 @@ import ( "wox/ui" "wox/util" "wox/util/hotkey" - "wox/util/single_instance" ) import _ "wox/plugin/host" // import all hosts @@ -49,23 +51,22 @@ func main() { } util.GetLogger().Info(ctx, fmt.Sprintf("server port: %d", serverPort)) - existingPort, lockErr := single_instance.Lock(serverPort) - if lockErr != nil { - util.GetLogger().Error(ctx, fmt.Sprintf("there is existing instance running, port: %d, lock return: %s", existingPort, lockErr.Error())) - - if existingPort > 0 { - _, postShowErr := util.HttpPost(ctx, fmt.Sprintf("http://localhost:%d/show", existingPort), "") - if postShowErr != nil { - util.GetLogger().Error(ctx, fmt.Sprintf("failed to show existing instance: %s", postShowErr.Error())) - return - } + // check if there is existing instance running + if existingPort := getExistingInstancePort(ctx); existingPort > 0 { + util.GetLogger().Error(ctx, fmt.Sprintf("there is existing instance running, port: %d", existingPort)) + _, postShowErr := util.HttpPost(ctx, fmt.Sprintf("http://localhost:%d/show", existingPort), "") + if postShowErr != nil { + util.GetLogger().Error(ctx, fmt.Sprintf("failed to show existing instance: %s", postShowErr.Error())) } else { - util.GetLogger().Error(ctx, "failed to get existing instance port") + util.GetLogger().Info(ctx, "show existing instance successfully, bye~") } - return } else { - util.GetLogger().Info(ctx, "lock server port success") + util.GetLogger().Info(ctx, "no existing instance found") + writeErr := os.WriteFile(util.GetLocation().GetAppLockPath(), []byte(fmt.Sprintf("%d", serverPort)), 0644) + if writeErr != nil { + util.GetLogger().Error(ctx, fmt.Sprintf("failed to write lock file: %s", writeErr.Error())) + } } extractErr := resource.Extract(ctx) @@ -138,3 +139,34 @@ func main() { ui.GetUIManager().StartWebsocketAndWait(ctx, serverPort) }) } + +// retrieves the instance port from the existing instance lock file. +// It returns 0 if the lock file doesn't exist or fails to read the file. +func getExistingInstancePort(ctx context.Context) int { + filePath := util.GetLocation().GetAppLockPath() + if !util.IsFileExists(filePath) { + return 0 + } + + file, err := os.ReadFile(filePath) + if err != nil { + return 0 + } + + port, err := strconv.Atoi(string(file)) + if err != nil { + return 0 + } + + //check if the port is valid + response, err := util.HttpGet(ctx, fmt.Sprintf("http://localhost:%d/ping", port)) + if err != nil { + return 0 + } + + if !strings.Contains(string(response), "pong") { + return 0 + } + + return port +} diff --git a/Wox/ui/ui_impl.go b/Wox/ui/ui_impl.go index 4258c2f67..fcd033d07 100644 --- a/Wox/ui/ui_impl.go +++ b/Wox/ui/ui_impl.go @@ -85,8 +85,13 @@ func (u *uiImpl) send(ctx context.Context, method string, data any) (responseDat return "", err } + var timeout = time.Second * 2 + if method == "PickFiles" { + // pick files may take a long time + timeout = time.Second * 180 + } select { - case <-time.NewTimer(time.Second * 60).C: + case <-time.NewTimer(timeout).C: logger.Error(ctx, fmt.Sprintf("invoke ui method %s response timeout", method)) return "", fmt.Errorf("request timeout, request id: %s", requestID) case response := <-resultChan: diff --git a/Wox/util/location.go b/Wox/util/location.go index 4560c2a1f..bb1bcf61d 100644 --- a/Wox/util/location.go +++ b/Wox/util/location.go @@ -193,6 +193,6 @@ func (l *Location) GetUIAppPath() string { return "" } -func (l *Location) GetAppLockFilePath() string { +func (l *Location) GetAppLockPath() string { return path.Join(l.GetWoxDataDirectory(), "wox.lock") } diff --git a/Wox/util/single_instance/README.md b/Wox/util/single_instance/README.md deleted file mode 100644 index 91df9c278..000000000 --- a/Wox/util/single_instance/README.md +++ /dev/null @@ -1 +0,0 @@ -This single_instance module is inspired by the https://github.com/allan-simon/go-singleinstance \ No newline at end of file diff --git a/Wox/util/single_instance/single_instance.go b/Wox/util/single_instance/single_instance.go deleted file mode 100644 index 00c3fad99..000000000 --- a/Wox/util/single_instance/single_instance.go +++ /dev/null @@ -1,28 +0,0 @@ -package single_instance - -import ( - "fmt" - "os" - "strconv" - "wox/util" -) - -// Lock tries to lock the server port. If the port is already locked, it will return the existing server port -func Lock(serverPort int) (existingServerPort int, err error) { - if lockErr := lock(fmt.Sprintf("%d", serverPort)); lockErr != nil { - // If the file already exists, we read the content to get the existing server port - contents, readErr := os.ReadFile(util.GetLocation().GetAppLockFilePath()) - if readErr != nil { - return 0, fmt.Errorf("failed to lock: %s, and failed to read lock port: %s", lockErr.Error(), readErr.Error()) - } - - existingPort, parseErr := strconv.Atoi(string(contents)) - if parseErr != nil { - return 0, fmt.Errorf("failed to lock: %s, and failed to parse lock port: %s", lockErr.Error(), parseErr.Error()) - } - - return existingPort, lockErr - } - - return 0, nil -} diff --git a/Wox/util/single_instance/single_instance_posix.go b/Wox/util/single_instance/single_instance_posix.go deleted file mode 100644 index 089f8b11b..000000000 --- a/Wox/util/single_instance/single_instance_posix.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build !windows - -package single_instance - -import ( - "os" - "syscall" - "wox/util" -) - -func lock(content string) error { - filename := util.GetLocation().GetAppLockFilePath() - file, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600) - if err != nil { - return err - } - defer file.Close() - - err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB) - if err != nil { - return err - } - - if err := file.Truncate(0); err != nil { - return err - } - if _, err := file.WriteString(content); err != nil { - return err - } - - return nil -} diff --git a/Wox/util/single_instance/single_instance_windows.go b/Wox/util/single_instance/single_instance_windows.go deleted file mode 100644 index ba9341ec4..000000000 --- a/Wox/util/single_instance/single_instance_windows.go +++ /dev/null @@ -1,52 +0,0 @@ -//go:build windows - -package single_instance - -import ( - "os" - "syscall" - "unsafe" - "wox/util" -) - -const ( - LOCKFILE_EXCLUSIVE_LOCK = 2 -) - -var ( - kernel32 = syscall.MustLoadDLL("kernel32.dll") - procLockFileEx = kernel32.MustFindProc("LockFileEx") -) - -func LockFileEx(hFile syscall.Handle, dwFlags, dwReserved, nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh uint32, lpOverlapped *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(hFile), uintptr(dwFlags), uintptr(dwReserved), uintptr(nNumberOfBytesToLockLow), uintptr(nNumberOfBytesToLockHigh), uintptr(unsafe.Pointer(lpOverlapped))) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func lock(content string) error { - filename := util.GetLocation().GetAppLockFilePath() - file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0600) - if err != nil { - return err - } - defer file.Close() - - var overlapped syscall.Overlapped - err = LockFileEx(syscall.Handle(file.Fd()), LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &overlapped) - if err != nil { - return err - } - - if _, err := file.WriteString(content); err != nil { - return err - } - - return nil -}