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.

90 lines
2.5 KiB

  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package graceful
  5. import (
  6. "context"
  7. "fmt"
  8. "time"
  9. )
  10. // Errors for context.Err()
  11. var (
  12. ErrShutdown = fmt.Errorf("Graceful Manager called Shutdown")
  13. ErrHammer = fmt.Errorf("Graceful Manager called Hammer")
  14. ErrTerminate = fmt.Errorf("Graceful Manager called Terminate")
  15. )
  16. // ChannelContext is a context that wraps a channel and error as a context
  17. type ChannelContext struct {
  18. done <-chan struct{}
  19. err error
  20. }
  21. // NewChannelContext creates a ChannelContext from a channel and error
  22. func NewChannelContext(done <-chan struct{}, err error) *ChannelContext {
  23. return &ChannelContext{
  24. done: done,
  25. err: err,
  26. }
  27. }
  28. // Deadline returns the time when work done on behalf of this context
  29. // should be canceled. There is no Deadline for a ChannelContext
  30. func (ctx *ChannelContext) Deadline() (deadline time.Time, ok bool) {
  31. return
  32. }
  33. // Done returns the channel provided at the creation of this context.
  34. // When closed, work done on behalf of this context should be canceled.
  35. func (ctx *ChannelContext) Done() <-chan struct{} {
  36. return ctx.done
  37. }
  38. // Err returns nil, if Done is not closed. If Done is closed,
  39. // Err returns the error provided at the creation of this context
  40. func (ctx *ChannelContext) Err() error {
  41. select {
  42. case <-ctx.done:
  43. return ctx.err
  44. default:
  45. return nil
  46. }
  47. }
  48. // Value returns nil for all calls as no values are or can be associated with this context
  49. func (ctx *ChannelContext) Value(key interface{}) interface{} {
  50. return nil
  51. }
  52. // ShutdownContext returns a context.Context that is Done at shutdown
  53. // Callers using this context should ensure that they are registered as a running server
  54. // in order that they are waited for.
  55. func (g *Manager) ShutdownContext() context.Context {
  56. return &ChannelContext{
  57. done: g.IsShutdown(),
  58. err: ErrShutdown,
  59. }
  60. }
  61. // HammerContext returns a context.Context that is Done at hammer
  62. // Callers using this context should ensure that they are registered as a running server
  63. // in order that they are waited for.
  64. func (g *Manager) HammerContext() context.Context {
  65. return &ChannelContext{
  66. done: g.IsHammer(),
  67. err: ErrHammer,
  68. }
  69. }
  70. // TerminateContext returns a context.Context that is Done at terminate
  71. // Callers using this context should ensure that they are registered as a terminating server
  72. // in order that they are waited for.
  73. func (g *Manager) TerminateContext() context.Context {
  74. return &ChannelContext{
  75. done: g.IsTerminate(),
  76. err: ErrTerminate,
  77. }
  78. }