Chromium Code Reviews| 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 |