Browse Source

Change graceful to opt-in to signal handling

Previously, a set of standard signals would be handled automatically via
an init() function, however that made the package difficult to use in
packages in which an HTTP server would only be spawned some of the times
(perhaps keyed on an environment variable or flag). Now, signals must be
registered manually.

By default, the top-level "goji" package automatically registers
signals with graceful, so this will result in no behavior changes for
most people.

Fixes #35.
Carl Jackson 12 years ago
parent
commit
e3228e8322
3 changed files with 12 additions and 14 deletions
  1. +1
    -0
      goji.go
  2. +1
    -4
      graceful/einhorn.go
  3. +10
    -10
      graceful/signal.go

+ 1
- 0
goji.go View File

@ -59,6 +59,7 @@ func Serve() {
listener := bind.Default() listener := bind.Default()
log.Println("Starting Goji on", listener.Addr()) log.Println("Starting Goji on", listener.Addr())
graceful.HandleSignals()
bind.Ready() bind.Ready()
err := graceful.Serve(listener, http.DefaultServeMux) err := graceful.Serve(listener, http.DefaultServeMux)


+ 1
- 4
graceful/einhorn.go View File

@ -3,7 +3,6 @@
package graceful package graceful
import ( import (
"log"
"os" "os"
"strconv" "strconv"
"syscall" "syscall"
@ -18,7 +17,5 @@ func init() {
if err != nil || mpid != os.Getppid() { if err != nil || mpid != os.Getppid() {
return return
} }
log.Print("graceful: Einhorn detected, adding SIGUSR2 handler")
AddSignal(syscall.SIGUSR2)
stdSignals = append(stdSignals, syscall.SIGUSR2)
} }

+ 10
- 10
graceful/signal.go View File

@ -24,28 +24,28 @@ var hookLock sync.Mutex
var prehooks = make([]func(), 0) var prehooks = make([]func(), 0)
var posthooks = make([]func(), 0) var posthooks = make([]func(), 0)
var stdSignals = []os.Signal{os.Interrupt}
var sigchan = make(chan os.Signal, 1) var sigchan = make(chan os.Signal, 1)
func init() { func init() {
AddSignal(os.Interrupt)
go waitForSignal() go waitForSignal()
} }
// HandleSignals installs signal handlers for a set of standard signals. By
// default, this set only includes keyboard interrupts, however when the package
// detects that it is running under Einhorn, a SIGUSR2 handler is installed as
// well.
func HandleSignals() {
AddSignal(stdSignals...)
}
// AddSignal adds the given signal to the set of signals that trigger a graceful // AddSignal adds the given signal to the set of signals that trigger a graceful
// shutdown. Note that for convenience the default interrupt (SIGINT) handler is
// installed at package load time, and unless you call ResetSignals() will be
// listened for in addition to any signals you provide by calling this function.
// shutdown.
func AddSignal(sig ...os.Signal) { func AddSignal(sig ...os.Signal) {
signal.Notify(sigchan, sig...) signal.Notify(sigchan, sig...)
} }
// ResetSignals resets the list of signals that trigger a graceful shutdown. // ResetSignals resets the list of signals that trigger a graceful shutdown.
// Useful if, for instance, you don't want to use the default interrupt (SIGINT)
// handler. Since we necessarily install the SIGINT handler before you have a
// chance to call ResetSignals(), there will be a brief window during which the
// set of signals this package listens for will not be as you intend. Therefore,
// if you intend on using this function, we encourage you to call it as soon as
// possible.
func ResetSignals() { func ResetSignals() {
signal.Stop(sigchan) signal.Stop(sigchan)
} }


Loading…
Cancel
Save