Created
January 16, 2019 06:41
-
-
Save DigDeeply/6c23ec60705cc284f54f2c5cfbf2c4ca to your computer and use it in GitHub Desktop.
a graceful http demo.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"fmt" | |
"io" | |
"log" | |
"net" | |
"net/http" | |
"os" | |
"os/exec" | |
"os/signal" | |
"syscall" | |
"time" | |
) | |
var ln net.Listener | |
var srv http.Server | |
func main() { | |
fmt.Println("start") | |
fmt.Printf("%v\n", os.Environ()) | |
http.HandleFunc("/hello", getPidHandle) | |
Addr := ":8080" | |
var err error | |
if os.Getenv("_GRACEFUL") == "true" { | |
fd := os.NewFile(3, "") | |
ln, err = net.FileListener(fd) | |
if err != nil { | |
log.Fatal(err) | |
} | |
} else { | |
ln, err = net.Listen("tcp", Addr) | |
if err != nil { | |
log.Fatal(err) | |
} | |
} | |
go srv.Serve(ln) | |
sig := make(chan os.Signal, 1) | |
signal.Notify(sig, syscall.SIGUSR2) | |
s := <-sig | |
for { | |
switch s { | |
case syscall.SIGUSR2: | |
fmt.Printf("%v\n", s) | |
reload() | |
stop() | |
return | |
} | |
} | |
fmt.Println("Exiting") | |
} | |
func getPidHandle(w http.ResponseWriter, r *http.Request) { | |
io.WriteString(w, "Hello, world!\n"+fmt.Sprintf("%d\n", os.Getpid())) | |
} | |
func reload() { | |
tcp, ok := ln.(*net.TCPListener) | |
if !ok { | |
log.Fatal("tcp listener tcp not ok") | |
} | |
f, err := tcp.File() | |
if err != nil { | |
log.Fatal(err) | |
} | |
cmd := exec.Command(os.Args[0]) | |
os.Setenv("_GRACEFUL", "true") | |
cmd.ExtraFiles = []*os.File{f} | |
err = cmd.Start() | |
if err != nil { | |
log.Fatal(err) | |
} | |
} | |
func stop() { | |
// shutdown old service | |
ctx, cancleHandle := context.WithTimeout(context.Background(), 5*time.Second) | |
defer cancleHandle() | |
err := srv.Shutdown(ctx) | |
if err != nil { | |
log.Fatal(err) | |
} | |
time.Sleep(6 * time.Second) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment