diff --git a/README.md b/README.md index 039bb12..e94699d 100644 --- a/README.md +++ b/README.md @@ -62,12 +62,12 @@ A plugin must have the following functions defined in its root package. // OnLoad gets called after all plugins are successfully loaded and all dependencies are // properly initialized. func OnLoad(data interface{}) error { - return nil + return nil } // OnInit gets called after the execution of all OnLoad functions. func OnInit(sharedVault *vault.Vault) error { - return nil + return nil } // OnFree gets called at some time after a reload. @@ -76,22 +76,22 @@ func OnFree() { // Export returns an object to be exported to other plugins. func Export() interface{} { - return nil + return nil } // Import returns an object indicating the dependencies of the plugin. func Import() interface{} { - return nil + return nil } // InvokeFunc invokes the specified function. func InvokeFunc(name string, params ...interface{}) (interface{}, error) { - return nil, nil + return nil, nil } // Reloadable indicates whether the plugin is reloadable. func Reloadable() bool { - return true + return true } ``` diff --git a/README.zh-CN.md b/README.zh-CN.md index 61f0e2f..c0a72da 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -60,12 +60,12 @@ Flags: // OnLoad gets called after all plugins are successfully loaded and all dependencies are // properly initialized. func OnLoad(data interface{}) error { - return nil + return nil } // OnInit gets called after the execution of all OnLoad functions. func OnInit(sharedVault *vault.Vault) error { - return nil + return nil } // OnFree gets called at some time after a reload. @@ -74,22 +74,22 @@ func OnFree() { // Export returns an object to be exported to other plugins. func Export() interface{} { - return nil + return nil } // Import returns an object indicating the dependencies of the plugin. func Import() interface{} { - return nil + return nil } // InvokeFunc invokes the specified function. func InvokeFunc(name string, params ...interface{}) (interface{}, error) { - return nil, nil + return nil, nil } // Reloadable indicates whether the plugin is reloadable. func Reloadable() bool { - return true + return true } ``` diff --git a/cli/hotswap/cmd/build.go b/cli/hotswap/cmd/build.go index 77a122b..002cc8f 100644 --- a/cli/hotswap/cmd/build.go +++ b/cli/hotswap/cmd/build.go @@ -273,7 +273,7 @@ next1: }() defer func() { select { - case chSignal <- syscall.SIGUSR1: + case chSignal <- syscall.SIGQUIT: default: } <-done @@ -281,6 +281,10 @@ next1: var outputFile string if !wo.staticLinking { + if runtime.GOOS == "windows" { + _, _ = os.Stderr.WriteString("Go plugin does not support Windows at present. Use --staticLinking if you only want to debug.\n") + os.Exit(1) + } if os.Getenv("hotswap:checkRequiredPluginFuncs") != "1" { parseRequiredPluginFuncs(wo.pluginDir, "") } diff --git a/demo/slink/reload.sh b/demo/slink/reload.sh index a322fd2..ec189f7 100755 --- a/demo/slink/reload.sh +++ b/demo/slink/reload.sh @@ -44,4 +44,4 @@ plugin/dog/build.sh echo echo "Sending signal..." -kill -USR1 `cat "bin/$xOS/$PROGRAM.pid"` +touch "bin/$xOS/$PROGRAM.reload" diff --git a/demo/slink/run.sh b/demo/slink/run.sh index e16f834..a61818a 100755 --- a/demo/slink/run.sh +++ b/demo/slink/run.sh @@ -69,4 +69,4 @@ if [[ $REPLY =~ ^[Nn]$ ]]; then fi printf "Starting $PROGRAM...\n\n" -"$PROGRAM_EXE" --pluginDir="bin/$xOS/plugin/$PROGRAM" --pidFile="bin/$xOS/$PROGRAM.pid" "$staticLinking" +"$PROGRAM_EXE" --pluginDir="bin/$xOS/plugin/$PROGRAM" --pidFile="bin/$xOS/$PROGRAM.pid" --signalFile="bin/$xOS/$PROGRAM.reload" "$staticLinking" diff --git a/demo/slink/slink.go b/demo/slink/slink.go index fc4b7d8..16984a4 100644 --- a/demo/slink/slink.go +++ b/demo/slink/slink.go @@ -26,9 +26,11 @@ func init() { func main() { var pluginDir string var pidFile string + var signalFile string var staticLinking bool flag.StringVar(&pluginDir, "pluginDir", "", "the directory holding your plugins") flag.StringVar(&pidFile, "pidFile", "", "pid file path") + flag.StringVar(&signalFile, "signalFile", "", "once the specified file is found on your disk, reload all plugins") flag.BoolVar(&staticLinking, "staticLinking", false, "link plugin statically (not reloadable)") flag.Parse() @@ -42,6 +44,9 @@ func main() { if pidFile == "" { panic("no --pidFile") } + if signalFile == "" { + panic("no --signalFile") + } pid := fmt.Sprint(os.Getpid()) if err := ioutil.WriteFile(pidFile, []byte(pid), 0644); err != nil { @@ -74,9 +79,40 @@ func main() { } }() + go func() { + for range time.Tick(time.Millisecond * 50) { + if _, err := os.Stat(signalFile); err != nil { + continue + } + g.Logger.Info(" reloading...") + details, err := swapper.Reload(nil) + if staticLinking { + if err != nil { + g.Logger.Errorf(" %s", err) + break + } + panic("impossible") + } + if err != nil { + panic(err) + } else if len(details) == 0 { + g.Logger.Infof("no plugin is found in " + absDir) + } else { + g.Logger.Infof(" %d plugin(s) loaded. details: [%s]", + len(details), details) + } + + heartbeat() + if err := os.Remove(signalFile); err != nil { + g.Logger.Error(err) + os.Exit(1) + } + } + }() + // Wait for signals chSignal := make(chan os.Signal, 1) - signal.Notify(chSignal, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1) + signal.Notify(chSignal, syscall.SIGINT, syscall.SIGTERM) loop: for { @@ -86,30 +122,11 @@ loop: switch sig { case syscall.SIGINT, syscall.SIGTERM: break loop - case syscall.SIGUSR1: - g.Logger.Info(" reloading...") - details, err := swapper.Reload(nil) - if staticLinking { - if err != nil { - g.Logger.Errorf(" %s", err) - break - } - panic("impossible") - } - if err != nil { - panic(err) - } else if len(details) == 0 { - g.Logger.Infof("no plugin is found in " + absDir) - } else { - g.Logger.Infof(" %d plugin(s) loaded. details: [%s]", - len(details), details) - } - heartbeat() } } } - signal.Reset(syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1) + signal.Reset(syscall.SIGINT, syscall.SIGTERM) g.Logger.Info("THE END") }