diff --git a/main.go b/main.go index bea2bfa..2baa647 100644 --- a/main.go +++ b/main.go @@ -23,8 +23,10 @@ import ( "net/http" _ "net/http/pprof" "os" + "os/signal" "runtime" "strings" + "syscall" "time" "github.com/b3log/wide/conf" @@ -72,14 +74,11 @@ func init() { } i18n.Load() - event.Load() - conf.Load(*confPath, *confIP, *confPort, *confServer, *confLogLevel, *confStaticServer, *confContext, *confChannel, *confPlayground, *confDocker, *confUsersWorkspaces) conf.FixedTimeCheckEnv() - session.FixedTimeSave() session.FixedTimeRelease() @@ -96,6 +95,7 @@ func main() { runtime.GOMAXPROCS(conf.Wide.MaxProcs) initMime() + handleSignal() // IDE http.HandleFunc(conf.Wide.Context+"/", handlerGzWrapper(indexHandler)) @@ -242,7 +242,6 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { logger.Debugf("User [%s] has [%d] sessions", username, len(wideSessions)) t, err := template.ParseFiles("views/index.html") - if nil != err { logger.Error(err) http.Error(w, err.Error(), 500) @@ -253,6 +252,22 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { t.Execute(w, model) } +// handleSignal handles system signal for graceful shutdown. +func handleSignal() { + go func() { + c := make(chan os.Signal) + + signal.Notify(c, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM) + s := <-c + logger.Tracef("Got signal [%s]", s) + + session.SaveOnlineUsers() + logger.Tracef("Saved all online user, exit") + + os.Exit(0) + }() +} + // serveSingle registers the handler function for the given pattern and filename. func serveSingle(pattern string, filename string) { http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { diff --git a/session/users.go b/session/users.go index e1a0a14..78f1fac 100644 --- a/session/users.go +++ b/session/users.go @@ -70,11 +70,11 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) { tmpLinux := user.GoBuildArgsForLinux tmpWindows := user.GoBuildArgsForWindows tmpDarwin := user.GoBuildArgsForDarwin - + user.GoBuildArgsForLinux = strings.Replace(user.GoBuildArgsForLinux, `"`, `"`, -1) user.GoBuildArgsForWindows = strings.Replace(user.GoBuildArgsForWindows, `"`, `"`, -1) user.GoBuildArgsForDarwin = strings.Replace(user.GoBuildArgsForDarwin, `"`, `"`, -1) - + model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(user.Locale), "user": user, "ver": conf.WideVersion, "goos": runtime.GOOS, "goarch": runtime.GOARCH, "gover": runtime.Version(), "locales": i18n.GetLocalesNames(), "gofmts": util.Go.GetGoFormats(), @@ -85,7 +85,7 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) { if nil != err { logger.Error(err) http.Error(w, err.Error(), 500) - + user.GoBuildArgsForLinux = tmpLinux user.GoBuildArgsForWindows = tmpWindows user.GoBuildArgsForDarwin = tmpDarwin @@ -93,7 +93,7 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) { } t.Execute(w, model) - + user.GoBuildArgsForLinux = tmpLinux user.GoBuildArgsForWindows = tmpWindows user.GoBuildArgsForDarwin = tmpDarwin @@ -308,13 +308,7 @@ func FixedTimeSave() { defer util.Recover() for _ = range time.Tick(time.Minute) { - users := getOnlineUsers() - - for _, u := range users { - if u.Save() { - logger.Tracef("Saved online user [%s]'s configurations", u.Name) - } - } + SaveOnlineUsers() } }() } @@ -335,6 +329,16 @@ func CanAccess(username, path string) bool { return false } +// SaveOnlineUsers saves online users' configurations at once. +func SaveOnlineUsers() { + users := getOnlineUsers() + for _, u := range users { + if u.Save() { + logger.Tracef("Saved online user [%s]'s configurations", u.Name) + } + } +} + func getOnlineUsers() []*conf.User { ret := []*conf.User{}