cbrfWorker/internal/app/app.go
2023-06-22 11:26:42 +03:00

196 lines
4.6 KiB
Go

package app
import (
"context"
"errors"
"net/http"
"github.com/danilsolovyov/croupierCbrf/internal/dal"
"github.com/danilsolovyov/croupierCbrf/internal/handlers"
"github.com/danilsolovyov/croupierCbrf/internal/worker"
"github.com/gorilla/mux"
"github.com/skeris/appInit"
"github.com/themakers/hlog"
"go.uber.org/zap"
//"net/http"
"os"
"os/signal"
"syscall"
)
type Options struct {
IsProduction bool `env:"IS_PRODUCTION" default:"false"`
Development bool `env:"DEVELOPMENT" default:"true"`
AppName string `env:"APP_NAME" default:"croupierWorkerQuotes"`
AppAddr string `env:"APP_ADDR" default:"localhost:3131"`
AllowedOrigins string `env:"ALLOWED_ORIGINS" default:"*"`
AllowedHeaders string `env:"ALLOWED_HEADERS" default:"*"`
ExposeHeaders string `env:"EXPOSE_HEADERS" default:"*"`
MongoDbUri string `env:"DATABASE_URI" default:"mongodb+srv://user_1:cEDxC8ptLMMeoA5m@cluster0.aomle.mongodb.net/test"`
MongoDbTable string `env:"DATABASE_TABLE" default:"croupier"`
MongoCollections string `env:"COLLECTION_NAME" default:"quote"`
}
type App struct {
logger *zap.Logger
err chan error
}
func (a App) GetLogger() *zap.Logger {
return a.logger
}
func (a App) GetErr() chan error {
return a.err
}
//#region ======== Hl Info Structs ========
type InfoSvcStarted struct{}
type InfoInterruptSignal struct{}
type InfoTerminateSignal struct{}
type InfoSvcShuttingDown struct{}
type InfoSvcDone struct{}
//#endregion
//#region ======== Hl ErrorTypeApp Structs ========
type ErrorTypeApp struct {
Error error
}
type ErrorCanNotServe ErrorTypeApp
type ErrorSvcShuttingDown ErrorTypeApp
type ErrorZlogSync ErrorTypeApp
type ErrorConnectToMongo ErrorTypeApp
type ErrorDisconnectFromMongo ErrorTypeApp
type ErrorConnectToMinio ErrorTypeApp
type ErrorNewPairCache ErrorTypeApp
type ErrorNewMainWorker ErrorTypeApp
type ErrorStoreConnect struct {
Err string
Credentials string
}
//#endregion
func New(ctx context.Context, options interface{}) (appInit.CommonApp, error) {
opts := options.(Options)
var errCh chan error
// Create logger
zlog, err := zap.NewDevelopment()
if err != nil {
panic(err)
}
zlog = zlog.WithOptions(zap.AddCallerSkip(2))
//tl, err := zaptrashlog.NewCore(
// ctx,
// zapcore.DebugLevel,
// "trashlog:8008",
// v.Release,
// v.Commit,
// time.Now().Unix(),
//)
//if err != nil {
// tel, err := zaptg.NewCore(
// ctx,
// zap.ErrorLevel,
// "1408111289:AAHfWZRiBQRncb2gl2LtU8OeASjfJi4e8YE",
// v.Release,
// v.Commit,
// 0,
// -1001230000451,
// )
// if err != nil {
// panic(err)
// }
// zlog = zlog.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
// return zapcore.NewTee(core, tel)
// }))
//} else {
// zlog = zlog.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
// return zapcore.NewTee(core, tl)
// }))
//}
hlogger := hlog.New(zlog)
//hlogger = hlogger.With(v.GetVersion())
defer func() {
err = zlog.Sync()
if err != nil {
hlogger.Emit(ErrorZlogSync{err})
return
}
}()
// Connect to MongoDb
connMongo, err := dal.CreateMongo(ctx, hlogger, dal.MongoDbOptions{
DalName: "MongoDB",
URI: opts.MongoDbUri,
DbTable: opts.MongoDbTable,
Collections: opts.MongoCollections,
})
if err != nil {
hlogger.Emit(ErrorConnectToMongo{err})
return App{zlog, errCh}, err
}
ctxL, cancL := context.WithCancel(ctx)
defer cancL()
err = worker.InitAndStart(ctxL, connMongo, hlogger)
if err != nil {
return App{zlog, errCh}, err
}
router := mux.NewRouter()
handler := handlers.NewHandler(connMongo, hlogger, "")
router.HandleFunc("/getQuotes", handler.GetQuotes)
router.HandleFunc("/change", handler.Translate)
// Startup server
srv := &http.Server{Addr: opts.AppAddr, Handler: router}
go func() {
err = srv.ListenAndServe()
if err != http.ErrServerClosed && err != nil {
hlogger.Emit(ErrorCanNotServe{Error: err})
}
}()
hlogger.Emit(InfoSvcStarted{})
// Graceful Shutdown
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
killSignal := <-interrupt
switch killSignal {
case os.Interrupt:
err = errors.New("interrupted")
hlogger.Emit(InfoInterruptSignal{})
case syscall.SIGTERM:
err = errors.New("terminated")
hlogger.Emit(InfoTerminateSignal{})
}
hlogger.Emit(InfoSvcShuttingDown{})
err = srv.Shutdown(ctx)
if err != nil {
hlogger.Emit(ErrorSvcShuttingDown{err})
}
hlogger.Emit(InfoSvcDone{})
err = errors.New("finished") // Костыль чтобы приложение нормально закрывалось...
return App{zlog, errCh}, err
}