daemon.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package cli // import "miniflux.app/v2/internal/cli"
  4. import (
  5. "context"
  6. "log/slog"
  7. "net/http"
  8. "os"
  9. "os/signal"
  10. "syscall"
  11. "time"
  12. "miniflux.app/v2/internal/config"
  13. httpd "miniflux.app/v2/internal/http/server"
  14. "miniflux.app/v2/internal/metric"
  15. "miniflux.app/v2/internal/storage"
  16. "miniflux.app/v2/internal/systemd"
  17. "miniflux.app/v2/internal/worker"
  18. )
  19. func startDaemon(store *storage.Storage) {
  20. slog.Debug("Starting daemon...")
  21. stop := make(chan os.Signal, 1)
  22. signal.Notify(stop, os.Interrupt)
  23. signal.Notify(stop, syscall.SIGTERM)
  24. pool := worker.NewPool(store, config.Opts.WorkerPoolSize())
  25. if config.Opts.HasSchedulerService() && !config.Opts.HasMaintenanceMode() {
  26. runScheduler(store, pool)
  27. }
  28. var httpServer *http.Server
  29. if config.Opts.HasHTTPService() {
  30. httpServer = httpd.StartWebServer(store, pool)
  31. }
  32. if config.Opts.HasMetricsCollector() {
  33. collector := metric.NewCollector(store, config.Opts.MetricsRefreshInterval())
  34. go collector.GatherStorageMetrics()
  35. }
  36. if systemd.HasNotifySocket() {
  37. slog.Debug("Sending readiness notification to Systemd")
  38. if err := systemd.SdNotify(systemd.SdNotifyReady); err != nil {
  39. slog.Error("Unable to send readiness notification to systemd", slog.Any("error", err))
  40. }
  41. if config.Opts.HasWatchdog() && systemd.HasSystemdWatchdog() {
  42. slog.Debug("Activating Systemd watchdog")
  43. go func() {
  44. interval, err := systemd.WatchdogInterval()
  45. if err != nil {
  46. slog.Error("Unable to get watchdog interval from systemd", slog.Any("error", err))
  47. return
  48. }
  49. for {
  50. if err := store.Ping(); err != nil {
  51. slog.Error("Unable to ping database", slog.Any("error", err))
  52. } else {
  53. systemd.SdNotify(systemd.SdNotifyWatchdog)
  54. }
  55. time.Sleep(interval / 3)
  56. }
  57. }()
  58. }
  59. }
  60. <-stop
  61. slog.Debug("Shutting down the process")
  62. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  63. defer cancel()
  64. if httpServer != nil {
  65. httpServer.Shutdown(ctx)
  66. }
  67. slog.Debug("Process gracefully stopped")
  68. }