OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package prod | 5 package prod |
6 | 6 |
7 import ( | 7 import ( |
8 "time" | 8 "time" |
9 | 9 |
10 "github.com/luci/gae/service/info" | 10 "github.com/luci/gae/service/info" |
11 "golang.org/x/net/context" | 11 "golang.org/x/net/context" |
12 "google.golang.org/appengine" | 12 "google.golang.org/appengine" |
13 "google.golang.org/appengine/datastore" | 13 "google.golang.org/appengine/datastore" |
14 ) | 14 ) |
15 | 15 |
16 type key int | |
17 | |
18 var probeCacheKey key | |
19 | |
20 // useGI adds a gae.GlobalInfo implementation to context, accessible | 16 // useGI adds a gae.GlobalInfo implementation to context, accessible |
21 // by gae.GetGI(c) | 17 // by gae.GetGI(c) |
22 func useGI(c context.Context) context.Context { | 18 func useGI(usrCtx context.Context) context.Context { |
23 » probeCache := getProbeCache(c) | 19 » probeCache := getProbeCache(usrCtx) |
24 if probeCache == nil { | 20 if probeCache == nil { |
25 » » c = withProbeCache(c, probe(c)) | 21 » » usrCtx = withProbeCache(usrCtx, probe(AEContext(usrCtx))) |
26 } | 22 } |
27 | 23 |
28 » return info.SetFactory(c, func(ci context.Context) info.Interface { | 24 » return info.SetFactory(usrCtx, func(ci context.Context) info.Interface { |
29 » » return giImpl{ci} | 25 » » return giImpl{ci, AEContext(ci)} |
30 }) | 26 }) |
31 } | 27 } |
32 | 28 |
33 type giImpl struct{ context.Context } | 29 type giImpl struct { |
| 30 » usrCtx context.Context |
| 31 » aeCtx context.Context |
| 32 } |
34 | 33 |
35 func (g giImpl) AccessToken(scopes ...string) (token string, expiry time.Time, e
rr error) { | 34 func (g giImpl) AccessToken(scopes ...string) (token string, expiry time.Time, e
rr error) { |
36 » return appengine.AccessToken(g, scopes...) | 35 » return appengine.AccessToken(g.aeCtx, scopes...) |
37 } | 36 } |
38 func (g giImpl) AppID() string { | 37 func (g giImpl) AppID() string { |
39 » return appengine.AppID(g) | 38 » return appengine.AppID(g.aeCtx) |
40 } | 39 } |
41 func (g giImpl) FullyQualifiedAppID() string { | 40 func (g giImpl) FullyQualifiedAppID() string { |
42 » return getProbeCache(g).fqaid | 41 » return getProbeCache(g.usrCtx).fqaid |
43 } | 42 } |
44 func (g giImpl) GetNamespace() string { | 43 func (g giImpl) GetNamespace() string { |
45 » return getProbeCache(g).namespace | 44 » return getProbeCache(g.usrCtx).namespace |
46 } | 45 } |
47 func (g giImpl) Datacenter() string { | 46 func (g giImpl) Datacenter() string { |
48 » return appengine.Datacenter(g) | 47 » return appengine.Datacenter(g.aeCtx) |
49 } | 48 } |
50 func (g giImpl) DefaultVersionHostname() string { | 49 func (g giImpl) DefaultVersionHostname() string { |
51 » return appengine.DefaultVersionHostname(g) | 50 » return appengine.DefaultVersionHostname(g.aeCtx) |
52 } | 51 } |
53 func (g giImpl) InstanceID() string { | 52 func (g giImpl) InstanceID() string { |
54 return appengine.InstanceID() | 53 return appengine.InstanceID() |
55 } | 54 } |
56 func (g giImpl) IsDevAppServer() bool { | 55 func (g giImpl) IsDevAppServer() bool { |
57 return appengine.IsDevAppServer() | 56 return appengine.IsDevAppServer() |
58 } | 57 } |
59 func (g giImpl) IsOverQuota(err error) bool { | 58 func (g giImpl) IsOverQuota(err error) bool { |
60 return appengine.IsOverQuota(err) | 59 return appengine.IsOverQuota(err) |
61 } | 60 } |
62 func (g giImpl) IsTimeoutError(err error) bool { | 61 func (g giImpl) IsTimeoutError(err error) bool { |
63 return appengine.IsTimeoutError(err) | 62 return appengine.IsTimeoutError(err) |
64 } | 63 } |
65 func (g giImpl) ModuleHostname(module, version, instance string) (string, error)
{ | 64 func (g giImpl) ModuleHostname(module, version, instance string) (string, error)
{ |
66 » return appengine.ModuleHostname(g, module, version, instance) | 65 » return appengine.ModuleHostname(g.aeCtx, module, version, instance) |
67 } | 66 } |
68 func (g giImpl) ModuleName() (name string) { | 67 func (g giImpl) ModuleName() (name string) { |
69 » return appengine.ModuleName(g) | 68 » return appengine.ModuleName(g.aeCtx) |
70 } | 69 } |
71 func (g giImpl) Namespace(namespace string) (context.Context, error) { | 70 func (g giImpl) Namespace(namespace string) (context.Context, error) { |
72 » c, err := appengine.Namespace(g, namespace) | 71 » aeCtx, err := appengine.Namespace(g.aeCtx, namespace) |
73 if err != nil { | 72 if err != nil { |
74 » » return c, err | 73 » » return g.usrCtx, err |
75 } | 74 } |
76 » pc := *getProbeCache(g) | 75 » usrCtx := context.WithValue(g.usrCtx, prodContextKey, aeCtx) |
| 76 » pc := *getProbeCache(usrCtx) |
77 pc.namespace = namespace | 77 pc.namespace = namespace |
78 » return withProbeCache(c, &pc), nil | 78 » return withProbeCache(usrCtx, &pc), nil |
79 } | 79 } |
80 func (g giImpl) PublicCertificates() ([]info.Certificate, error) { | 80 func (g giImpl) PublicCertificates() ([]info.Certificate, error) { |
81 » certs, err := appengine.PublicCertificates(g) | 81 » certs, err := appengine.PublicCertificates(g.aeCtx) |
82 if err != nil { | 82 if err != nil { |
83 return nil, err | 83 return nil, err |
84 } | 84 } |
85 ret := make([]info.Certificate, len(certs)) | 85 ret := make([]info.Certificate, len(certs)) |
86 for i, c := range certs { | 86 for i, c := range certs { |
87 ret[i] = info.Certificate(c) | 87 ret[i] = info.Certificate(c) |
88 } | 88 } |
89 return ret, nil | 89 return ret, nil |
90 } | 90 } |
91 func (g giImpl) RequestID() string { | 91 func (g giImpl) RequestID() string { |
92 » return appengine.RequestID(g) | 92 » return appengine.RequestID(g.aeCtx) |
93 } | 93 } |
94 func (g giImpl) ServerSoftware() string { | 94 func (g giImpl) ServerSoftware() string { |
95 return appengine.ServerSoftware() | 95 return appengine.ServerSoftware() |
96 } | 96 } |
97 func (g giImpl) ServiceAccount() (string, error) { | 97 func (g giImpl) ServiceAccount() (string, error) { |
98 » return appengine.ServiceAccount(g) | 98 » return appengine.ServiceAccount(g.aeCtx) |
99 } | 99 } |
100 func (g giImpl) SignBytes(bytes []byte) (keyName string, signature []byte, err e
rror) { | 100 func (g giImpl) SignBytes(bytes []byte) (keyName string, signature []byte, err e
rror) { |
101 » return appengine.SignBytes(g, bytes) | 101 » return appengine.SignBytes(g.aeCtx, bytes) |
102 } | 102 } |
103 func (g giImpl) VersionID() string { | 103 func (g giImpl) VersionID() string { |
104 » return appengine.VersionID(g) | 104 » return appengine.VersionID(g.aeCtx) |
105 } | 105 } |
106 | 106 |
107 type infoProbeCache struct { | 107 type infoProbeCache struct { |
108 namespace string | 108 namespace string |
109 fqaid string | 109 fqaid string |
110 } | 110 } |
111 | 111 |
112 func probe(c context.Context) *infoProbeCache { | 112 func probe(aeCtx context.Context) *infoProbeCache { |
113 » probeKey := datastore.NewKey(c, "Kind", "id", 0, nil) | 113 » probeKey := datastore.NewKey(aeCtx, "Kind", "id", 0, nil) |
114 return &infoProbeCache{ | 114 return &infoProbeCache{ |
115 namespace: probeKey.Namespace(), | 115 namespace: probeKey.Namespace(), |
116 fqaid: probeKey.AppID(), | 116 fqaid: probeKey.AppID(), |
117 } | 117 } |
118 } | 118 } |
119 | 119 |
120 func getProbeCache(c context.Context) *infoProbeCache { | 120 func getProbeCache(c context.Context) *infoProbeCache { |
121 if pc, ok := c.Value(probeCacheKey).(*infoProbeCache); ok { | 121 if pc, ok := c.Value(probeCacheKey).(*infoProbeCache); ok { |
122 return pc | 122 return pc |
123 } | 123 } |
124 return nil | 124 return nil |
125 } | 125 } |
126 | 126 |
127 func withProbeCache(c context.Context, pc *infoProbeCache) context.Context { | 127 func withProbeCache(c context.Context, pc *infoProbeCache) context.Context { |
128 return context.WithValue(c, probeCacheKey, pc) | 128 return context.WithValue(c, probeCacheKey, pc) |
129 } | 129 } |
OLD | NEW |