Skip to content

Instantly share code, notes, and snippets.

@ZurgInq
Created May 2, 2017 19:35
Show Gist options
  • Save ZurgInq/14cbc8ee0768544ee9c4ff44152c3425 to your computer and use it in GitHub Desktop.
Save ZurgInq/14cbc8ee0768544ee9c4ff44152c3425 to your computer and use it in GitHub Desktop.
Go auto update, auto restart (Windows)
package main
import (
"github.com/inconshreveable/go-update"
"net/http"
"log"
"fmt"
"github.com/kardianos/service"
"os"
"os/signal"
"syscall"
"time"
)
var (
version = "1"
)
func doUpdate(url string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
err = update.Apply(resp.Body, update.Options{
})
if err != nil {
log.Println("update failed")
}
return err
}
type exampleApp struct{
srv http.Server
}
func (p *exampleApp) Start(s service.Service) error {
// Start should not block. Do the actual work async.
go p.run()
return nil
}
func (p *exampleApp) run() {
// Do work here
log.Fatal(p.srv.ListenAndServe())
}
func (p *exampleApp) Stop(s service.Service) error {
// Stop should not block. Return with a few seconds.
p.srv.Shutdown(nil)
return nil
}
func (p *exampleApp) Exit(code int) {
// Stop should not block. Return with a few seconds.
p.srv.Shutdown(nil)
os.Exit(code)
}
func main() {
fmt.Println(version)
svcConfig := &service.Config{
Name: "Example",
DisplayName: "Go Service Example",
Description: "This is an example Go service.",
}
app := &exampleApp{
srv: http.Server{Addr: ":8080"},
}
appService, err := service.New(app, svcConfig)
appService.Install()
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/version", func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(200)
rw.Write([]byte(version))
})
http.HandleFunc("/update", func(rw http.ResponseWriter, req *http.Request) {
err := doUpdate("http://localhost:8081/app")
log.Println(err)
rw.WriteHeader(200)
time.AfterFunc(1 * time.Second, func() {
app.Exit(1)
})
})
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGKILL)
go func() {
<-sigs
app.srv.Shutdown(nil)
os.Exit(0)
}()
appService.Run()
}
#create service
sc create Example binPath=c:\gopath\src\...
#autorestart
sc failure Example reset=60 actions=restart/0
package main
import (
"net/http"
"log"
)
func main() {
http.HandleFunc("/app", func(rw http.ResponseWriter, req *http.Request) {
http.ServeFile(rw, req, "app.exe")
})
log.Fatal(http.ListenAndServe(":8081", nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment