diff options
| author | 2021-03-02 22:52:31 +0100 | |
|---|---|---|
| committer | 2021-03-02 22:52:31 +0100 | |
| commit | be1b631681ae1bc588c9002f1bedfcc01a7bb153 (patch) | |
| tree | 5d66376080520cba36b7e53b5090ae12216cedc4 | |
| parent | start implementing db interface (diff) | |
| download | gotosocial-be1b631681ae1bc588c9002f1bedfcc01a7bb153.tar.xz | |
More messing around
| -rw-r--r-- | cmd/server/main.go | 38 | ||||
| -rw-r--r-- | go.mod | 2 | ||||
| -rw-r--r-- | go.sum | 24 | ||||
| -rw-r--r-- | internal/client/router.go | 7 | ||||
| -rw-r--r-- | internal/db/const.go | 12 | ||||
| -rw-r--r-- | internal/db/postgres.go | 91 | ||||
| -rw-r--r-- | internal/db/service.go | 10 | 
7 files changed, 135 insertions, 49 deletions
| diff --git a/cmd/server/main.go b/cmd/server/main.go index fded184fa..7a509e96f 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -19,10 +19,42 @@  package main  import ( -	"github.com/gotosocial/gotosocial/internal/client" +	"context" +	"os" +	"os/signal" +	"syscall" + +	"github.com/gotosocial/gotosocial/internal/db" +	"github.com/sirupsen/logrus"  )  func main() { -	router := client.NewRouter() -	router.Route() +	log := logrus.New() +	ctx := context.Background() +	dbConfig := &db.Config{ +		Type:            "POSTGRES", +		Address:         "", +		Port:            5432, +		User:            "", +		Password:        "whatever", +		Database:        "postgres", +		ApplicationName: "gotosocial", +	} +	dbService, err := db.NewService(ctx, dbConfig, log) +	if err != nil { +		panic(err) +	} + +	// catch shutdown signals from the operating system +	sigs := make(chan os.Signal, 1) +	signal.Notify(sigs, os.Interrupt, syscall.SIGTERM) +	sig := <-sigs +	log.Infof("received signal %s, shutting down", sig) + +	// close down all running services in order +	if err := dbService.Stop(ctx); err != nil { +		log.Errorf("error closing dbservice: %s", err) +	} + +	log.Info("done! exiting...")  } @@ -9,9 +9,9 @@ require (  	github.com/golang/protobuf v1.4.3 // indirect  	github.com/google/go-cmp v0.5.4 // indirect  	github.com/jinzhu/inflection v1.0.0 // indirect -	github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect  	github.com/onsi/ginkgo v1.15.0 // indirect  	github.com/onsi/gomega v1.10.5 // indirect +	github.com/sirupsen/logrus v1.8.0  	github.com/stretchr/testify v1.7.0 // indirect  	golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect  	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect @@ -67,33 +67,31 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=  github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=  github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=  github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g= +github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=  github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=  github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=  github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=  github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=  github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=  github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=  github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=  github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=  github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=  github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= -github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=  github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4=  github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=  github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=  github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=  github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=  github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=  github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=  github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=  github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= +github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU= +github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=  github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=  github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=  github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=  github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= @@ -108,8 +106,6 @@ golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnf  golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=  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-20210218145215-b8e89b74b9df h1:y7QZzfUiTwWam+xBn29Ulb8CBwVN5UdzmMDavl9Whlw= -golang.org/x/crypto v0.0.0-20210218145215-b8e89b74b9df/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=  golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=  golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=  golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -125,10 +121,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn  golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=  golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=  golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=  golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=  golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=  golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=  golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -148,12 +141,9 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w  golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=  golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=  golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=  golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=  golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=  golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210218155724-8ebf48af031b h1:lAZ0/chPUDWwjqosYR0X4M490zQhMsiJ4K3DbA7o+3g= -golang.org/x/sys v0.0.0-20210218155724-8ebf48af031b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=  golang.org/x/sys v0.0.0-20210301091718-77cc2087c03b h1:kHlr0tATeLRMEiZJu5CknOw/E8V6h69sXXQFGoPtjcc=  golang.org/x/sys v0.0.0-20210301091718-77cc2087c03b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=  golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -171,8 +161,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn  golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=  golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=  golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=  golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=  golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=  google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=  google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -193,8 +183,6 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD  google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=  google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=  gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=  gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=  gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=  gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= diff --git a/internal/client/router.go b/internal/client/router.go index cf00419c5..0cedcd0dc 100644 --- a/internal/client/router.go +++ b/internal/client/router.go @@ -22,7 +22,7 @@ import "github.com/gin-gonic/gin"  // Router provides the http routes used by the API  type Router interface { -	Route() +	Route() error  }  // NewRouter returns a new router @@ -34,7 +34,7 @@ func NewRouter() Router {  type router struct {  } -func (r *router) Route() { +func (r *router) Route() error {  	ginRouter := gin.Default()  	ginRouter.LoadHTMLGlob("web/template/*") @@ -44,5 +44,6 @@ func (r *router) Route() {  	statusesGroup := v1.Group("/statuses")  	statusesGroup.GET(":id", statusGet) -	ginRouter.Run() +	err := ginRouter.Run() +	return err  } diff --git a/internal/db/const.go b/internal/db/const.go index ab0a5c03f..ca4ab3922 100644 --- a/internal/db/const.go +++ b/internal/db/const.go @@ -21,15 +21,23 @@ package db  import "regexp"  const ( -	// general db defaults +	/* +	   general db defaults +	*/  	// default database to use in whatever db implementation we have  	defaultDatabase string = "gotosocial" +	// default address should in most cases be overwritten +	defaultAddress string = "localhost" -	// implementation-specific defaults +	/* +	   implementation-specific defaults +	*/  	// widely-recognised default postgres port  	postgresDefaultPort int = 5432 +	// default user should in most cases be overwritten +	postgresDefaultUser string = "postgres"  )  var ipv4Regex = regexp.MustCompile(`^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`) diff --git a/internal/db/postgres.go b/internal/db/postgres.go index 67d0bb4e9..f4cf47406 100644 --- a/internal/db/postgres.go +++ b/internal/db/postgres.go @@ -23,31 +23,69 @@ import (  	"errors"  	"fmt"  	"net/url" +	"time"  	"github.com/go-fed/activity/streams/vocab"  	"github.com/go-pg/pg" +	"github.com/sirupsen/logrus"  )  type postgresService struct {  	config *Config  	conn   *pg.DB -	ready  bool +	log    *logrus.Entry +	cancel context.CancelFunc  }  // newPostgresService returns a postgresService derived from the provided config, which implements the go-fed DB interface.  // Under the hood, it uses https://github.com/go-pg/pg to create and maintain a database connection. -func newPostgresService(config *Config) (*postgresService, error) { +func newPostgresService(ctx context.Context, config *Config, log *logrus.Entry) (*postgresService, error) {  	opts, err := derivePGOptions(config)  	if err != nil {  		return nil, fmt.Errorf("could not create postgres service: %s", err)  	} -	conn := pg.Connect(opts) + +	readyChan := make(chan interface{}) +	opts.OnConnect = func(c *pg.Conn) error { +		close(readyChan) +		return nil +	} + +	// create a connection +	pgCtx, cancel := context.WithCancel(ctx) +	conn := pg.Connect(opts).WithContext(pgCtx) + +	// actually *begin* the connection so that we can tell if the db is there +	// and listening, and also trigger the opts.OnConnect function passed in above +	tx, err := conn.Begin() +	if err != nil { +		cancel() +		return nil, fmt.Errorf("db connection error: %s", err) +	} + +	// close the transaction we just started so it doesn't hang around +	if err := tx.Rollback(); err != nil { +		cancel() +		return nil, fmt.Errorf("db connection error: %s", err) +	} + +	// make sure the opts.OnConnect function has been triggered +	// and closed the ready channel +	select { +	case <-readyChan: +		log.Infof("postgres connection ready") +	case <-time.After(5 * time.Second): +		cancel() +		return nil, errors.New("db connection timeout") +	} + +	// we can confidently return this useable postgres service now  	return &postgresService{ -		config, -		conn, -		false, +		config: config, +		conn:   conn, +		log:    log, +		cancel: cancel,  	}, nil -  }  /* @@ -68,22 +106,35 @@ func derivePGOptions(config *Config) (*pg.Options, error) {  	}  	// validate address -	address := config.Address -	if address == "" { -		return nil, errors.New("address not provided") +	if config.Address == "" { +		config.Address = defaultAddress +	} +	if !hostnameRegex.MatchString(config.Address) && !ipv4Regex.MatchString(config.Address) && config.Address != "localhost" { +		return nil, fmt.Errorf("address %s was neither an ipv4 address nor a valid hostname", config.Address) +	} + +	// validate username +	if config.User == "" { +		config.User = postgresDefaultUser  	} -	if !hostnameRegex.MatchString(address) && !ipv4Regex.MatchString(address) { -		return nil, fmt.Errorf("address %s was neither an ipv4 address nor a valid hostname", address) + +	// validate that there's a password +	if config.Password == "" { +		return nil, errors.New("no password set") +	} + +	// validate database +	if config.Database == "" { +		config.Database = defaultDatabase  	} +	// We can rely on the pg library we're using to set +	// sensible defaults for everything we don't set here.  	options := &pg.Options{  		Addr:     fmt.Sprintf("%s:%d", config.Address, config.Port),  		User:     config.User,  		Password: config.Password,  		Database: config.Database, -		OnConnect: func(c *pg.Conn) error { -			return nil -		},  	}  	return options, nil @@ -176,6 +227,12 @@ func (ps *postgresService) Liked(c context.Context, actorIRI *url.URL) (follower  	EXTRA FUNCTIONS  */ -func (ps *postgresService) Ready() bool { -	return false +func (ps *postgresService) Stop(ctx context.Context) error { +	ps.log.Info("closing db connection") +	if err := ps.conn.Close(); err != nil { +		// only cancel if there's a problem closing the db +		ps.cancel() +		return err +	} +	return nil  } diff --git a/internal/db/service.go b/internal/db/service.go index 6163b3c69..9a1d3ce2c 100644 --- a/internal/db/service.go +++ b/internal/db/service.go @@ -19,10 +19,12 @@  package db  import ( +	"context"  	"fmt"  	"strings"  	"github.com/go-fed/activity/pub" +	"github.com/sirupsen/logrus"  )  const dbTypePostgres string = "POSTGRES" @@ -39,9 +41,7 @@ type Service interface {  	/*  		ANY ADDITIONAL DESIRED FUNCTIONS  	*/ - -	// Ready indicates whether the database is ready to handle queries and whatnot. -	Ready() bool +	Stop(context.Context) error  }  // Config provides configuration options for the database connection @@ -57,10 +57,10 @@ type Config struct {  // NewService returns a new database service that satisfies the Service interface and, by extension,  // the go-fed database interface described here: https://github.com/go-fed/activity/blob/master/pub/database.go -func NewService(config *Config) (Service, error) { +func NewService(context context.Context, config *Config, log *logrus.Logger) (Service, error) {  	switch strings.ToUpper(config.Type) {  	case dbTypePostgres: -		return newPostgresService(config) +		return newPostgresService(context, config, log.WithField("service", "db"))  	default:  		return nil, fmt.Errorf("database type %s not supported", config.Type)  	} | 
