Skip to content

Instantly share code, notes, and snippets.

@Gitart
Created October 29, 2016 15:34
Show Gist options
  • Save Gitart/24cad3e6b7915658801ea52c74571527 to your computer and use it in GitHub Desktop.
Save Gitart/24cad3e6b7915658801ea52c74571527 to your computer and use it in GitHub Desktop.
App worker
package main
/*
Run and it will create appmaster.exe which will create a new appworker.exe if it is shutdown.
Must delete appmaster.exe before each run.
Only tested on Windows.
Should build with: -ldflags -H windowsgui
*/
import (
"io/ioutil"
"log"
"os"
"os/exec"
"strconv"
"strings"
"time"
)
const (
sleepTimeout = 200
)
func main() {
self := os.Args[0]
pid := os.Getpid()
// Start Worker
if len(os.Args) != 2 {
slave := strings.Replace(self, "appworker.exe", "appmaster.exe", -1)
if !fileExists(slave) {
copyFile(self, slave)
cmd := exec.Command(slave, string(pid))
err := cmd.Start()
if err != nil {
log.Println("Start error:", err)
}
cmd.Process.Release()
} else {
for {
// This is where you do work
time.Sleep(sleepTimeout * time.Millisecond)
}
}
log.Println("Master:", pid)
} else { // Start Master
app := strings.Replace(self, "appmaster.exe", "appworker.exe", -1)
i, _ := strconv.Atoi(os.Args[1])
var p *os.Process
var err error
// Loop foreach
for {
// If process was killed
if p, err = os.FindProcess(i); err != nil {
cmd := exec.Command(app)
err = cmd.Start()
if err != nil {
log.Println("Start error:", err)
break
}
i = cmd.Process.Pid
cmd.Process.Release()
} else { // Process is still alive
p.Release()
}
time.Sleep(sleepTimeout * time.Millisecond)
}
}
}
func copyFile(src string, dst string) {
// Read all content of src to data
data, err := ioutil.ReadFile(src)
if err != nil {
log.Fatal(err)
}
// Write data to dst
err = ioutil.WriteFile(dst, data, 0644)
if err != nil {
log.Fatal(err)
}
}
func fileExists(filename string) bool {
if _, err := os.Stat(filename); err == nil {
return true
}
return false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment