You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server_hooks.go 1.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package graceful
  4. import (
  5. "os"
  6. "runtime"
  7. "code.gitea.io/gitea/modules/log"
  8. )
  9. // awaitShutdown waits for the shutdown signal from the Manager
  10. func (srv *Server) awaitShutdown() {
  11. select {
  12. case <-GetManager().IsShutdown():
  13. // Shutdown
  14. srv.doShutdown()
  15. case <-GetManager().IsHammer():
  16. // Hammer
  17. srv.doShutdown()
  18. srv.doHammer()
  19. }
  20. <-GetManager().IsHammer()
  21. srv.doHammer()
  22. }
  23. // shutdown closes the listener so that no new connections are accepted
  24. // and starts a goroutine that will hammer (stop all running requests) the server
  25. // after setting.GracefulHammerTime.
  26. func (srv *Server) doShutdown() {
  27. // only shutdown if we're running.
  28. if srv.getState() != stateRunning {
  29. return
  30. }
  31. srv.setState(stateShuttingDown)
  32. if srv.OnShutdown != nil {
  33. srv.OnShutdown()
  34. }
  35. err := srv.listener.Close()
  36. if err != nil {
  37. log.Error("PID: %d Listener.Close() error: %v", os.Getpid(), err)
  38. } else {
  39. log.Info("PID: %d Listener (%s) closed.", os.Getpid(), srv.listener.Addr())
  40. }
  41. }
  42. func (srv *Server) doHammer() {
  43. defer func() {
  44. // We call srv.wg.Done() until it panics.
  45. // This happens if we call Done() when the WaitGroup counter is already at 0
  46. // So if it panics -> we're done, Serve() will return and the
  47. // parent will goroutine will exit.
  48. if r := recover(); r != nil {
  49. log.Error("WaitGroup at 0: Error: %v", r)
  50. }
  51. }()
  52. if srv.getState() != stateShuttingDown {
  53. return
  54. }
  55. log.Warn("Forcefully shutting down parent")
  56. for {
  57. if srv.getState() == stateTerminate {
  58. break
  59. }
  60. srv.wg.Done()
  61. // Give other goroutines a chance to finish before we forcibly stop them.
  62. runtime.Gosched()
  63. }
  64. }