context.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package context
  2. import (
  3. "sync"
  4. "github.com/docker/distribution/uuid"
  5. "golang.org/x/net/context"
  6. )
  7. // Context is a copy of Context from the golang.org/x/net/context package.
  8. type Context interface {
  9. context.Context
  10. }
  11. // instanceContext is a context that provides only an instance id. It is
  12. // provided as the main background context.
  13. type instanceContext struct {
  14. Context
  15. id string // id of context, logged as "instance.id"
  16. once sync.Once // once protect generation of the id
  17. }
  18. func (ic *instanceContext) Value(key interface{}) interface{} {
  19. if key == "instance.id" {
  20. ic.once.Do(func() {
  21. // We want to lazy initialize the UUID such that we don't
  22. // call a random generator from the package initialization
  23. // code. For various reasons random could not be available
  24. // https://github.com/docker/distribution/issues/782
  25. ic.id = uuid.Generate().String()
  26. })
  27. return ic.id
  28. }
  29. return ic.Context.Value(key)
  30. }
  31. var background = &instanceContext{
  32. Context: context.Background(),
  33. }
  34. // Background returns a non-nil, empty Context. The background context
  35. // provides a single key, "instance.id" that is globally unique to the
  36. // process.
  37. func Background() Context {
  38. return background
  39. }
  40. // WithValue returns a copy of parent in which the value associated with key is
  41. // val. Use context Values only for request-scoped data that transits processes
  42. // and APIs, not for passing optional parameters to functions.
  43. func WithValue(parent Context, key, val interface{}) Context {
  44. return context.WithValue(parent, key, val)
  45. }
  46. // stringMapContext is a simple context implementation that checks a map for a
  47. // key, falling back to a parent if not present.
  48. type stringMapContext struct {
  49. context.Context
  50. m map[string]interface{}
  51. }
  52. // WithValues returns a context that proxies lookups through a map. Only
  53. // supports string keys.
  54. func WithValues(ctx context.Context, m map[string]interface{}) context.Context {
  55. mo := make(map[string]interface{}, len(m)) // make our own copy.
  56. for k, v := range m {
  57. mo[k] = v
  58. }
  59. return stringMapContext{
  60. Context: ctx,
  61. m: mo,
  62. }
  63. }
  64. func (smc stringMapContext) Value(key interface{}) interface{} {
  65. if ks, ok := key.(string); ok {
  66. if v, ok := smc.m[ks]; ok {
  67. return v
  68. }
  69. }
  70. return smc.Context.Value(key)
  71. }