OLD | NEW |
---|---|
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be 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" |
(...skipping 22 matching lines...) Expand all Loading... | |
33 | 33 |
34 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) { |
35 return appengine.AccessToken(g.aeCtx, scopes...) | 35 return appengine.AccessToken(g.aeCtx, scopes...) |
36 } | 36 } |
37 func (g giImpl) AppID() string { | 37 func (g giImpl) AppID() string { |
38 return appengine.AppID(g.aeCtx) | 38 return appengine.AppID(g.aeCtx) |
39 } | 39 } |
40 func (g giImpl) FullyQualifiedAppID() string { | 40 func (g giImpl) FullyQualifiedAppID() string { |
41 return getProbeCache(g.usrCtx).fqaid | 41 return getProbeCache(g.usrCtx).fqaid |
42 } | 42 } |
43 func (g giImpl) GetNamespace() (string, bool) { | 43 func (g giImpl) GetNamespace() string { |
44 » pc := getProbeCache(g.usrCtx) | 44 » return getProbeCache(g.usrCtx).namespace |
45 » if ns := pc.namespace; ns != nil { | |
46 » » return *ns, true | |
47 » } | |
48 » return "", false | |
49 } | 45 } |
50 func (g giImpl) Datacenter() string { | 46 func (g giImpl) Datacenter() string { |
51 return appengine.Datacenter(g.aeCtx) | 47 return appengine.Datacenter(g.aeCtx) |
52 } | 48 } |
53 func (g giImpl) DefaultVersionHostname() string { | 49 func (g giImpl) DefaultVersionHostname() string { |
54 return appengine.DefaultVersionHostname(g.aeCtx) | 50 return appengine.DefaultVersionHostname(g.aeCtx) |
55 } | 51 } |
56 func (g giImpl) InstanceID() string { | 52 func (g giImpl) InstanceID() string { |
57 return appengine.InstanceID() | 53 return appengine.InstanceID() |
58 } | 54 } |
59 func (g giImpl) IsDevAppServer() bool { | 55 func (g giImpl) IsDevAppServer() bool { |
60 return appengine.IsDevAppServer() | 56 return appengine.IsDevAppServer() |
61 } | 57 } |
62 func (g giImpl) IsOverQuota(err error) bool { | 58 func (g giImpl) IsOverQuota(err error) bool { |
63 return appengine.IsOverQuota(err) | 59 return appengine.IsOverQuota(err) |
64 } | 60 } |
65 func (g giImpl) IsTimeoutError(err error) bool { | 61 func (g giImpl) IsTimeoutError(err error) bool { |
66 return appengine.IsTimeoutError(err) | 62 return appengine.IsTimeoutError(err) |
67 } | 63 } |
68 func (g giImpl) ModuleHostname(module, version, instance string) (string, error) { | 64 func (g giImpl) ModuleHostname(module, version, instance string) (string, error) { |
69 return appengine.ModuleHostname(g.aeCtx, module, version, instance) | 65 return appengine.ModuleHostname(g.aeCtx, module, version, instance) |
70 } | 66 } |
71 func (g giImpl) ModuleName() (name string) { | 67 func (g giImpl) ModuleName() (name string) { |
72 return appengine.ModuleName(g.aeCtx) | 68 return appengine.ModuleName(g.aeCtx) |
73 } | 69 } |
74 func (g giImpl) Namespace(namespace string) (context.Context, error) { | 70 func (g giImpl) Namespace(namespace string) (context.Context, error) { |
75 » aeCtx, err := appengine.Namespace(g.aeCtx, namespace) | 71 » c := g.usrCtx |
dnj
2016/09/01 15:25:40
Only interesting change here. As I mentioned earli
| |
72 | |
73 » pc := *getProbeCache(c) | |
74 » if pc.namespace == namespace { | |
75 » » // Already using this namespace. | |
76 » » return c, nil | |
77 » } | |
78 » pc.namespace = namespace | |
79 | |
80 » // Apply the namespace to our retained GAE Contexts. | |
81 » var err error | |
82 » ps := getProdState(c) | |
83 | |
84 » // Apply to current GAE Context. | |
85 » if ps.ctx, err = appengine.Namespace(ps.ctx, namespace); err != nil { | |
86 » » return c, err | |
87 » } | |
88 | |
89 » // Apply to non-transactional Context. Since the previous one applied | |
90 » // successfully, this must succeed. | |
91 » ps.noTxnCtx, err = appengine.Namespace(ps.noTxnCtx, namespace) | |
76 if err != nil { | 92 if err != nil { |
77 » » return g.usrCtx, err | 93 » » panic(err) |
78 } | 94 } |
79 » usrCtx := context.WithValue(g.usrCtx, prodContextKey, aeCtx) | 95 |
80 » pc := *getProbeCache(usrCtx) | 96 » // Update our user Context with the new namespace-imbued objects. |
81 » pc.namespace = &namespace | 97 » c = withProbeCache(c, &pc) |
82 » return withProbeCache(usrCtx, &pc), nil | 98 » c = withProdState(c, ps) |
99 » return c, nil | |
83 } | 100 } |
84 func (g giImpl) PublicCertificates() ([]info.Certificate, error) { | 101 func (g giImpl) PublicCertificates() ([]info.Certificate, error) { |
85 certs, err := appengine.PublicCertificates(g.aeCtx) | 102 certs, err := appengine.PublicCertificates(g.aeCtx) |
86 if err != nil { | 103 if err != nil { |
87 return nil, err | 104 return nil, err |
88 } | 105 } |
89 ret := make([]info.Certificate, len(certs)) | 106 ret := make([]info.Certificate, len(certs)) |
90 for i, c := range certs { | 107 for i, c := range certs { |
91 ret[i] = info.Certificate(c) | 108 ret[i] = info.Certificate(c) |
92 } | 109 } |
(...skipping 13 matching lines...) Expand all Loading... | |
106 } | 123 } |
107 return appengine.ServiceAccount(g.aeCtx) | 124 return appengine.ServiceAccount(g.aeCtx) |
108 } | 125 } |
109 func (g giImpl) SignBytes(bytes []byte) (keyName string, signature []byte, err e rror) { | 126 func (g giImpl) SignBytes(bytes []byte) (keyName string, signature []byte, err e rror) { |
110 return appengine.SignBytes(g.aeCtx, bytes) | 127 return appengine.SignBytes(g.aeCtx, bytes) |
111 } | 128 } |
112 func (g giImpl) VersionID() string { | 129 func (g giImpl) VersionID() string { |
113 return appengine.VersionID(g.aeCtx) | 130 return appengine.VersionID(g.aeCtx) |
114 } | 131 } |
115 | 132 |
116 func (g giImpl) Testable() info.Testable { | 133 func (g giImpl) GetTestable() info.Testable { return nil } |
117 » return nil | |
118 } | |
119 | 134 |
120 type infoProbeCache struct { | 135 type infoProbeCache struct { |
121 » namespace *string | 136 » namespace string |
122 fqaid string | 137 fqaid string |
123 } | 138 } |
124 | 139 |
125 func probe(aeCtx context.Context) *infoProbeCache { | 140 func probe(aeCtx context.Context) *infoProbeCache { |
126 probeKey := datastore.NewKey(aeCtx, "Kind", "id", 0, nil) | 141 probeKey := datastore.NewKey(aeCtx, "Kind", "id", 0, nil) |
127 namespace := probeKey.Namespace() | |
128 ipb := infoProbeCache{ | 142 ipb := infoProbeCache{ |
129 » » fqaid: probeKey.AppID(), | 143 » » fqaid: probeKey.AppID(), |
130 » } | 144 » » namespace: probeKey.Namespace(), |
131 » if namespace != "" { | |
132 » » ipb.namespace = &namespace | |
133 } | 145 } |
134 return &ipb | 146 return &ipb |
135 } | 147 } |
136 | 148 |
137 func getProbeCache(c context.Context) *infoProbeCache { | 149 func getProbeCache(c context.Context) *infoProbeCache { |
138 if pc, ok := c.Value(probeCacheKey).(*infoProbeCache); ok { | 150 if pc, ok := c.Value(probeCacheKey).(*infoProbeCache); ok { |
139 return pc | 151 return pc |
140 } | 152 } |
141 return nil | 153 return nil |
142 } | 154 } |
143 | 155 |
144 func withProbeCache(c context.Context, pc *infoProbeCache) context.Context { | 156 func withProbeCache(c context.Context, pc *infoProbeCache) context.Context { |
145 return context.WithValue(c, probeCacheKey, pc) | 157 return context.WithValue(c, probeCacheKey, pc) |
146 } | 158 } |
OLD | NEW |