| 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 """Provides info about projects (service tenants).""" | 5 """Provides info about projects (service tenants).""" |
| 6 | 6 |
| 7 import logging | 7 import logging |
| 8 | 8 |
| 9 from google.appengine.api import memcache |
| 9 from google.appengine.ext import ndb | 10 from google.appengine.ext import ndb |
| 10 from google.appengine.ext.ndb import msgprop | 11 from google.appengine.ext.ndb import msgprop |
| 11 from protorpc import messages | 12 from protorpc import messages |
| 12 | 13 |
| 13 from components.config.proto import project_config_pb2 | 14 from components.config.proto import project_config_pb2 |
| 14 from components.config.proto import service_config_pb2 | 15 from components.config.proto import service_config_pb2 |
| 15 | 16 |
| 16 import common | 17 import common |
| 17 import storage | 18 import storage |
| 18 | 19 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 } | 90 } |
| 90 | 91 |
| 91 | 92 |
| 92 def get_metadata(project_ids): | 93 def get_metadata(project_ids): |
| 93 """Returns a mapping {project_id: metadata}. | 94 """Returns a mapping {project_id: metadata}. |
| 94 | 95 |
| 95 If a project does not exist, the metadata is None. | 96 If a project does not exist, the metadata is None. |
| 96 | 97 |
| 97 The project metadata stored in project.cfg files in each project. | 98 The project metadata stored in project.cfg files in each project. |
| 98 """ | 99 """ |
| 99 return _get_project_configs( | 100 cache_ns = 'projects.get_metadata' |
| 100 project_ids, common.PROJECT_METADATA_FILENAME, | 101 cache_map = memcache.get_multi(project_ids, namespace=cache_ns) |
| 101 project_config_pb2.ProjectCfg) | 102 result = {} |
| 103 missing = [] |
| 104 for pid in project_ids: |
| 105 if pid in cache_map: |
| 106 # cache hit |
| 107 binary = cache_map[pid] |
| 108 if binary is None: |
| 109 # project does not exist |
| 110 result[pid] = None |
| 111 else: |
| 112 cfg = project_config_pb2.ProjectCfg() |
| 113 cfg.ParseFromString(binary) |
| 114 result[pid] = cfg |
| 115 else: |
| 116 # cache miss |
| 117 missing.append(pid) |
| 118 |
| 119 if missing: |
| 120 fetched = _get_project_configs( |
| 121 missing, common.PROJECT_METADATA_FILENAME, |
| 122 project_config_pb2.ProjectCfg) |
| 123 result.update(fetched) # at this point result must have all project ids |
| 124 # Cache metadata for 10 min. In practice, it never changes. |
| 125 cache_map = { |
| 126 pid: cfg.SerializeToString() if cfg else None |
| 127 for pid, cfg in fetched.iteritems() |
| 128 } |
| 129 memcache.set_multi(cache_map, namespace=cache_ns, time=60 * 10) |
| 130 |
| 131 return result |
| 102 | 132 |
| 103 | 133 |
| 104 def get_refs(project_ids): | 134 def get_refs(project_ids): |
| 105 """Returns a mapping {project_id: list of refs} | 135 """Returns a mapping {project_id: list of refs} |
| 106 | 136 |
| 107 The ref list is None if a project does not exist. | 137 The ref list is None if a project does not exist. |
| 108 | 138 |
| 109 The list of refs stored in refs.cfg of a project. | 139 The list of refs stored in refs.cfg of a project. |
| 110 """ | 140 """ |
| 111 cfgs = _get_project_configs( | 141 cfgs = _get_project_configs( |
| (...skipping 27 matching lines...) Expand all Loading... |
| 139 # TODO(nodir): optimize | 169 # TODO(nodir): optimize |
| 140 assert isinstance(project_ids, list) | 170 assert isinstance(project_ids, list) |
| 141 if not project_ids: | 171 if not project_ids: |
| 142 return project_ids | 172 return project_ids |
| 143 assert all(pid for pid in project_ids) | 173 assert all(pid for pid in project_ids) |
| 144 all_project_ids = set(p.id for p in get_projects()) | 174 all_project_ids = set(p.id for p in get_projects()) |
| 145 return [ | 175 return [ |
| 146 pid for pid in project_ids | 176 pid for pid in project_ids |
| 147 if pid in all_project_ids | 177 if pid in all_project_ids |
| 148 ] | 178 ] |
| OLD | NEW |