Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for running profiling when debug build-tags provided #491

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,10 @@ The following libraries and frameworks are used by GoToSocial, with gratitude
- [google/uuid](https://github.com/google/uuid); UUID generation. [BSD-3-Clause License](https://spdx.org/licenses/BSD-3-Clause.html)
- [go-playground/validator](https://github.com/go-playground/validator); struct validation. [MIT License](https://spdx.org/licenses/MIT.html)
- [gorilla/websocket](https://github.com/gorilla/websocket); Websocket connectivity. [BSD-2-Clause License](https://spdx.org/licenses/BSD-2-Clause.html).
- [gruf/go-debug](https://codeberg.org/gruf/go-debug); profiling support in debug builds. [MIT License](https://spdx.org/licenses/MIT.html).
- [gruf/go-mutexes](https://codeberg.org/gruf/go-mutexes); mutex map. [MIT License](https://spdx.org/licenses/MIT.html).
- [gruf/go-runners](https://codeberg.org/gruf/go-runners); worker pool library. [MIT License](https://spdx.org/licenses/MIT.html).
- [gruf/go-store](https://codeberg.org/gruf/go-store); cacheing library. [MIT License](https://spdx.org/licenses/MIT.html).
- [gruf/go-store](https://codeberg.org/gruf/go-store); local media store. [MIT License](https://spdx.org/licenses/MIT.html).
- [h2non/filetype](https://github.com/h2non/filetype); filetype checking. [MIT License](https://spdx.org/licenses/MIT.html).
- [jackc/pgx](https://github.com/jackc/pgx); Postgres driver. [MIT License](https://spdx.org/licenses/MIT.html).
- [mcuadros/go-syslog](https://github.com/mcuadros/go-syslog); Syslog server library. [MIT License](https://spdx.org/licenses/MIT.html).
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/superseriousbusiness/gotosocial
go 1.18

require (
codeberg.org/gruf/go-debug v1.1.2
codeberg.org/gruf/go-errors v1.0.5
codeberg.org/gruf/go-runners v1.2.0
codeberg.org/gruf/go-store v1.3.6
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ codeberg.org/gruf/go-bytes v1.0.1/go.mod h1:1v/ibfaosfXSZtRdW2rWaVrDXMc9E3bsi/M9
codeberg.org/gruf/go-bytes v1.0.2 h1:malqE42Ni+h1nnYWBUAJaDDtEzF4aeN4uPN8DfMNNvo=
codeberg.org/gruf/go-bytes v1.0.2/go.mod h1:1v/ibfaosfXSZtRdW2rWaVrDXMc9E3bsi/M9Ekx39cg=
codeberg.org/gruf/go-cache v1.1.2/go.mod h1:/Dbc+xU72Op3hMn6x2PXF3NE9uIDFeS+sXPF00hN/7o=
codeberg.org/gruf/go-debug v1.1.2 h1:7Tqkktg60M/4WtXTTNUFH2T/6irBw4tI4viv7IRLZDE=
codeberg.org/gruf/go-debug v1.1.2/go.mod h1:N+vSy9uJBQgpQcJUqjctvqFz7tBHJf+S/PIjLILzpLg=
codeberg.org/gruf/go-errors v1.0.5 h1:rxV70oQkfasUdggLHxOX2QAoJOMFM7XWxHQR45Zx/Fg=
codeberg.org/gruf/go-errors v1.0.5/go.mod h1:n03EpmvcmfzU3/xJKC0XXtleXXJUNFpT2fgISODvZ1Y=
codeberg.org/gruf/go-fastcopy v1.1.1 h1:HhPCeFdVR5pwiSVDnQEGJ+J2ny9b5QgfiESc0zrWQAY=
Expand Down
92 changes: 57 additions & 35 deletions internal/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"net/http"
"time"

"codeberg.org/gruf/go-debug"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
Expand All @@ -32,7 +33,7 @@ import (
"golang.org/x/crypto/acme/autocert"
)

var (
const (
readTimeout = 60 * time.Second
writeTimeout = 30 * time.Second
idleTimeout = 30 * time.Second
Expand Down Expand Up @@ -69,38 +70,69 @@ func (r *router) AttachStaticFS(relativePath string, fs http.FileSystem) {

// Start starts the router nicely. It will serve two handlers if letsencrypt is enabled, and only the web/API handler if letsencrypt is not enabled.
func (r *router) Start() {
keys := config.Keys
leEnabled := viper.GetBool(keys.LetsEncryptEnabled)
var (
keys = config.Keys

// listen is the server start function, by
// default pointing to regular HTTP listener,
// but updated to TLS if LetsEncrypt is enabled.
listen = r.srv.ListenAndServe
)

if viper.GetBool(keys.LetsEncryptEnabled) {
// LetsEncrypt support is enabled

// Prepare an HTTPS-redirect handler for LetsEncrypt fallback
redirect := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
target := "https://" + r.Host + r.URL.Path
if len(r.URL.RawQuery) > 0 {
target += "?" + r.URL.RawQuery
}
http.Redirect(rw, r, target, http.StatusTemporaryRedirect)
})

if leEnabled {
bindAddress := viper.GetString(keys.BindAddress)
lePort := viper.GetInt(keys.LetsEncryptPort)
// Clone HTTP server but with autocert handler
srv := r.srv
srv.Handler = r.certManager.HTTPHandler(redirect)

// serve the http handler on the selected letsencrypt port, for receiving letsencrypt requests and solving their devious riddles
// Start the LetsEncrypt autocert manager HTTP server.
go func() {
listen := fmt.Sprintf("%s:%d", bindAddress, lePort)
logrus.Infof("letsencrypt listening on %s", listen)
if err := http.ListenAndServe(listen, r.certManager.HTTPHandler(http.HandlerFunc(httpsRedirect))); err != nil && err != http.ErrServerClosed {
addr := fmt.Sprintf("%s:%d",
viper.GetString(keys.BindAddress),
viper.GetInt(keys.LetsEncryptPort),
)

logrus.Infof("letsencrypt listening on %s", addr)

if err := srv.ListenAndServe(); err != nil &&
err != http.ErrServerClosed {
logrus.Fatalf("letsencrypt: listen: %s", err)
}
}()

// and serve the actual TLS handler
go func() {
logrus.Infof("listening on %s", r.srv.Addr)
if err := r.srv.ListenAndServeTLS("", ""); err != nil && err != http.ErrServerClosed {
logrus.Fatalf("listen: %s", err)
}
}()
} else {
// no tls required
go func() {
logrus.Infof("listening on %s", r.srv.Addr)
if err := r.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logrus.Fatalf("listen: %s", err)
}
}()
// TLS is enabled, update the listen function
listen = func() error { return r.srv.ListenAndServeTLS("", "") }
}

// Pass the server handler through a debug pprof middleware handler.
// For standard production builds this will be a no-op, but when the
// "debug" or "debugenv" build-tag is set pprof stats will be served
// at the standard "/debug/pprof" URL.
r.srv.Handler = debug.WithPprof(r.srv.Handler)
if debug.DEBUG() {
// Profiling requires timeouts longer than 30s, so reset these.
logrus.Warn("resetting http.Server{} timeout to support profiling")
r.srv.ReadTimeout = 0
r.srv.WriteTimeout = 0
}

// Start the main listener.
go func() {
logrus.Infof("listening on %s", r.srv.Addr)
if err := listen(); err != nil && err != http.ErrServerClosed {
logrus.Fatalf("listen: %s", err)
}
}()
}

// Stop shuts down the router nicely
Expand Down Expand Up @@ -193,13 +225,3 @@ func New(ctx context.Context, db db.DB) (Router, error) {
certManager: m,
}, nil
}

func httpsRedirect(w http.ResponseWriter, req *http.Request) {
target := "https://" + req.Host + req.URL.Path

if len(req.URL.RawQuery) > 0 {
target += "?" + req.URL.RawQuery
}

http.Redirect(w, req, target, http.StatusTemporaryRedirect)
}
5 changes: 4 additions & 1 deletion scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

set -eu

# DEBUG returns whether DEBUG build is enabled.
DEBUG() { [ ! -z "${DEBUG-}" ]; }

CGO_ENABLED=0 go build -trimpath \
-tags 'netgo osusergo static_build' \
-tags "netgo osusergo static_build $(DEBUG && echo 'debugenv')" \
-ldflags="-s -w -extldflags '-static' -X 'main.Version=${VERSION:-$(git describe --tags --abbrev=0)}'" \
./cmd/gotosocial
9 changes: 9 additions & 0 deletions vendor/codeberg.org/gruf/go-debug/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions vendor/codeberg.org/gruf/go-debug/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions vendor/codeberg.org/gruf/go-debug/debug.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions vendor/codeberg.org/gruf/go-debug/debug_env.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions vendor/codeberg.org/gruf/go-debug/debug_off.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions vendor/codeberg.org/gruf/go-debug/debug_on.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions vendor/codeberg.org/gruf/go-debug/pprof_off.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions vendor/codeberg.org/gruf/go-debug/pprof_on.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions vendor/codeberg.org/gruf/go-debug/run_tests.sh

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions vendor/modules.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# codeberg.org/gruf/go-bytes v1.0.2
## explicit; go 1.14
codeberg.org/gruf/go-bytes
# codeberg.org/gruf/go-debug v1.1.2
## explicit; go 1.16
codeberg.org/gruf/go-debug
# codeberg.org/gruf/go-errors v1.0.5
## explicit; go 1.15
codeberg.org/gruf/go-errors
Expand Down