Watch and reload on config changes
This commit is contained in:
parent
65921d4d42
commit
78dbe32bd4
@ -20,6 +20,10 @@ auth_fail_block: never
|
||||
# response
|
||||
enable_tracing: true
|
||||
|
||||
# Watch the config folder and reload Super Graph
|
||||
# with the new configs when a change is detected
|
||||
reload_on_config_change: false
|
||||
|
||||
# Postgres related environment Variables
|
||||
# SG_DATABASE_HOST
|
||||
# SG_DATABASE_PORT
|
||||
|
13
go.mod
13
go.mod
@ -8,26 +8,23 @@ require (
|
||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737
|
||||
github.com/cespare/xxhash/v2 v2.0.0
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/fsnotify/fsnotify v1.4.7
|
||||
github.com/garyburd/redigo v1.6.0
|
||||
|
||||
github.com/go-pg/pg v8.0.1+incompatible
|
||||
github.com/gobuffalo/envy v1.7.0 // indirect
|
||||
github.com/gobuffalo/flect v0.1.1
|
||||
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2
|
||||
github.com/gorilla/websocket v1.4.0
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect
|
||||
github.com/labstack/gommon v0.2.8
|
||||
github.com/mattn/go-colorable v0.1.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.7 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/onsi/ginkgo v1.8.0 // indirect
|
||||
github.com/onsi/gomega v1.5.0 // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/rs/zerolog v1.14.3
|
||||
github.com/sirupsen/logrus v1.4.0
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/viper v1.3.1
|
||||
github.com/valyala/fasttemplate v1.0.1
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
mellium.im/sasl v0.2.1 // indirect
|
||||
)
|
||||
|
28
go.sum
28
go.sum
@ -27,12 +27,8 @@ github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc
|
||||
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/go-pg/pg v8.0.1+incompatible h1:gi93AxXmqlFGT0os5z2kTnbDqCk6BHXnA9MMApVxAkY=
|
||||
github.com/go-pg/pg v8.0.1+incompatible/go.mod h1:a2oXow+aFOrvwcKs3eIA0lNFmMilrxK2sOkB5NWe0vA=
|
||||
github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU=
|
||||
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/flect v0.1.1 h1:GTZJjJufv9FxgRs1+0Soo3wj+Md3kTUmTER/YE4uINA=
|
||||
github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
||||
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2 h1:8thhT+kUJMTMy3HlX4+y9Da+BNJck+p109tqqKp7WDs=
|
||||
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
@ -43,22 +39,13 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k=
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
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/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
|
||||
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@ -68,16 +55,13 @@ github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/rogpeppe/go-internal v1.1.0 h1:g0fH8RicVgNl+zVZDCDfbdWxAWoAEJyI7I3TZYXFiig=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.14.3 h1:4EGfSkR2hJDB0s3oFfrlPqjU1e4WLncergLil3nEKW0=
|
||||
github.com/rs/zerolog v1.14.3/go.mod h1:3WXPzbXEEliJ+a6UFE4vhIxV8qR1EML6ngzP9ug4eYg=
|
||||
github.com/sirupsen/logrus v1.4.0 h1:yKenngtzGh+cUSSh6GWbxW2abRqhYUSR/t/6+2QqNvE=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
@ -92,7 +76,6 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
||||
github.com/spf13/viper v1.3.1 h1:5+8j8FTpnFV4nEImW/ofkzEt8VoOiLXxdYIDsB73T38=
|
||||
github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/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 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@ -103,7 +86,6 @@ github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8W
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
@ -115,8 +97,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJV
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -128,8 +110,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
|
@ -7,17 +7,18 @@ import (
|
||||
)
|
||||
|
||||
type config struct {
|
||||
AppName string `mapstructure:"app_name"`
|
||||
Env string
|
||||
HostPort string `mapstructure:"host_port"`
|
||||
Host string
|
||||
Port string
|
||||
WebUI bool `mapstructure:"web_ui"`
|
||||
LogLevel string `mapstructure:"log_level"`
|
||||
EnableTracing bool `mapstructure:"enable_tracing"`
|
||||
UseAllowList bool `mapstructure:"use_allow_list"`
|
||||
AuthFailBlock string `mapstructure:"auth_fail_block"`
|
||||
Inflections map[string]string
|
||||
AppName string `mapstructure:"app_name"`
|
||||
Env string
|
||||
HostPort string `mapstructure:"host_port"`
|
||||
Host string
|
||||
Port string
|
||||
WebUI bool `mapstructure:"web_ui"`
|
||||
LogLevel string `mapstructure:"log_level"`
|
||||
EnableTracing bool `mapstructure:"enable_tracing"`
|
||||
UseAllowList bool `mapstructure:"use_allow_list"`
|
||||
WatchAndReload bool `mapstructure:"reload_on_config_change"`
|
||||
AuthFailBlock string `mapstructure:"auth_fail_block"`
|
||||
Inflections map[string]string
|
||||
|
||||
Auth struct {
|
||||
Type string
|
||||
|
195
serv/reload.go
Normal file
195
serv/reload.go
Normal file
@ -0,0 +1,195 @@
|
||||
// Package reload offers lightweight automatic reloading of running processes.
|
||||
//
|
||||
// After initialisation with reload.Do() any changes to the binary will
|
||||
// restart the process.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// go func() {
|
||||
// err := reload.Do(log.Printf)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// }()
|
||||
//
|
||||
// A list of additional directories to watch can be added:
|
||||
//
|
||||
// go func() {
|
||||
// err := reload.Do(log.Printf, reload.Dir("tpl", reloadTpl)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// }()
|
||||
//
|
||||
// Note that this package won't prevent race conditions (e.g. when assigning to
|
||||
// a global templates variable). You'll need to use sync.RWMutex yourself.
|
||||
package serv // import "github.com/teamwork/reload"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var binSelf string
|
||||
|
||||
type dir struct {
|
||||
path string
|
||||
cb func()
|
||||
}
|
||||
|
||||
// Dir is an additional directory to watch for changes. Directories are watched
|
||||
// non-recursively.
|
||||
//
|
||||
// The second argument is the callback that to run when the directory changes.
|
||||
// Use reload.ReExec() to restart the process.
|
||||
func Dir(path string, cb func()) dir { return dir{path, cb} } // nolint: golint
|
||||
|
||||
// Do reload the current process when its binary changes.
|
||||
//
|
||||
// The log function is used to display an informational startup message and
|
||||
// errors. It works well with e.g. the standard log package or Logrus.
|
||||
//
|
||||
// The error return will only return initialisation errors. Once initialized it
|
||||
// will use the log function to print errors, rather than return.
|
||||
func Do(log func(string, ...interface{}), additional ...dir) error {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cannot setup watcher")
|
||||
}
|
||||
defer watcher.Close() // nolint: errcheck
|
||||
|
||||
binSelf, err = self()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Watch the directory, because a recompile renames the existing
|
||||
// file (rather than rewriting it), so we won't get events for that.
|
||||
dirs := make([]string, len(additional)+1)
|
||||
dirs[0] = filepath.Dir(binSelf)
|
||||
|
||||
for i := range additional {
|
||||
path, err := filepath.Abs(additional[i].path)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "cannot get absolute path to %q: %v",
|
||||
additional[i].path, err)
|
||||
}
|
||||
|
||||
s, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "os.Stat")
|
||||
}
|
||||
if !s.IsDir() {
|
||||
return errors.Errorf("not a directory: %q; can only watch directories",
|
||||
additional[i].path)
|
||||
}
|
||||
|
||||
additional[i].path = path
|
||||
dirs[i+1] = path
|
||||
}
|
||||
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case err := <-watcher.Errors:
|
||||
// Standard logger doesn't have anything other than Print,
|
||||
// Panic, and Fatal :-/ Printf() is probably best.
|
||||
log("reload error: %v", err)
|
||||
case event := <-watcher.Events:
|
||||
// Ensure that we use the correct events, as they are not uniform accross
|
||||
// platforms. See https://github.com/fsnotify/fsnotify/issues/74
|
||||
var trigger bool
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "freebsd", "openbsd", "netbsd", "dragonfly":
|
||||
trigger = event.Op&fsnotify.Create == fsnotify.Create
|
||||
case "linux":
|
||||
trigger = event.Op&fsnotify.Write == fsnotify.Write
|
||||
default:
|
||||
trigger = event.Op&fsnotify.Create == fsnotify.Create
|
||||
log("reload: untested GOOS %q; this package may not work correctly", runtime.GOOS)
|
||||
}
|
||||
|
||||
if !trigger {
|
||||
continue
|
||||
}
|
||||
|
||||
if event.Name == binSelf {
|
||||
// Wait for writes to finish.
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
ReExec()
|
||||
}
|
||||
|
||||
for _, a := range additional {
|
||||
if strings.HasPrefix(event.Name, a.path) {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
a.cb()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for _, d := range dirs {
|
||||
if err := watcher.Add(d); err != nil {
|
||||
return errors.Wrapf(err, "cannot add %q to watcher", d)
|
||||
}
|
||||
}
|
||||
|
||||
add := ""
|
||||
if len(additional) > 0 {
|
||||
reldirs := make([]string, len(dirs)-1)
|
||||
for i := range dirs[1:] {
|
||||
reldirs[i] = relpath(dirs[i+1])
|
||||
}
|
||||
add = fmt.Sprintf(" (additional dirs: %s)", strings.Join(reldirs, ", "))
|
||||
}
|
||||
log("restarting %q when it changes%s", relpath(binSelf), add)
|
||||
<-done
|
||||
return nil
|
||||
}
|
||||
|
||||
// Exec replaces the current process with a new copy of itself.
|
||||
func ReExec() {
|
||||
err := syscall.Exec(binSelf, append([]string{binSelf}, os.Args[1:]...), os.Environ())
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot restart: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// Get location to executable.
|
||||
func self() (string, error) {
|
||||
bin := os.Args[0]
|
||||
if !filepath.IsAbs(bin) {
|
||||
var err error
|
||||
bin, err = os.Executable()
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err,
|
||||
"cannot get path to binary %q (launch with absolute path): %v",
|
||||
os.Args[0], err)
|
||||
}
|
||||
}
|
||||
return bin, nil
|
||||
}
|
||||
|
||||
// Get path relative to cwd
|
||||
func relpath(p string) string {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return p
|
||||
}
|
||||
|
||||
if strings.HasPrefix(p, cwd) {
|
||||
return "./" + strings.TrimLeft(p[len(cwd):], "/")
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
21
serv/serv.go
21
serv/serv.go
@ -171,6 +171,26 @@ func initCompilers(c *config) (*qcode.Compiler, *psql.Compiler, error) {
|
||||
return qc, pc, nil
|
||||
}
|
||||
|
||||
func initWatcher(path string) {
|
||||
if conf.WatchAndReload == false {
|
||||
return
|
||||
}
|
||||
|
||||
var d dir
|
||||
if len(path) == 0 || path == "./" {
|
||||
d = Dir("./config", ReExec)
|
||||
} else {
|
||||
d = Dir(path, ReExec)
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := Do(logger.Printf, d)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func Init() {
|
||||
var err error
|
||||
|
||||
@ -206,6 +226,7 @@ func Init() {
|
||||
|
||||
initAllowList(*path)
|
||||
initPreparedList()
|
||||
initWatcher(*path)
|
||||
|
||||
startHTTP()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user