server.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package server
  2. import (
  3. "errors"
  4. "fmt"
  5. "net"
  6. "net/http"
  7. "os"
  8. "os/signal"
  9. "sync"
  10. "syscall"
  11. "time"
  12. )
  13. type StoppableListener struct {
  14. *net.TCPListener //Wrapped listener
  15. stop chan int //Channel used only to indicate listener should shutdown
  16. }
  17. var quit chan os.Signal
  18. func New(l net.Listener) (*StoppableListener, error) {
  19. tcpL, ok := l.(*net.TCPListener)
  20. if !ok {
  21. return nil, errors.New("Cannot wrap listener")
  22. }
  23. retval := &StoppableListener{}
  24. retval.TCPListener = tcpL
  25. retval.stop = make(chan int)
  26. return retval, nil
  27. }
  28. var StoppedError = errors.New("Listener stopped")
  29. func (sl *StoppableListener) Accept() (net.Conn, error) {
  30. for {
  31. //Wait up to one second for a new connection
  32. sl.SetDeadline(time.Now().Add(time.Second))
  33. newConn, err := sl.TCPListener.Accept()
  34. //Check for the channel being closed
  35. select {
  36. case <-sl.stop:
  37. return nil, StoppedError
  38. default:
  39. //If the channel is still open, continue as normal
  40. }
  41. if err != nil {
  42. netErr, ok := err.(net.Error)
  43. //If this is a timeout, then continue to wait for
  44. //new connections
  45. if ok && netErr.Timeout() && netErr.Temporary() {
  46. continue
  47. }
  48. }
  49. return newConn, err
  50. }
  51. }
  52. func (sl *StoppableListener) Stop() {
  53. close(sl.stop)
  54. }
  55. func TerminateServer() {
  56. quit <- syscall.SIGTERM
  57. }
  58. func Start(port string, r http.Handler) {
  59. orgLst, err := net.Listen("tcp", ":"+port)
  60. if err != nil {
  61. panic(err)
  62. }
  63. sl, err := New(orgLst)
  64. if err != nil {
  65. panic(err)
  66. }
  67. server := http.Server{
  68. Handler: r,
  69. ReadTimeout: 5 * time.Second,
  70. WriteTimeout: 10 * time.Second,
  71. }
  72. server.SetKeepAlivesEnabled(false)
  73. quit = make(chan os.Signal)
  74. signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
  75. var wg sync.WaitGroup
  76. go func(wg sync.WaitGroup) {
  77. wg.Add(1)
  78. defer wg.Done()
  79. server.Serve(sl)
  80. }(wg)
  81. fmt.Printf("Started at port : " + port + "\n")
  82. select {
  83. case signal := <-quit:
  84. // wait for a few seconds
  85. time.Sleep(1000 * time.Millisecond)
  86. fmt.Printf("Got signal:%v\n", signal)
  87. }
  88. fmt.Printf("Stopping listener\n")
  89. sl.Stop()
  90. fmt.Printf("Waiting on server\n")
  91. wg.Wait()
  92. }