svc_common.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // +build !windows
  2. package svc
  3. import (
  4. "context"
  5. "os"
  6. "syscall"
  7. )
  8. // Run runs your Service.
  9. //
  10. // Run will block until one of the signals specified in sig is received or a provided context is done.
  11. // If sig is empty syscall.SIGINT and syscall.SIGTERM are used by default.
  12. func Run(service Service, sig ...os.Signal) error {
  13. env := environment{}
  14. if err := service.Init(env); err != nil {
  15. return err
  16. }
  17. if err := service.Start(); err != nil {
  18. return err
  19. }
  20. if len(sig) == 0 {
  21. sig = []os.Signal{syscall.SIGINT, syscall.SIGTERM}
  22. }
  23. signalChan := make(chan os.Signal, 1)
  24. signalNotify(signalChan, sig...)
  25. var ctx context.Context
  26. if s, ok := service.(Context); ok {
  27. ctx = s.Context()
  28. } else {
  29. ctx = context.Background()
  30. }
  31. for {
  32. select {
  33. case s := <-signalChan:
  34. if h, ok := service.(Handler); ok {
  35. if err := h.Handle(s); err == ErrStop {
  36. goto stop
  37. }
  38. } else {
  39. // this maintains backwards compatibility for Services that do not implement Handle()
  40. goto stop
  41. }
  42. case <-ctx.Done():
  43. goto stop
  44. }
  45. }
  46. stop:
  47. return service.Stop()
  48. }
  49. type environment struct{}
  50. func (environment) IsWindowsService() bool {
  51. return false
  52. }