From ad8bf087ca257e5f963655dc9de1e937de17a88f Mon Sep 17 00:00:00 2001 From: Jan-Lukas Else Date: Thu, 17 Jun 2021 16:34:57 +0200 Subject: [PATCH] Use shutdowner library, improve logging, update deps --- app.go | 3 +++ config.go | 3 +++ database.go | 13 +++++++++---- go.mod | 10 ++++++---- go.sum | 22 +++++++++++++--------- hooks.go | 43 +++++++++++++++++++++++-------------------- http.go | 17 ++++++++++------- main.go | 44 ++++++++++++++++++++++---------------------- shutdown.go | 48 ------------------------------------------------ tor.go | 2 +- 10 files changed, 90 insertions(+), 115 deletions(-) delete mode 100644 shutdown.go diff --git a/app.go b/app.go index f016d4a..c9b3c40 100644 --- a/app.go +++ b/app.go @@ -6,6 +6,7 @@ import ( "net/http" "sync" + shutdowner "git.jlel.se/jlelse/go-shutdowner" ts "git.jlel.se/jlelse/template-strings" "github.com/go-chi/chi/v5" "github.com/go-fed/httpsig" @@ -66,6 +67,8 @@ type goBlog struct { templates map[string]*template.Template // Sessions loginSessions, captchaSessions *dbSessionStore + // Shutdown + shutdown shutdowner.Shutdowner // Template strings ts *ts.TemplateStrings // Tor diff --git a/config.go b/config.go index 8176503..dea3dc0 100644 --- a/config.go +++ b/config.go @@ -2,6 +2,7 @@ package main import ( "errors" + "log" "net/url" "strings" @@ -225,6 +226,7 @@ type configWebmention struct { } func (a *goBlog) initConfig() error { + log.Println("Initialize configuration...") viper.SetConfigName("config") viper.AddConfigPath("./config/") err := viper.ReadInConfig() @@ -307,6 +309,7 @@ func (a *goBlog) initConfig() error { br.Enabled = false } } + log.Println("Initialized configuration") return nil } diff --git a/database.go b/database.go index 820584c..00a2ea5 100644 --- a/database.go +++ b/database.go @@ -22,6 +22,7 @@ type database struct { } func (a *goBlog) initDatabase() (err error) { + log.Println("Initialize database...") // Setup db db, err := a.openDatabase(a.cfg.Db.File, true) if err != nil { @@ -29,9 +30,12 @@ func (a *goBlog) initDatabase() (err error) { } // Create appDB a.db = db - addShutdownFunc(func() { - _ = db.close() - log.Println("Closed database") + a.shutdown.Add(func() { + if err := db.close(); err != nil { + log.Printf("Failed to close database: %v", err) + } else { + log.Println("Closed database") + } }) if a.cfg.Db.DumpFile != "" { hourlyHooks = append(hourlyHooks, func() { @@ -39,6 +43,7 @@ func (a *goBlog) initDatabase() (err error) { }) db.dump(a.cfg.Db.DumpFile) } + log.Println("Initialized database") return nil } @@ -113,7 +118,7 @@ func (db *database) dump(file string) { log.Println("Error while dump db:", err.Error()) return } - if err = sqlite3dump.DumpDB(db.db, f); err != nil { + if err = sqlite3dump.DumpDB(db.db, f, sqlite3dump.WithTransaction(true)); err != nil { log.Println("Error while dump db:", err.Error()) } } diff --git a/go.mod b/go.mod index fbf7132..39fcf5a 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.16 require ( git.jlel.se/jlelse/go-geouri v0.0.0-20210525190615-a9c1d50f42d6 + git.jlel.se/jlelse/go-shutdowner v0.0.0-20210617142609-b824b8996568 git.jlel.se/jlelse/goldmark-mark v0.0.0-20210522162520-9788c89266a4 git.jlel.se/jlelse/template-strings v0.0.0-20210523080439-57437f8d23ee github.com/PuerkitoBio/goquery v1.7.0 @@ -34,11 +35,11 @@ require ( github.com/lib/pq v1.9.0 // indirect github.com/lopezator/migrator v0.3.0 github.com/mattn/go-sqlite3 v1.14.7 - github.com/microcosm-cc/bluemonday v1.0.10 + github.com/microcosm-cc/bluemonday v1.0.14 github.com/mitchellh/go-server-timing v1.0.1 github.com/paulmach/go.geojson v1.4.0 github.com/pquerna/otp v1.3.0 - github.com/schollz/sqlite3dump v1.2.4 + github.com/schollz/sqlite3dump v1.3.0 github.com/smartystreets/assertions v1.2.0 // indirect github.com/snabb/sitemap v1.0.0 github.com/spf13/cast v1.3.1 @@ -48,14 +49,15 @@ require ( github.com/thoas/go-funk v0.8.0 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 github.com/vcraescu/go-paginator v1.0.1-0.20201114172518-2cfc59fe05c2 - github.com/yuin/goldmark v1.3.7 + github.com/yuin/goldmark v1.3.8 // master github.com/yuin/goldmark-emoji v1.0.2-0.20210607094911-0487583eca38 go.uber.org/atomic v1.8.0 // indirect go.uber.org/multierr v1.7.0 // indirect + golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect golang.org/x/net v0.0.0-20210614182718-04defd469f4e golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 // indirect + golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b diff --git a/go.sum b/go.sum index 9d9f3d7..14d6a93 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= git.jlel.se/jlelse/go-geouri v0.0.0-20210525190615-a9c1d50f42d6 h1:d7k1NKd9fr+Eq7EtUrqUly+HDqDzpx9T9v8Gl2jJvpo= git.jlel.se/jlelse/go-geouri v0.0.0-20210525190615-a9c1d50f42d6/go.mod h1:eKL81ZHiGWZ4cdv9MI0ADmPiG9p0C+ajkSldNTr2ftQ= +git.jlel.se/jlelse/go-shutdowner v0.0.0-20210617142609-b824b8996568 h1:lsGzeyyxEnbf3rYRnb1eIx7kCP2rNipDhfo75K9qzTw= +git.jlel.se/jlelse/go-shutdowner v0.0.0-20210617142609-b824b8996568/go.mod h1:ekOAwB3OuHq9a5aInTRZeJic5oPltZXgZXChUxWw6HA= git.jlel.se/jlelse/goldmark-mark v0.0.0-20210522162520-9788c89266a4 h1:p3c/vCY6MUADNXWCYI/hsZ8ZEvN7LtvwHzK2B8Y6BSk= git.jlel.se/jlelse/goldmark-mark v0.0.0-20210522162520-9788c89266a4/go.mod h1:ZFhxwbX+afhgbzh5rpkSJUp6vIduNPtIGDrsWpIcHTE= git.jlel.se/jlelse/template-strings v0.0.0-20210523080439-57437f8d23ee h1:zun+B6UygGTYm+OBxK9eoPUHSd3M7AebIxXJyFyZzR4= @@ -287,14 +289,13 @@ github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9v github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA= github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mholt/acmez v0.1.3 h1:J7MmNIk4Qf9b8mAGqAh4XkNeowv3f1zW816yf4zt7Qk= github.com/mholt/acmez v0.1.3/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM= -github.com/microcosm-cc/bluemonday v1.0.10 h1:hsW4ch5StWWscflW8orGkX3TP2AVelTmwYO26qwGjqg= -github.com/microcosm-cc/bluemonday v1.0.10/go.mod h1:beubO5lmWoy1tU8niaMyXNriNgROO37H3U/tsrcZsy0= +github.com/microcosm-cc/bluemonday v1.0.14 h1:Djd+GeTanVeA23todvVC0AO5hsI+vAwQMLTy794Zr5I= +github.com/microcosm-cc/bluemonday v1.0.14/go.mod h1:beubO5lmWoy1tU8niaMyXNriNgROO37H3U/tsrcZsy0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.42 h1:gWGe42RGaIqXQZ+r3WUGEKBEtvPHY2SXo4dqixDNxuY= github.com/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= @@ -333,8 +334,8 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/schollz/sqlite3dump v1.2.4 h1:b3dgcKLsHZhF6OsB2EK+e/oA77vh4P/45TAh2R35OFI= -github.com/schollz/sqlite3dump v1.2.4/go.mod h1:SEajZA5udi52Taht5xQYlFfHwr7AIrqPrLDrAoFv17o= +github.com/schollz/sqlite3dump v1.3.0 h1:ll4MjfwoXbfZ0HpMa73x09uCj4h3R+G6YI+CmNssw5s= +github.com/schollz/sqlite3dump v1.3.0/go.mod h1:mzSTjZpJH4zAb1FN3iNlhWPbbdyeBpOaTW0hukyMHyI= github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -386,8 +387,9 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.3.7 h1:NSaHgaeJFCtWXCBkBKXw0rhgMuJ0VoE9FB5mWldcrQ4= github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.3.8 h1:Nw158Q8QN+CPgTmVRByhVwapp8Mm1e2blinhmx4wx5E= +github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark-emoji v1.0.2-0.20210607094911-0487583eca38 h1:XZjLcLoTPNZuxppY3gwhRqo/T2XF6JMGFFdkAjX3w1w= github.com/yuin/goldmark-emoji v1.0.2-0.20210607094911-0487583eca38/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= @@ -419,8 +421,9 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -567,8 +570,9 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk= -golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/hooks.go b/hooks.go index 9877cef..2b95aa7 100644 --- a/hooks.go +++ b/hooks.go @@ -9,10 +9,10 @@ import ( ) func (a *goBlog) preStartHooks() { - for _, cmd := range a.cfg.Hooks.PreStart { + cfg := a.cfg.Hooks + for _, cmd := range cfg.PreStart { func(cmd string) { - log.Println("Executing pre-start hook:", cmd) - a.cfg.Hooks.executeCommand(cmd) + executeHookCommand("pre-start", cfg.Shell, cmd) }(cmd) } } @@ -75,53 +75,56 @@ func (cfg *configHooks) executeTemplateCommand(hookType string, tmpl string, dat return } cmd := cmdBuf.String() - log.Println("Executing "+hookType+" hook:", cmd) - cfg.executeCommand(cmd) + executeHookCommand(hookType, cfg.Shell, cmd) } var hourlyHooks = []func(){} func (a *goBlog) startHourlyHooks() { + cfg := a.cfg.Hooks // Add configured hourly hooks - for _, cmd := range a.cfg.Hooks.Hourly { + for _, cmd := range cfg.Hourly { c := cmd f := func() { - log.Println("Executing hourly hook:", c) - a.cfg.Hooks.executeCommand(c) + executeHookCommand("hourly", cfg.Shell, c) } hourlyHooks = append(hourlyHooks, f) } - // Calculate waiting time for first exec - n := time.Now() - f := time.Date(n.Year(), n.Month(), n.Day(), n.Hour(), 0, 0, 0, n.Location()).Add(time.Hour) - w := f.Sub(n) // When there are hooks, start ticker if len(hourlyHooks) > 0 { - go func() { - // Wait for next hour to begin - time.Sleep(w) + // Wait for next full hour + tr := time.AfterFunc(time.Until(time.Now().Truncate(time.Hour).Add(time.Hour)), func() { // Execute once for _, f := range hourlyHooks { go f() } // Start ticker and execute regularly ticker := time.NewTicker(1 * time.Hour) + a.shutdown.Add(func() { + ticker.Stop() + log.Println("Stopped hourly hooks") + }) for range ticker.C { for _, f := range hourlyHooks { go f() } } - }() + }) + a.shutdown.Add(func() { + if tr.Stop() { + log.Println("Canceled hourly hooks") + } + }) } } -func (cfg *configHooks) executeCommand(cmd string) { - out, err := exec.Command(cfg.Shell, "-c", cmd).CombinedOutput() +func executeHookCommand(hookType, shell, cmd string) { + log.Printf("Executing %v hook: %v", hookType, cmd) + out, err := exec.Command(shell, "-c", cmd).CombinedOutput() if err != nil { log.Println("Failed to execute command:", err.Error()) } if len(out) > 0 { - log.Println("Output:") - log.Print(string(out)) + log.Printf("Output:\n%v", string(out)) } } diff --git a/http.go b/http.go index 5e68f7b..54c0078 100644 --- a/http.go +++ b/http.go @@ -45,6 +45,7 @@ const ( ) func (a *goBlog) startServer() (err error) { + log.Println("Start server(s)...") // Start a.d = &dynamicHandler{} // Set basic middlewares @@ -81,7 +82,7 @@ func (a *goBlog) startServer() (err error) { ReadTimeout: 5 * time.Minute, WriteTimeout: 5 * time.Minute, } - addShutdownFunc(shutdownServer(s, "main server")) + a.shutdown.Add(shutdownServer(s, "main server")) if a.cfg.Server.PublicHTTPS { // Configure certmagic.Default.Storage = &certmagic.FileStorage{Path: "data/https"} @@ -94,7 +95,7 @@ func (a *goBlog) startServer() (err error) { ReadTimeout: 5 * time.Minute, WriteTimeout: 5 * time.Minute, } - addShutdownFunc(shutdownServer(httpServer, "http server")) + a.shutdown.Add(shutdownServer(httpServer, "http server")) go func() { if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Println("Failed to start HTTP server:", err.Error()) @@ -125,8 +126,10 @@ func (a *goBlog) startServer() (err error) { func shutdownServer(s *http.Server, name string) func() { return func() { toc, c := context.WithTimeout(context.Background(), 5*time.Second) - _ = s.Shutdown(toc) - c() + defer c() + if err := s.Shutdown(toc); err != nil { + log.Printf("Error on server shutdown (%v): %v", name, err) + } log.Println("Stopped server:", name) } } @@ -627,13 +630,13 @@ func (d *dynamicHandler) swapHandler(h *chi.Mux) { } func (d *dynamicHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - for !d.initialized { - time.Sleep(1 * time.Second) - } // Fix to use Path routing instead of RawPath routing in Chi r.URL.RawPath = "" // Serve request d.mutex.RLock() + for !d.initialized { + time.Sleep(10 * time.Millisecond) + } router := d.router d.mutex.RUnlock() router.ServeHTTP(w, r) diff --git a/main.go b/main.go index e8fcdcb..070d019 100644 --- a/main.go +++ b/main.go @@ -50,9 +50,8 @@ func main() { app := &goBlog{} // Initialize config - log.Println("Initialize configuration...") if err = app.initConfig(); err != nil { - logErrAndQuit("Failed to init config:", err.Error()) + app.logErrAndQuit("Failed to init config:", err.Error()) return } @@ -60,7 +59,7 @@ func main() { if len(os.Args) >= 2 && os.Args[1] == "healthcheck" { // Connect to public address + "/ping" and exit with 0 when successful health := app.healthcheckExitCode() - shutdown() + app.shutdown.Shutdown() os.Exit(health) return } @@ -72,11 +71,11 @@ func main() { AccountName: app.cfg.User.Nick, }) if err != nil { - logErrAndQuit(err.Error()) + app.logErrAndQuit(err.Error()) return } log.Println("TOTP-Secret:", key.Secret()) - shutdown() + app.shutdown.Shutdown() return } @@ -87,48 +86,49 @@ func main() { app.preStartHooks() // Initialize database and markdown - log.Println("Initialize database...") if err = app.initDatabase(); err != nil { - logErrAndQuit("Failed to init database:", err.Error()) + app.logErrAndQuit("Failed to init database:", err.Error()) return } - log.Println("Initialize server components...") + + log.Println("Initialize components...") + app.initMarkdown() // Link check tool after init of markdown if len(os.Args) >= 2 && os.Args[1] == "check" { app.checkAllExternalLinks() - shutdown() + app.shutdown.Shutdown() return } // More initializations if err = app.initTemplateAssets(); err != nil { // Needs minify - logErrAndQuit("Failed to init template assets:", err.Error()) + app.logErrAndQuit("Failed to init template assets:", err.Error()) return } if err = app.initTemplateStrings(); err != nil { - logErrAndQuit("Failed to init template translations:", err.Error()) + app.logErrAndQuit("Failed to init template translations:", err.Error()) return } if err = app.initRendering(); err != nil { // Needs assets and minify - logErrAndQuit("Failed to init HTML rendering:", err.Error()) + app.logErrAndQuit("Failed to init HTML rendering:", err.Error()) return } if err = app.initCache(); err != nil { - logErrAndQuit("Failed to init HTTP cache:", err.Error()) + app.logErrAndQuit("Failed to init HTTP cache:", err.Error()) return } if err = app.initRegexRedirects(); err != nil { - logErrAndQuit("Failed to init redirects:", err.Error()) + app.logErrAndQuit("Failed to init redirects:", err.Error()) return } if err = app.initHTTPLog(); err != nil { - logErrAndQuit("Failed to init HTTP logging:", err.Error()) + app.logErrAndQuit("Failed to init HTTP logging:", err.Error()) return } if err = app.initActivityPub(); err != nil { - logErrAndQuit("Failed to init ActivityPub:", err.Error()) + app.logErrAndQuit("Failed to init ActivityPub:", err.Error()) return } app.initWebmention() @@ -139,21 +139,21 @@ func main() { // Start cron hooks app.startHourlyHooks() + log.Println("Initialized components") + // Start the server - log.Println("Starting server(s)...") err = app.startServer() if err != nil { - logErrAndQuit("Failed to start server(s):", err.Error()) + app.logErrAndQuit("Failed to start server(s):", err.Error()) return } // Wait till everything is shutdown - waitForShutdown() - + app.shutdown.Wait() } -func logErrAndQuit(v ...interface{}) { +func (a *goBlog) logErrAndQuit(v ...interface{}) { log.Println(v...) - shutdown() + a.shutdown.Shutdown() os.Exit(1) } diff --git a/shutdown.go b/shutdown.go deleted file mode 100644 index 1b68593..0000000 --- a/shutdown.go +++ /dev/null @@ -1,48 +0,0 @@ -package main - -import ( - "os" - "os/signal" - "sync" - "syscall" -) - -var ( - quit = make(chan os.Signal, 1) - shutdownFuncs = []func(){} - shutdownWg sync.WaitGroup - shutdownFuncMapMutex sync.Mutex -) - -func init() { - signal.Notify(quit, - os.Interrupt, - syscall.SIGINT, - syscall.SIGTERM, // e.g. Docker stop - ) - go func() { - <-quit - shutdown() - }() -} - -func addShutdownFunc(f func()) { - shutdownWg.Add(1) - shutdownFuncMapMutex.Lock() - shutdownFuncs = append(shutdownFuncs, f) - shutdownFuncMapMutex.Unlock() -} - -func shutdown() { - for _, f := range shutdownFuncs { - go func(f func()) { - defer shutdownWg.Done() - f() - }(f) - } - shutdownWg.Wait() -} - -func waitForShutdown() { - shutdownWg.Wait() -} diff --git a/tor.go b/tor.go index 8172ce9..3f04b26 100644 --- a/tor.go +++ b/tor.go @@ -82,7 +82,7 @@ func (a *goBlog) startOnionService(h http.Handler) error { ReadTimeout: 5 * time.Minute, WriteTimeout: 5 * time.Minute, } - addShutdownFunc(shutdownServer(s, "tor")) + a.shutdown.Add(shutdownServer(s, "tor")) if err = s.Serve(onion); err != nil && err != http.ErrServerClosed { return err }