writePIDFile writes the current process ID to the specified file
(pidFile string, logger *slog.Logger)
| 305 | |
| 306 | // writePIDFile writes the current process ID to the specified file |
| 307 | func writePIDFile(pidFile string, logger *slog.Logger) error { |
| 308 | pid := os.Getpid() |
| 309 | pidContent := fmt.Sprintf("%d\n", pid) |
| 310 | |
| 311 | // Create directory if it doesn't exist |
| 312 | dir := filepath.Dir(pidFile) |
| 313 | if err := os.MkdirAll(dir, 0o700); err != nil { |
| 314 | return xerrors.Errorf("failed to create PID file directory: %w", err) |
| 315 | } |
| 316 | |
| 317 | // Check if PID file already exists |
| 318 | if existingPIDData, err := os.ReadFile(pidFile); err == nil { |
| 319 | existingPIDStr := strings.TrimSpace(string(existingPIDData)) |
| 320 | if existingPID, err := strconv.Atoi(existingPIDStr); err == nil { |
| 321 | if isProcessRunning(existingPID) { |
| 322 | return xerrors.Errorf("another instance is already running with PID %d (PID file: %s)", existingPID, pidFile) |
| 323 | } |
| 324 | logger.Warn("Found stale PID file, will overwrite", "pidFile", pidFile, "stalePID", existingPID) |
| 325 | } |
| 326 | } else if !os.IsNotExist(err) { |
| 327 | return xerrors.Errorf("failed to read existing PID file: %w", err) |
| 328 | } |
| 329 | |
| 330 | // Write PID file |
| 331 | if err := os.WriteFile(pidFile, []byte(pidContent), 0o600); err != nil { |
| 332 | return xerrors.Errorf("failed to write PID file: %w", err) |
| 333 | } |
| 334 | |
| 335 | logger.Info("Wrote PID file", "pidFile", pidFile, "pid", pid) |
| 336 | return nil |
| 337 | } |
| 338 | |
| 339 | // cleanupPIDFile removes the PID file if it was written by this process. |
| 340 | func cleanupPIDFile(pidFile string, logger *slog.Logger) { |