msrc
/
HttpService.go
97 строк · 3.6 Кб
1package msrc
2
3import (
4"context"
5"fmt"
6"net/http"
7
8"github.com/pkg/errors"
9"github.com/sirupsen/logrus"
10hh "gitlab.systems-fd.com/packages/golang/helpers/h"
11)
12
13// httpService реализует базовый функционал HTTP сервера для приложений
14// в виде сервиса для библиотеки.
15type httpService struct {
16router http.Handler
17server *http.Server
18logger *logrus.Entry
19
20httpHost string
21httpPort string
22}
23
24// HttpService реализует фабрику сервиса для библиотеки, реализующего
25// функционал HTTP сервера. На вход передаются обязательные аргументы
26// для HTTP сервера, а так же возможна передача конфигурации запуска
27// сервера.
28//
29// Если конфигурация запуска не передана, то будет использоваться конфигурация
30// `http.Server{}`, при этом в обоих случаях (передано/не передано) будет
31// происходить переопределение полей Addr и Handler в соответствии с
32// переданными обязательными аргументами функции.
33func HttpService(
34HttpHost, HttpPort string,
35Router http.Handler,
36GraceStopPeriodSeconds uint8,
37ServerConfig ...*http.Server,
38) ServiceInterface {
39if 0 == len(ServerConfig) {
40ServerConfig = append(ServerConfig, &http.Server{})
41}
42
43if ServerConfig[0] == nil {
44ServerConfig[0] = &http.Server{}
45}
46
47return NewSimpleService(
48&httpService{
49router: Router,
50server: ServerConfig[0],
51logger: logrus.WithField("prefix", "msrc/HttpService"),
52httpHost: HttpHost,
53httpPort: HttpPort,
54},
55GraceStopPeriodSeconds,
56)
57}
58
59// Run выполняет запуск упрощенной версии сервиса.
60// На вход передается контекст, который передаст `<-ctx.Done()` в случае
61// его остановки. Сам сервис должен обрабатывать его, если он не реализует
62// своего собственного, отдельного алгоритма остановки.
63func (h *httpService) Run(ctx context.Context) error {
64h.server.Addr = fmt.Sprintf(`%v:%v`, h.httpHost, h.httpPort)
65h.server.Handler = h.router
66
67h.logger.WithField("type", "tcp").WithField("host", h.server.Addr).Info("Starting HTTP Server")
68
69err := h.server.ListenAndServe()
70if hh.IsCtxDone(ctx) {
71return nil
72}
73
74if nil != err {
75h.logger.
76WithError(err).
77WithField("code", 500).
78WithField("host", h.server.Addr).
79Error(`Failed to serve HTTP requests`)
80
81return errors.Wrap(err, `[httpService]`)
82}
83
84return nil
85}
86
87// GracefulShutdown выполняет правильную остановку упрощенного
88// сервиса. В данном случае, если сервис необходимо останавливать
89// вызовом отдельного функционала остановки, этот метод предоставляет
90// такую возможность.
91//
92// Метод вызывается в процессе остановки сервера и принимает на вход
93// контекст с deadline, устанавливаемым сверху. За установленное время
94// сервис либо завершает работу, либо отключается принудительно.
95func (h *httpService) GracefulShutdown(ctx context.Context) error {
96return h.server.Shutdown(ctx)
97}
98