Skip to content

Instantly share code, notes, and snippets.

@MohamedBassem
Last active May 19, 2016 12:39
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 MohamedBassem/0f294d6df244e4def877e01d98af47af to your computer and use it in GitHub Desktop.
Save MohamedBassem/0f294d6df244e4def877e01d98af47af to your computer and use it in GitHub Desktop.
USR1 Signal in Go
USR1 Signal in Go
package main
import (
"fmt"
"io/ioutil"
"os"
"os/signal"
"sync"
"syscall"
"time"
"gopkg.in/yaml.v2"
)
// The config struct, having only a single field Name that will be printed
type config struct {
Name string
}
// Context is a struct to wrap the config file and guard it with a mutex
type context struct {
config
sync.Mutex
}
// The global context variable
var ctx *context
func (c *context) Config() config {
c.Lock()
cnf := c.config
c.Unlock()
return cnf
}
// A function that reads the file "config.yml" and returns a pointer to an instance of the config struct.
func readConfig() config {
content, err := ioutil.ReadFile("config.yml")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
var tmpCnf config
err = yaml.Unmarshal(content, &tmpCnf)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
return tmpCnf
}
// That's the interesting part
func swapConfig(c chan os.Signal) {
for {
// This line will block until the signal is received
<-c
// Whenever the signal is received. Read the configuration file and swap the old config out.
ctx.Lock()
ctx.config = readConfig()
ctx.Unlock()
}
}
func main() {
fmt.Printf("Process PID : %v\n", os.Getpid())
ctx = &context{config: readConfig()}
c := make(chan os.Signal, 1)
// Send to channel c whenver you receive a SIGUSR1 signal.
signal.Notify(c, syscall.SIGUSR1)
go swapConfig(c)
for {
fmt.Println(ctx.Config().Name)
time.Sleep(time.Second)
}
}
func handle(c chan os.Signal) {
for {
<-c // This line will block until a signal is received
// DO SOMETHING
}
}
func main() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGUSR1)
go handle(c)
}
package main
import (
"fmt"
"io"
"io/ioutil"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
// The io.Writer that the prints will write to
var writeTo io.Writer = ioutil.Discard
var mutex sync.Mutex
func toggleOutput(c chan os.Signal) {
for {
// This line will block until the signal is received
<-c
// Whenver the signal is received toggle the target writer. If it's stdout swap it with ioutil.Discard and vice versa.
mutex.Lock()
if writeTo == os.Stdout {
writeTo = ioutil.Discard
} else {
writeTo = os.Stdout
}
mutex.Unlock()
}
}
func main() {
fmt.Printf("Process PID : %v\n", os.Getpid())
c := make(chan os.Signal, 1)
// Send to channel c whenver you receive a SIGUSR1 signal.
signal.Notify(c, syscall.SIGUSR1)
go toggleOutput(c)
// An infinte loops that prints and increments a counter
counter := 1
for {
mutex.Lock()
fmt.Fprintln(writeTo, counter)
mutex.Unlock()
counter++
time.Sleep(time.Second)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment