mirror of
https://github.com/edwingeng/hotswap.git
synced 2025-12-24 11:52:07 +08:00
refactor for Windows compatibility
This commit is contained in:
12
README.md
12
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
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -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, "")
|
||||
}
|
||||
|
||||
@@ -44,4 +44,4 @@ plugin/dog/build.sh
|
||||
echo
|
||||
|
||||
echo "Sending signal..."
|
||||
kill -USR1 `cat "bin/$xOS/$PROGRAM.pid"`
|
||||
touch "bin/$xOS/$PROGRAM.reload"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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("<hotswap> reloading...")
|
||||
details, err := swapper.Reload(nil)
|
||||
if staticLinking {
|
||||
if err != nil {
|
||||
g.Logger.Errorf("<hotswap> %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("<hotswap> %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("<hotswap> reloading...")
|
||||
details, err := swapper.Reload(nil)
|
||||
if staticLinking {
|
||||
if err != nil {
|
||||
g.Logger.Errorf("<hotswap> %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("<hotswap> %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")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user