Skip to content

Instantly share code, notes, and snippets.

@rossedman
Last active April 6, 2020 03:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rossedman/210e8e9b44e7f1af198505e744e88552 to your computer and use it in GitHub Desktop.
Save rossedman/210e8e9b44e7f1af198505e744e88552 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
type Config struct {
sync.Mutex
Port string `json:"port"`
}
func (c *Config) Init() {
// lock accessing the config
c.Lock()
defer c.Unlock()
// open the config file
f, err := os.Open("config.json")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// read the file into a byte array
bytes, _ := ioutil.ReadAll(f)
// create the config
var config Config
// hydrate the fields
json.Unmarshal(bytes, &config)
// set
c.Port = config.Port
}
func main() {
config := &Config{}
config.Init()
go func() {
sigHUP := make(chan os.Signal, 1)
signal.Notify(sigHUP, syscall.SIGHUP)
for {
select {
case <-sigHUP:
config.Init()
}
}
}()
ticker := time.NewTicker(time.Second * 5)
for {
select {
case <-ticker.C:
config.Lock()
defer config.Unlock()
fmt.Println("New port:", config.Port)
}
}
}
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
for {
if err := waitForSignals(); err != nil {
fmt.Printf("Error with signal: %v\n", err)
return
}
}
}
func waitForSignals() error {
signals := make(chan os.Signal, 1024)
signal.Notify(signals, syscall.SIGHUP, syscall.SIGUSR1, syscall.SIGUSR2)
for {
select {
case s := <-signals:
switch s {
case syscall.SIGHUP:
fmt.Printf("SIGHUP. Reload config.\n")
return nil
case syscall.SIGUSR1:
fmt.Printf("SIGUSR1. Zero downtime deployment. \n")
return nil
case syscall.SIGUSR2:
fmt.Printf("SIGUSR2. Restart task\n")
}
}
}
}
package main
import (
"fmt"
"os"
"sync"
"time"
)
func watcher(file string, wg *sync.WaitGroup) {
ticker := time.NewTicker(time.Second)
timeout := time.NewTimer(time.Minute)
for {
select {
case <-ticker.C:
_, err := os.Stat(file)
if os.IsNotExist(err) {
fmt.Println("[DEBUG] checking for file", file)
} else {
fmt.Println("[DEBUG] file exists", file)
wg.Done()
return
}
case <-timeout.C:
fmt.Println("[ERROR] timeout waiting for file", file)
wg.Done()
return
}
}
}
func main() {
var wg sync.WaitGroup
files := []string{
"/home/rossedman/.test1",
"/home/rossedman/.test2",
"/home/rossedman/.test3",
}
for _, f := range files {
wg.Add(1)
go watcher(f, &wg)
}
wg.Wait()
fmt.Println("[INFO] all files ready")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment