diff --git a/.gitignore b/.gitignore index 171f88d..13bd2e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ rippleapi +rippleapi.exe api -api.conf \ No newline at end of file +api.conf diff --git a/app/v1/meta.go b/app/v1/meta_linux.go similarity index 99% rename from app/v1/meta.go rename to app/v1/meta_linux.go index 87f0166..40f919e 100644 --- a/app/v1/meta.go +++ b/app/v1/meta_linux.go @@ -1,3 +1,5 @@ +// +build !windows + package v1 import ( diff --git a/app/v1/meta_windows.go b/app/v1/meta_windows.go new file mode 100644 index 0000000..eb304df --- /dev/null +++ b/app/v1/meta_windows.go @@ -0,0 +1,42 @@ +// +build windows + +package v1 + +import ( + "time" + + "git.zxq.co/ripple/rippleapi/common" +) + +// MetaRestartGET restarts the API with Zero Downtime™. +func MetaRestartGET(md common.MethodData) common.CodeMessager { + return common.SimpleResponse(200, "brb in your dreams") +} + +// MetaKillGET kills the API process. NOTE TO EVERYONE: NEVER. EVER. USE IN PROD. +// Mainly created because I couldn't bother to fire up a terminal, do htop and kill the API each time. +func MetaKillGET(md common.MethodData) common.CodeMessager { + return common.SimpleResponse(200, "haha") +} + +var upSince = time.Now() + +type metaUpSinceResponse struct { + common.ResponseBase + Code int `json:"code"` + Since int64 `json:"since"` +} + +// MetaUpSinceGET retrieves the moment the API application was started. +// Mainly used to get if the API was restarted. +func MetaUpSinceGET(md common.MethodData) common.CodeMessager { + return metaUpSinceResponse{ + Code: 200, + Since: int64(upSince.UnixNano()), + } +} + +// MetaUpdateGET updates the API to the latest version, and restarts it. +func MetaUpdateGET(md common.MethodData) common.CodeMessager { + return common.SimpleResponse(200, "lol u wish") +} diff --git a/main.go b/main.go index 5c92a10..a09463d 100644 --- a/main.go +++ b/main.go @@ -4,15 +4,11 @@ import ( "database/sql" "fmt" "log" - "net" - "net/http" "syscall" - "time" "git.zxq.co/ripple/rippleapi/app" "git.zxq.co/ripple/rippleapi/common" "git.zxq.co/ripple/schiavolib" - "github.com/rcrowley/goagain" // Golint pls dont break balls _ "github.com/go-sql-driver/mysql" ) @@ -27,6 +23,8 @@ func init() { common.Version = Version } +var db *sql.DB + func main() { fmt.Print("Ripple API") if Version != "" { @@ -41,65 +39,13 @@ func main() { schiavo.Prefix = "Ripple API" - db, err := sql.Open(conf.DatabaseType, conf.DSN) + var err error + db, err = sql.Open(conf.DatabaseType, conf.DSN) if err != nil { schiavo.Bunker.Send(err.Error()) log.Fatalln(err) } engine := app.Start(conf, db) - // Inherit a net.Listener from our parent process or listen anew. - l, err := goagain.Listener() - if nil != err { - - // Listen on a TCP or a UNIX domain socket (TCP here). - if conf.Unix { - l, err = net.Listen("unix", conf.ListenTo) - } else { - l, err = net.Listen("tcp", conf.ListenTo) - } - if nil != err { - schiavo.Bunker.Send(err.Error()) - log.Fatalln(err) - } - - schiavo.Bunker.Send(fmt.Sprint("LISTENINGU STARTUATO ON ", l.Addr())) - - // Accept connections in a new goroutine. - go http.Serve(l, engine) - - } else { - - // Resume accepting connections in a new goroutine. - schiavo.Bunker.Send(fmt.Sprint("LISTENINGU RESUMINGU ON ", l.Addr())) - go http.Serve(l, engine) - - // Kill the parent, now that the child has started successfully. - if err := goagain.Kill(); nil != err { - schiavo.Bunker.Send(err.Error()) - log.Fatalln(err) - } - - } - - // Block the main goroutine awaiting signals. - if _, err := goagain.Wait(l); nil != err { - schiavo.Bunker.Send(err.Error()) - log.Fatalln(err) - } - - // Do whatever's necessary to ensure a graceful exit like waiting for - // goroutines to terminate or a channel to become closed. - // - // In this case, we'll simply stop listening and wait one second. - if err := l.Close(); nil != err { - schiavo.Bunker.Send(err.Error()) - log.Fatalln(err) - } - if err := db.Close(); err != nil { - schiavo.Bunker.Send(err.Error()) - log.Fatalln(err) - } - time.Sleep(time.Second * 1) - + startuato(engine) } diff --git a/startuato_linux.go b/startuato_linux.go new file mode 100644 index 0000000..e5e7156 --- /dev/null +++ b/startuato_linux.go @@ -0,0 +1,73 @@ +// +build !windows + +package main + +import ( + "log" + "net" + "net/http" + "fmt" + "time" + + "git.zxq.co/ripple/schiavolib" + "git.zxq.co/ripple/rippleapi/common" + "github.com/gin-gonic/gin" + "github.com/rcrowley/goagain" +) + +func startuato(engine *gin.Engine) { + conf, _ := common.Load() + // Inherit a net.Listener from our parent process or listen anew. + l, err := goagain.Listener() + if nil != err { + + // Listen on a TCP or a UNIX domain socket (TCP here). + if conf.Unix { + l, err = net.Listen("unix", conf.ListenTo) + } else { + l, err = net.Listen("tcp", conf.ListenTo) + } + if nil != err { + schiavo.Bunker.Send(err.Error()) + log.Fatalln(err) + } + + schiavo.Bunker.Send(fmt.Sprint("LISTENINGU STARTUATO ON ", l.Addr())) + + // Accept connections in a new goroutine. + go http.Serve(l, engine) + + } else { + + // Resume accepting connections in a new goroutine. + schiavo.Bunker.Send(fmt.Sprint("LISTENINGU RESUMINGU ON ", l.Addr())) + go http.Serve(l, engine) + + // Kill the parent, now that the child has started successfully. + if err := goagain.Kill(); nil != err { + schiavo.Bunker.Send(err.Error()) + log.Fatalln(err) + } + + } + + // Block the main goroutine awaiting signals. + if _, err := goagain.Wait(l); nil != err { + schiavo.Bunker.Send(err.Error()) + log.Fatalln(err) + } + + // Do whatever's necessary to ensure a graceful exit like waiting for + // goroutines to terminate or a channel to become closed. + // + // In this case, we'll simply stop listening and wait one second. + if err := l.Close(); nil != err { + schiavo.Bunker.Send(err.Error()) + log.Fatalln(err) + } + if err := db.Close(); err != nil { + schiavo.Bunker.Send(err.Error()) + log.Fatalln(err) + } + time.Sleep(time.Second * 1) +} diff --git a/startuato_windows.go b/startuato_windows.go new file mode 100644 index 0000000..3accce9 --- /dev/null +++ b/startuato_windows.go @@ -0,0 +1,31 @@ +// +build windows + +package main + +import ( + "net" + "log" + "net/http" + + "github.com/gin-gonic/gin" + "git.zxq.co/ripple/rippleapi/common" +) + +func startuato(engine *gin.Engine) { + conf, _ := common.Load() + var ( + l net.Listener + err error + ) + // Listen on a TCP or a UNIX domain socket (TCP here). + if conf.Unix { + l, err = net.Listen("unix", conf.ListenTo) + } else { + l, err = net.Listen("tcp", conf.ListenTo) + } + if nil != err { + log.Fatalln(err) + } + + http.Serve(l, engine) +}