-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
110 lines (93 loc) · 2.73 KB
/
main.go
File metadata and controls
110 lines (93 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"context"
"errors"
"fmt"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/jair/bulkdownload/api"
appconfig "github.com/jair/bulkdownload/internal/config"
"github.com/jair/bulkdownload/internal/jobs"
"github.com/jair/bulkdownload/internal/service"
)
const (
httpServerReadHeaderTimeout = 5 * time.Second
httpServerReadTimeout = 30 * time.Second
httpServerIdleTimeout = 2 * time.Minute
httpServerShutdownTimeout = 10 * time.Second
)
func main() {
config, err := appconfig.LoadConfig()
if err != nil {
fmt.Fprintf(os.Stderr, "load config: %v\n", err)
os.Exit(1)
}
logger, err := newLogger(os.Stdout, config.LogLevel)
if err != nil {
fmt.Fprintf(os.Stderr, "create logger: %v\n", err)
os.Exit(1)
}
slog.SetDefault(logger)
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
if err := os.MkdirAll(config.JobsDir, 0o755); err != nil {
logger.Error("create jobs directory failed", "error", err, "jobs_dir", config.JobsDir)
os.Exit(1)
}
jobStore := jobs.NewJobs()
manager := service.NewManager(jobStore, config)
stopCleanup := service.StartCleanup(jobStore, config.JobsDir, config.CleanupTick)
server := &http.Server{
Addr: ":" + config.Port,
Handler: api.NewRouter(logger, manager, jobStore, config),
ReadHeaderTimeout: httpServerReadHeaderTimeout,
ReadTimeout: httpServerReadTimeout,
IdleTimeout: httpServerIdleTimeout,
}
logger.Info(
"service configuration loaded",
"jobs_dir", config.JobsDir,
"source_root_dir", config.SourceRootDir,
"public_base_url", config.PublicBaseURL,
"download_root_dir", config.DownloadRootDir,
"port", config.Port,
"log_level", config.LogLevel,
"job_ttl", config.JobTTL,
"cleanup_tick", config.CleanupTick,
)
logger.Info("service listening", "addr", ":"+config.Port)
serverErrCh := make(chan error, 1)
go func() {
serverErrCh <- server.ListenAndServe()
}()
select {
case err := <-serverErrCh:
stopCleanup()
manager.Shutdown()
if err != nil && !errors.Is(err, http.ErrServerClosed) {
logger.Error("server exited unexpectedly", "error", err)
os.Exit(1)
}
logger.Info("server stopped")
return
case <-ctx.Done():
stopCleanup()
logger.Info("shutdown started")
shutdownCtx, cancel := context.WithTimeout(context.Background(), httpServerShutdownTimeout)
defer cancel()
if err := server.Shutdown(shutdownCtx); err != nil {
logger.Error("shutdown server failed", "error", err)
os.Exit(1)
}
if err := <-serverErrCh; err != nil && !errors.Is(err, http.ErrServerClosed) {
logger.Error("server stopped with error", "error", err)
os.Exit(1)
}
manager.Shutdown()
logger.Info("shutdown complete")
}
}