Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(612)

Side by Side Diff: chromeos/printing/ppd_cache.cc

Issue 2487343006: Add in-memory caching to PpdCache available printers. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 #include "chromeos/printing/ppd_cache.h" 5 #include "chromeos/printing/ppd_cache.h"
6 6
7 #include <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 // something is exceptionally hosed. 84 // something is exceptionally hosed.
85 if (!base::DeleteFile(contents_path, false)) { 85 if (!base::DeleteFile(contents_path, false)) {
86 LOG(ERROR) << "Failed to cleanup partially-written file " 86 LOG(ERROR) << "Failed to cleanup partially-written file "
87 << contents_path.LossyDisplayName(); 87 << contents_path.LossyDisplayName();
88 return ret; 88 return ret;
89 } 89 }
90 } 90 }
91 return ret; 91 return ret;
92 } 92 }
93 93
94 base::Optional<PpdProvider::AvailablePrintersMap> FindAvailablePrinters() 94 const PpdProvider::AvailablePrintersMap* FindAvailablePrinters() override {
95 override { 95 if (available_printers_ != nullptr &&
96 base::Time::Now() - available_printers_timestamp_ <
97 options_.max_available_list_staleness) {
98 // Satisfy from memory cache.
99 return available_printers_.get();
100 }
96 std::string buf; 101 std::string buf;
97 if (!MaybeReadAvailablePrintersCache(&buf)) { 102 if (!MaybeReadAvailablePrintersCache(&buf)) {
98 return base::nullopt; 103 // Disk cache miss.
104 return nullptr;
99 } 105 }
100 auto dict = base::DictionaryValue::From(base::JSONReader::Read(buf)); 106 auto dict = base::DictionaryValue::From(base::JSONReader::Read(buf));
101 if (dict == nullptr) { 107 if (dict == nullptr) {
102 LOG(ERROR) << "Failed to deserialize available printers cache"; 108 LOG(ERROR) << "Failed to deserialize available printers cache";
103 return base::nullopt; 109 return nullptr;
104 } 110 }
105 PpdProvider::AvailablePrintersMap ret; 111 // Note if we got here, we've already set available_printers_timestamp_ to
112 // the mtime of the file we read from.
113 available_printers_.reset(new PpdProvider::AvailablePrintersMap);
106 const base::ListValue* models; 114 const base::ListValue* models;
107 std::string model; 115 std::string model;
108 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); 116 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
109 it.Advance()) { 117 it.Advance()) {
110 auto& out = ret[it.key()]; 118 auto& out = (*available_printers_)[it.key()];
111 if (!it.value().GetAsList(&models)) { 119 if (!it.value().GetAsList(&models)) {
112 LOG(ERROR) << "Skipping malformed printer make: " << it.key(); 120 LOG(ERROR) << "Skipping malformed printer make: " << it.key();
113 continue; 121 continue;
114 } 122 }
115 for (const auto& model_value : *models) { 123 for (const auto& model_value : *models) {
116 if (model_value->GetAsString(&model)) { 124 if (model_value->GetAsString(&model)) {
117 out.push_back(model); 125 out.push_back(model);
118 } else { 126 } else {
119 LOG(ERROR) << "Skipping malformed printer model in: " << it.key() 127 LOG(ERROR) << "Skipping malformed printer model in: " << it.key()
120 << ". Expected a string, found a " 128 << ". Expected a string, found a "
121 << base::Value::GetTypeName(model_value->GetType()); 129 << base::Value::GetTypeName(model_value->GetType());
122 } 130 }
123 } 131 }
124 } 132 }
125 return ret; 133 return available_printers_.get();
126 } 134 }
127 135
128 // Note we throw up our hands and fail (gracefully) to store if we encounter 136 // Note we throw up our hands and fail (gracefully) to store if we encounter
129 // non-unicode things in the strings of |available_printers|. Since these 137 // non-unicode things in the strings of |available_printers|. Since these
130 // strings come from a source we control, being less paranoid about these 138 // strings come from a source we control, being less paranoid about these
131 // values seems reasonable. 139 // values seems reasonable.
132 void StoreAvailablePrinters( 140 void StoreAvailablePrinters(std::unique_ptr<PpdProvider::AvailablePrintersMap>
133 const PpdProvider::AvailablePrintersMap& available_printers) override { 141 available_printers) override {
142 available_printers_ = std::move(available_printers);
143 available_printers_timestamp_ = base::Time::Now();
134 // Convert the map to Values, in preparation for jsonification. 144 // Convert the map to Values, in preparation for jsonification.
135 base::DictionaryValue top_level; 145 base::DictionaryValue top_level;
136 for (const auto& entry : available_printers) { 146 for (const auto& entry : *available_printers_) {
137 auto printers = base::MakeUnique<base::ListValue>(); 147 auto printers = base::MakeUnique<base::ListValue>();
138 printers->AppendStrings(entry.second); 148 printers->AppendStrings(entry.second);
139 top_level.Set(entry.first, std::move(printers)); 149 top_level.Set(entry.first, std::move(printers));
140 } 150 }
141 std::string contents; 151 std::string contents;
142 if (!base::JSONWriter::Write(top_level, &contents)) { 152 if (!base::JSONWriter::Write(top_level, &contents)) {
143 LOG(ERROR) << "Failed to generate JSON"; 153 LOG(ERROR) << "Failed to generate JSON";
144 return; 154 return;
145 } 155 }
146 if (contents.size() > options_.max_available_list_cached_size) { 156 if (contents.size() > options_.max_available_list_cached_size) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 (base::Time::Now() - info.last_modified <= 227 (base::Time::Now() - info.last_modified <=
218 options_.max_available_list_staleness)) { 228 options_.max_available_list_staleness)) {
219 // We have a file that's recent enough to use. 229 // We have a file that's recent enough to use.
220 if (!base::ReadFileToStringWithMaxSize( 230 if (!base::ReadFileToStringWithMaxSize(
221 available_printers_file_, buf, 231 available_printers_file_, buf,
222 options_.max_available_list_cached_size)) { 232 options_.max_available_list_cached_size)) {
223 LOG(ERROR) << "Failed to read printer cache"; 233 LOG(ERROR) << "Failed to read printer cache";
224 buf->clear(); 234 buf->clear();
225 return false; 235 return false;
226 } 236 }
237 available_printers_timestamp_ = info.last_modified;
227 return true; 238 return true;
228 } 239 }
240
229 // Either we don't have an openable file, or it's too old. 241 // Either we don't have an openable file, or it's too old.
230 // 242 //
231 // If we have an invalid file and it's not valid for reasons other than 243 // If we have an invalid file and it's not valid for reasons other than
232 // NOT_FOUND, that's unexpected and worth logging. Otherwise this is 244 // NOT_FOUND, that's unexpected and worth logging. Otherwise this is
233 // a normal cache miss. 245 // a normal cache miss.
234 if (!cache_file.IsValid() && 246 if (!cache_file.IsValid() &&
235 cache_file.error_details() != base::File::FILE_ERROR_NOT_FOUND) { 247 cache_file.error_details() != base::File::FILE_ERROR_NOT_FOUND) {
236 LOG(ERROR) << "Unexpected result when attempting to open printer cache: " 248 LOG(ERROR) << "Unexpected result when attempting to open printer cache: "
237 << base::File::ErrorToString(cache_file.error_details()); 249 << base::File::ErrorToString(cache_file.error_details());
238 } 250 }
239 return false; 251 return false;
240 } 252 }
241 253
254 // In-memory copy of the available printers map, null if we don't have an
255 // in-memory copy yet. Filled in the first time the map is fetched (whether
256 // from disk or server), and remains for the life of the PpdCache.
skau 2016/11/10 20:46:37 This isn't strictly true. It's reset when the cac
Carlson 2016/11/11 01:39:27 You're right, I changed this after I wrote the com
257 std::unique_ptr<PpdProvider::AvailablePrintersMap> available_printers_;
258 // Timestamp for the in-memory copy of the cache. (The on-disk version uses
259 // the file mtime).
260 base::Time available_printers_timestamp_;
261
242 const base::FilePath cache_base_dir_; 262 const base::FilePath cache_base_dir_;
243 const base::FilePath available_printers_file_; 263 const base::FilePath available_printers_file_;
244 const PpdCache::Options options_; 264 const PpdCache::Options options_;
245 265
246 DISALLOW_COPY_AND_ASSIGN(PpdCacheImpl); 266 DISALLOW_COPY_AND_ASSIGN(PpdCacheImpl);
247 }; 267 };
248 268
249 } // namespace 269 } // namespace
250 270
251 // static 271 // static
252 std::unique_ptr<PpdCache> PpdCache::Create(const base::FilePath& cache_base_dir, 272 std::unique_ptr<PpdCache> PpdCache::Create(const base::FilePath& cache_base_dir,
253 const PpdCache::Options& options) { 273 const PpdCache::Options& options) {
254 return base::MakeUnique<PpdCacheImpl>(cache_base_dir, options); 274 return base::MakeUnique<PpdCacheImpl>(cache_base_dir, options);
255 } 275 }
256 276
257 } // namespace printing 277 } // namespace printing
258 } // namespace chromeos 278 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698