From ce6530acef9f3f3abe25553e73cb781d81a7c008 Mon Sep 17 00:00:00 2001 From: Maxim Lebedev Date: Tue, 5 Oct 2021 12:08:41 +0500 Subject: [PATCH] :recycle: Refactored main.go for new modules usage --- cmd/indieauth/main.go | 151 +++++++++++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 53 deletions(-) diff --git a/cmd/indieauth/main.go b/cmd/indieauth/main.go index 78cd071..2e1945d 100644 --- a/cmd/indieauth/main.go +++ b/cmd/indieauth/main.go @@ -1,84 +1,129 @@ -//go:generate go get -u github.com/valyala/quicktemplate/qtc +//go:generate go install github.com/valyala/quicktemplate/qtc@latest //go:generate qtc -dir=../../web package main import ( "flag" "log" + gohttp "net/http" + _ "net/http/pprof" "os" "path/filepath" + "runtime" + "runtime/pprof" + "strings" "github.com/fasthttp/router" "github.com/spf13/viper" http "github.com/valyala/fasthttp" - authdelivery "gitlab.com/toby3d/indieauth/internal/auth/delivery/http" - authrepo "gitlab.com/toby3d/indieauth/internal/auth/repository/bolt" - authusecase "gitlab.com/toby3d/indieauth/internal/auth/usecase" - configrepo "gitlab.com/toby3d/indieauth/internal/config/repository/viper" - configusecase "gitlab.com/toby3d/indieauth/internal/config/usecase" - tokendelivery "gitlab.com/toby3d/indieauth/internal/token/delivery/http" - tokenrepo "gitlab.com/toby3d/indieauth/internal/token/repository/bolt" - tokenusecase "gitlab.com/toby3d/indieauth/internal/token/usecase" bolt "go.etcd.io/bbolt" + + configrepo "source.toby3d.me/website/oauth/internal/config/repository/viper" + configucase "source.toby3d.me/website/oauth/internal/config/usecase" + healthdelivery "source.toby3d.me/website/oauth/internal/health/delivery/http" + tokendelivery "source.toby3d.me/website/oauth/internal/token/delivery/http" + tokenrepo "source.toby3d.me/website/oauth/internal/token/repository/bolt" + tokenucase "source.toby3d.me/website/oauth/internal/token/usecase" ) -var flagConfig = flag.String("config", filepath.Join(".", "config.yml"), "set specific path to config file") +//nolint: gochecknoglobals +var ( + flagConfig = flag.String("config", filepath.Join(".", "config.yml"), "set specific path to config file") + flagCpuProfile = flag.String("cpuprofile", "", "write cpu profile to `file`") + flagMemProfile = flag.String("memprofile", "", "write memory profile to `file`") +) +//nolint: funlen func main() { flag.Parse() - infoLog := log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime) - errLog := log.New(os.Stdout, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile) - - v := viper.New() - dir, _ := filepath.Split(*flagConfig) - - v.AddConfigPath(dir) - - configRepo, err := configrepo.NewViperConfigRepository(v) - if err != nil { - errLog.Fatal(err) + if *flagCpuProfile != "" || *flagMemProfile != "" { + go log.Println(gohttp.ListenAndServe("localhost:6060", nil)) } - config := configusecase.NewConfigUseCase(configRepo) + if *flagCpuProfile != "" { + cpuProfile, err := os.Create(*flagCpuProfile) + if err != nil { + log.Fatal("could not create CPU profile: ", err) + } + defer cpuProfile.Close() - db, err := bolt.Open(config.GetDatabaseFileName(), 0666, nil) + if err := pprof.StartCPUProfile(cpuProfile); err != nil { + log.Fatal("could not start CPU profile: ", err) + } + defer pprof.StopCPUProfile() + } + + v := viper.New() + v.SetDefault("url", "/") + v.SetDefault("database", map[string]interface{}{ + "client": "bolt", + "connection": map[string]interface{}{ + "filename": filepath.Join(".", "development.db"), + }, + }) + v.SetDefault("server", map[string]interface{}{ + "host": "127.0.0.1", + "port": 3000, //nolint: gomnd + }) + v.SetConfigName("config") + v.SetConfigType("yaml") + + dir, file := filepath.Split(*flagConfig) + if file != "" { + ext := filepath.Ext(file) + v.SetConfigName(strings.TrimSuffix(file, ext)) + v.SetConfigType(ext[1:]) + } + + v.AddConfigPath(dir) + v.AddConfigPath(filepath.Join(".", "configs")) + v.AddConfigPath(".") + + r := router.New() + cfg := configucase.NewConfigUseCase(configrepo.NewViperConfigRepository(v)) + + db, err := bolt.Open(cfg.DBFileName(), os.ModePerm, nil) if err != nil { - errLog.Fatal(err) + log.Fatalln(err) } defer db.Close() - authRepo, err := authrepo.NewBoltAuthRepository(db) + if err = db.Update(func(tx *bolt.Tx) error { + _, err := tx.CreateBucketIfNotExists(tokenrepo.Token{}.Bucket()) + + return err + }); err != nil { + log.Fatalln(err) + } + + tokendelivery.NewRequestHandler(tokenucase.NewTokenUseCase(tokenrepo.NewBoltTokenRepository(db))).Register(r) + healthdelivery.NewRequestHandler().Register(r) + + server := &http.Server{ + Handler: r.Handler, + Name: "IndieAuth/1.0.0 (" + cfg.URL() + ")", + DisableKeepalive: true, + CloseOnShutdown: true, + // TODO(toby3d): Logger + } + + if err := server.ListenAndServe(cfg.Addr()); err != nil { + log.Fatalln(err) + } + + if *flagMemProfile == "" { + return + } + + memProfile, err := os.Create(*flagMemProfile) if err != nil { - errLog.Fatal(err) + log.Fatal("could not create memory profile: ", err) } + defer memProfile.Close() - tokenRepo, err := tokenrepo.NewBoltTokenRepository(db) - if err != nil { - errLog.Fatal(err) - } - - authUseCase := authusecase.NewAuthUseCase(authRepo) - tokenUseCase := tokenusecase.NewTokenUseCase(authRepo, tokenRepo) - authHandler := authdelivery.NewAuthHandler(authUseCase) - tokenHandler := tokendelivery.NewTokenHandler(tokenUseCase) - r := router.New() - - r.GET("/health", func(ctx *http.RequestCtx) { ctx.SetStatusCode(http.StatusOK) }) - authHandler.Register(r) - tokenHandler.Register(r) - - server := http.Server{ - CloseOnShutdown: true, - Handler: r.Handler, - Name: "IndieAuth/1.0.0 (" + config.GetURL() + ")", - Logger: infoLog, - LogAllErrors: true, - SecureErrorLogMessage: true, - } - - infoLog.Printf("IndieAuth started on %s", config.GetAddr()) - if err = server.ListenAndServe(config.GetAddr()); err != nil { - errLog.Fatal(err) + runtime.GC() // NOTE(toby3d): get up-to-date statistics + if err := pprof.WriteHeapProfile(memProfile); err != nil { + log.Fatal("could not write memory profile: ", err) } }