Skip to content

Commit

Permalink
Merge pull request #13 from minazukie/feature/hot-restart
Browse files Browse the repository at this point in the history
Add hot restart
  • Loading branch information
张亮 authored Jan 17, 2020
2 parents 50bfbdd + 7707e01 commit f925301
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 64 deletions.
67 changes: 15 additions & 52 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,31 @@
package main

import (
"encoding/json"
"flag"
"github.com/GoSome/fileUpdater/pkg/core"
"github.com/GoSome/fileUpdater/pkg/config"
"github.com/GoSome/fileUpdater/pkg/listeners"
"github.com/GoSome/fileUpdater/pkg/server"
"github.com/sevlyar/go-daemon"
"gopkg.in/yaml.v3"
"log"
"os"
"strings"
)

var configPath string
var daemonZ bool
var pidPath string
var logFile string
var config core.ServerConfigs

func main() {
flag.StringVar(&configPath, "config", "config.json", "server config file path")
flag.BoolVar(&daemonZ, "d", false, "daemon")
flag.StringVar(&pidPath, "pid", "", "pid path work in daemon")
flag.StringVar(&logFile, "log", "", "log path work in daemon")
flag.StringVar(&config.Path, "config", "config.json", "server config file path")
flag.BoolVar(&config.DaemonZ, "d", false, "daemon")
flag.StringVar(&config.PidPath, "pid", "", "pid path work in daemon")
flag.StringVar(&config.LogFile, "log", "", "log path work in daemon")
flag.Parse()

ParseConfig()
if daemonZ {
config.Parse(true)

listeners.ListenSIGUSR2()
go config.Watch()

if config.DaemonZ {
cntxt := &daemon.Context{
PidFileName: pidPath,
PidFileName: config.PidPath,
PidFilePerm: 0644,
LogFileName: logFile,
LogFileName: config.LogFile,
LogFilePerm: 0640,
WorkDir: "./",
Umask: 027,
Expand All @@ -57,37 +52,5 @@ func main() {
log.Print("daemon started")
}

server.Run(config)
}

func ParseConfig() {

if _, err := os.Stat(configPath); os.IsNotExist(err) {
log.Fatalf("config file \"%s\" not exist", configPath)
}

configFile, err := os.Open(configPath)
if err != nil {
log.Fatalf("open config file \"%s\" failed", configPath)
return
}
if strings.HasSuffix(configPath, ".json") {
//
err = json.NewDecoder(configFile).Decode(&config)
if err != nil {
// todo
panic(err)
}
} else if strings.HasSuffix(configPath, ".yaml") {
err := yaml.NewDecoder(configFile).Decode(&config)
if err != nil {
// todo
log.Println("err: ", err.Error())
panic(err)
}
} else {
panic("config file path must end with .json or .yaml")
}

configFile.Close()
server.Run(config.Config)
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.13

require (
github.com/GeertJohan/go.rice v1.0.0
github.com/fsnotify/fsnotify v1.4.7
github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2 // indirect
github.com/gin-gonic/gin v1.5.0
github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CL
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2 h1:xLG16iua01X7Gzms9045s2Y2niNpvSY/Zb1oBwgNYZY=
Expand Down
80 changes: 80 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package config

import (
"encoding/json"
"github.com/GoSome/fileUpdater/pkg/core"
"github.com/fsnotify/fsnotify"
"github.com/gin-gonic/gin"
"gopkg.in/yaml.v3"
"log"
"os"
"path"
)

var Path string
var Config core.ServerConfigs
var DaemonZ bool
var PidPath string
var LogFile string

func Parse(init bool) {
logFunc := log.Printf
if init {
logFunc = log.Fatalf
}
if _, err := os.Stat(Path); os.IsNotExist(err) {
logFunc("config file \"%s\" not exist", Path)
return
}

configFile, err := os.Open(Path)
if err != nil {
logFunc("open config file \"%s\" failed", Path)
return
}
defer configFile.Close()

switch path.Ext(Path) {
case ".json":
err = json.NewDecoder(configFile).Decode(&Config)
if err != nil {
logFunc("%s", err)
}
case ".yml":
fallthrough
case ".yaml":
err := yaml.NewDecoder(configFile).Decode(&Config)
if err != nil {
logFunc("%s", err)
}
default:
logFunc("config file path must end with .json or .yaml")
}
}

// Inject injects config into gin's context.
func Inject(c *gin.Context) {
c.Set("cfg", Config)
c.Next()
}

// Watch watches config file, configs will be reloaded when config file is changed.
func Watch() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()

watcher.Add(Path)

for {
select {
case ev := <-watcher.Events:
if ev.Op == fsnotify.Write {
log.Println("config file has been changed, attempt to reload...")
Parse(false)
}
}
}
}
1 change: 0 additions & 1 deletion pkg/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
)

// server configFiles struct

type ServerConfigs struct {
ServerHost string `json:"server_host" yaml:"server_host"`
ServerPort string `json:"server_port" yaml:"server_port"`
Expand Down
22 changes: 22 additions & 0 deletions pkg/listeners/sig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package listeners

import (
"github.com/GoSome/fileUpdater/pkg/config"
"log"
"os"
"os/signal"
"syscall"
)

func ListenSIGUSR2() {
s := make(chan os.Signal, 1)
signal.Notify(s, syscall.SIGUSR2)

go func() {
for {
<-s
log.Println("config file has been changed, attempt to reload...")
config.Parse(false)
}
}()
}
8 changes: 6 additions & 2 deletions pkg/server/getContent.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,22 @@
package server

import (
"github.com/GoSome/fileUpdater/pkg/core"
"github.com/gin-gonic/gin"
)

func GetContent(c *gin.Context) {

name := c.Query("name")
if name == "" {
// todo
c.String(200, "nothing i found")
return
}
u := Configs.GetUpdaterByName(name)

getConfig, _ := c.Get("cfg")
cfg := getConfig.(core.ServerConfigs)

u := cfg.GetUpdaterByName(name)
if u == nil {
c.String(400, "no idea")
return
Expand Down
5 changes: 4 additions & 1 deletion pkg/server/getUpdater.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ func GetUpdater(c *gin.Context) {
return
}

u := Configs.GetUpdaterByName(name)
getConfig, _ := c.Get("cfg")
cfg := getConfig.(core.ServerConfigs)

u := cfg.GetUpdaterByName(name)
if u == nil {
c.String(404, "Not Found")
return
Expand Down
3 changes: 2 additions & 1 deletion pkg/server/getUpdaters.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ package server

import (
"encoding/json"
"github.com/GoSome/fileUpdater/pkg/config"
"github.com/gin-gonic/gin"
"log"
)

func GetUpdaters(c *gin.Context) {
updates := Configs.FileUpdaters
updates := config.Config.FileUpdaters
log.Printf("updates: %s", updates)
c.Header("Content-Type", "application/json")
err := json.NewEncoder(c.Writer).Encode(&updates)
Expand Down
11 changes: 5 additions & 6 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,22 @@ package server
import (
rice "github.com/GeertJohan/go.rice"
"github.com/GoSome/fileUpdater/pkg/binding"
"github.com/GoSome/fileUpdater/pkg/config"
"github.com/GoSome/fileUpdater/pkg/core"
"github.com/gin-gonic/gin"
"log"
)

var configPath string
var Configs core.ServerConfigs

func Run(config core.ServerConfigs) {
Configs = config

func Run(cfg core.ServerConfigs) {
app := gin.Default()
app.Use(config.Inject)

app.StaticFS("statics/", rice.MustFindBox("dist").HTTPBox())
app.GET("/api/updaters", GetUpdaters)
app.GET("/api/updater", GetUpdater)
app.GET("/api/content", GetContent)
app.POST("/api/content", UpdateFile)
app.NoRoute(binding.Index)
log.Fatal(app.Run(Configs.ServerHost + ":" + Configs.ServerPort))
log.Fatal(app.Run(cfg.ServerHost + ":" + cfg.ServerPort))
}
7 changes: 6 additions & 1 deletion pkg/server/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package server

import (
"encoding/json"
"github.com/GoSome/fileUpdater/pkg/core"
"github.com/gin-gonic/gin"
"log"
"strings"
Expand All @@ -19,7 +20,11 @@ func UpdateFile(c *gin.Context) {
return
}

updaters := Configs.GetUpdaterByName(req.Name)
getConfig, _ := c.Get("cfg")
cfg := getConfig.(core.ServerConfigs)


updaters := cfg.GetUpdaterByName(req.Name)
if updaters == nil {
c.String(404, "Not Found")
return
Expand Down

0 comments on commit f925301

Please sign in to comment.