isLockFileStale checks if the lock file exists but no process is using it. This function attempts to determine if a BadgerDB lock file is stale by checking if the process that created it is still running.
(lockFilePath string)
| 92 | // This function attempts to determine if a BadgerDB lock file is stale by |
| 93 | // checking if the process that created it is still running. |
| 94 | func isLockFileStale(lockFilePath string) (bool, error) { |
| 95 | // Read the lock file to get the PID |
| 96 | // #nosec G304 -- lockFilePath is constructed internally, not from user input |
| 97 | data, err := os.ReadFile(lockFilePath) |
| 98 | if err != nil { |
| 99 | // Can't read the file, consider it not stale (safer default) |
| 100 | return false, fmt.Errorf("failed to read lock file: %w", err) |
| 101 | } |
| 102 | |
| 103 | // BadgerDB lock files typically contain just a PID |
| 104 | // Try to parse it as an integer |
| 105 | var pid int |
| 106 | if _, err := fmt.Sscanf(string(data), "%d", &pid); err != nil { |
| 107 | // Invalid lock file format, might be corrupted - consider it stale |
| 108 | getCacheLogger().Debug("Lock file has invalid format, considering stale") |
| 109 | return true, nil |
| 110 | } |
| 111 | |
| 112 | // Check if the process exists by trying to find it |
| 113 | process, err := os.FindProcess(pid) |
| 114 | if err != nil { |
| 115 | // Process doesn't exist (on some systems FindProcess always succeeds) |
| 116 | getCacheLogger().Debug("Process %d not found, lock is stale", pid) |
| 117 | return true, nil |
| 118 | } |
| 119 | |
| 120 | // On Unix systems, send signal 0 to check if process is alive |
| 121 | // Signal 0 doesn't actually send a signal, just checks if we can |
| 122 | err = process.Signal(syscall.Signal(0)) |
| 123 | if err != nil { |
| 124 | // Process doesn't exist or we don't have permission to signal it |
| 125 | getCacheLogger().Debug("Cannot signal process %d: %v, lock is stale", pid, err) |
| 126 | return true, nil |
| 127 | } |
| 128 | |
| 129 | // Process exists and is running, lock is NOT stale |
| 130 | getCacheLogger().Debug("Process %d is running, lock is valid", pid) |
| 131 | return false, nil |
| 132 | } |
| 133 | |
| 134 | // isErrorTemporarilyUnavailable checks if an error is due to a resource being temporarily unavailable. |
| 135 | func isErrorTemporarilyUnavailable(err error) bool { |
no test coverage detected