Commit 0aff707f authored by Mythri Alle's avatar Mythri Alle Committed by Commit Bot

Add ClearCache option for GeneratedCodeCache

Add an api for clearing the GeneratedCodeCache.

Bug: chromium:812168
Change-Id: Iba8fb3c81e8bed04573ed0cd4dabf4af31ea0c21
Reviewed-on: https://chromium-review.googlesource.com/1114974
Commit-Queue: Mythri Alle <mythria@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMaks Orlovich <morlovich@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577150}
parent 223cc79d
...@@ -58,50 +58,85 @@ std::string GetCacheKey(const GURL& resource_url, ...@@ -58,50 +58,85 @@ std::string GetCacheKey(const GURL& resource_url,
// being initialized. // being initialized.
class GeneratedCodeCache::PendingOperation { class GeneratedCodeCache::PendingOperation {
public: public:
PendingOperation(Operation op, static std::unique_ptr<PendingOperation> CreateWritePendingOp(
std::string key, std::string key,
scoped_refptr<net::IOBufferWithSize>); scoped_refptr<net::IOBufferWithSize>);
PendingOperation(Operation op, std::string key, const ReadDataCallback&); static std::unique_ptr<PendingOperation> CreateFetchPendingOp(
PendingOperation(Operation op, std::string key); std::string key,
const ReadDataCallback&);
static std::unique_ptr<PendingOperation> CreateDeletePendingOp(
std::string key);
static std::unique_ptr<PendingOperation> CreateClearCachePendingOp(
net::CompletionCallback callback);
~PendingOperation(); ~PendingOperation();
Operation operation() const { return op_; } Operation operation() const { return op_; }
const std::string& key() const { return key_; } const std::string& key() const { return key_; }
const scoped_refptr<net::IOBufferWithSize> data() const { return data_; } const scoped_refptr<net::IOBufferWithSize> data() const { return data_; }
const ReadDataCallback& callback() const { return callback_; } ReadDataCallback ReleaseReadCallback() { return std::move(read_callback_); }
net::CompletionCallback ReleaseCallback() { return std::move(callback_); }
private: private:
PendingOperation(Operation op,
std::string key,
scoped_refptr<net::IOBufferWithSize>,
const ReadDataCallback&,
net::CompletionCallback);
const Operation op_; const Operation op_;
const std::string key_; const std::string key_;
const scoped_refptr<net::IOBufferWithSize> data_; const scoped_refptr<net::IOBufferWithSize> data_;
const ReadDataCallback callback_; ReadDataCallback read_callback_;
net::CompletionCallback callback_;
}; };
GeneratedCodeCache::PendingOperation::PendingOperation( std::unique_ptr<GeneratedCodeCache::PendingOperation>
Operation op, GeneratedCodeCache::PendingOperation::CreateWritePendingOp(
std::string key, std::string key,
scoped_refptr<net::IOBufferWithSize> buffer) scoped_refptr<net::IOBufferWithSize> buffer) {
: op_(op), return base::WrapUnique(
key_(std::move(key)), new PendingOperation(Operation::kWrite, std::move(key), buffer,
data_(buffer), ReadDataCallback(), net::CompletionCallback()));
callback_(ReadDataCallback()) {} }
std::unique_ptr<GeneratedCodeCache::PendingOperation>
GeneratedCodeCache::PendingOperation::CreateFetchPendingOp(
std::string key,
const ReadDataCallback& read_callback) {
return base::WrapUnique(new PendingOperation(
Operation::kFetch, std::move(key), scoped_refptr<net::IOBufferWithSize>(),
read_callback, net::CompletionCallback()));
}
std::unique_ptr<GeneratedCodeCache::PendingOperation>
GeneratedCodeCache::PendingOperation::CreateDeletePendingOp(std::string key) {
return base::WrapUnique(
new PendingOperation(Operation::kDelete, std::move(key),
scoped_refptr<net::IOBufferWithSize>(),
ReadDataCallback(), net::CompletionCallback()));
}
std::unique_ptr<GeneratedCodeCache::PendingOperation>
GeneratedCodeCache::PendingOperation::CreateClearCachePendingOp(
net::CompletionCallback callback) {
return base::WrapUnique(
new PendingOperation(Operation::kClearCache, std::string(),
scoped_refptr<net::IOBufferWithSize>(),
ReadDataCallback(), std::move(callback)));
}
GeneratedCodeCache::PendingOperation::PendingOperation( GeneratedCodeCache::PendingOperation::PendingOperation(
Operation op, Operation op,
std::string key, std::string key,
const ReadDataCallback& callback) scoped_refptr<net::IOBufferWithSize> buffer,
: op_(op), const ReadDataCallback& read_callback,
key_(std::move(key)), net::CompletionCallback callback)
data_(scoped_refptr<net::IOBufferWithSize>()),
callback_(callback) {}
GeneratedCodeCache::PendingOperation::PendingOperation(Operation op,
std::string key)
: op_(op), : op_(op),
key_(std::move(key)), key_(std::move(key)),
data_(scoped_refptr<net::IOBufferWithSize>()), data_(buffer),
callback_(ReadDataCallback()) {} read_callback_(read_callback),
callback_(std::move(callback)) {}
GeneratedCodeCache::PendingOperation::~PendingOperation() = default; GeneratedCodeCache::PendingOperation::~PendingOperation() = default;
...@@ -131,8 +166,9 @@ void GeneratedCodeCache::WriteData( ...@@ -131,8 +166,9 @@ void GeneratedCodeCache::WriteData(
if (backend_state_ != kInitialized) { if (backend_state_ != kInitialized) {
// Insert it into the list of pending operations while the backend is // Insert it into the list of pending operations while the backend is
// still being opened. // still being opened.
pending_ops_.push_back(std::make_unique<PendingOperation>( pending_ops_.push_back(
Operation::kWrite, std::move(key), buffer)); GeneratedCodeCache::PendingOperation::CreateWritePendingOp(
std::move(key), buffer));
return; return;
} }
...@@ -159,8 +195,9 @@ void GeneratedCodeCache::FetchEntry(const GURL& url, ...@@ -159,8 +195,9 @@ void GeneratedCodeCache::FetchEntry(const GURL& url,
if (backend_state_ != kInitialized) { if (backend_state_ != kInitialized) {
// Insert it into the list of pending operations while the backend is // Insert it into the list of pending operations while the backend is
// still being opened. // still being opened.
pending_ops_.push_back(std::make_unique<PendingOperation>( pending_ops_.push_back(
Operation::kFetch, std::move(key), read_data_callback)); GeneratedCodeCache::PendingOperation::CreateFetchPendingOp(
std::move(key), read_data_callback));
return; return;
} }
...@@ -183,13 +220,29 @@ void GeneratedCodeCache::DeleteEntry(const GURL& url, ...@@ -183,13 +220,29 @@ void GeneratedCodeCache::DeleteEntry(const GURL& url,
// Insert it into the list of pending operations while the backend is // Insert it into the list of pending operations while the backend is
// still being opened. // still being opened.
pending_ops_.push_back( pending_ops_.push_back(
std::make_unique<PendingOperation>(Operation::kDelete, std::move(key))); GeneratedCodeCache::PendingOperation::CreateDeletePendingOp(
std::move(key)));
return; return;
} }
DeleteEntryImpl(key); DeleteEntryImpl(key);
} }
int GeneratedCodeCache::ClearCache(net::CompletionCallback callback) {
if (backend_state_ == kFailed) {
return net::ERR_FAILED;
}
if (backend_state_ != kInitialized) {
pending_ops_.push_back(
GeneratedCodeCache::PendingOperation::CreateClearCachePendingOp(
std::move(callback)));
return net::ERR_IO_PENDING;
}
return backend_->DoomAllEntries(std::move(callback));
}
GeneratedCodeCache::GeneratedCodeCache(const base::FilePath& path, GeneratedCodeCache::GeneratedCodeCache(const base::FilePath& path,
int max_size_bytes) int max_size_bytes)
: backend_state_(kUnInitialized), : backend_state_(kUnInitialized),
...@@ -242,7 +295,7 @@ void GeneratedCodeCache::IssuePendingOperations() { ...@@ -242,7 +295,7 @@ void GeneratedCodeCache::IssuePendingOperations() {
for (auto const& op : pending_ops_) { for (auto const& op : pending_ops_) {
switch (op->operation()) { switch (op->operation()) {
case kFetch: case kFetch:
FetchEntryImpl(op->key(), op->callback()); FetchEntryImpl(op->key(), op->ReleaseReadCallback());
break; break;
case kWrite: case kWrite:
WriteDataImpl(op->key(), op->data()); WriteDataImpl(op->key(), op->data());
...@@ -250,6 +303,9 @@ void GeneratedCodeCache::IssuePendingOperations() { ...@@ -250,6 +303,9 @@ void GeneratedCodeCache::IssuePendingOperations() {
case kDelete: case kDelete:
DeleteEntryImpl(op->key()); DeleteEntryImpl(op->key());
break; break;
case kClearCache:
DoPendingClearCache(op->ReleaseCallback());
break;
} }
} }
pending_ops_.clear(); pending_ops_.clear();
...@@ -380,4 +436,14 @@ void GeneratedCodeCache::DeleteEntryImpl(const std::string& key) { ...@@ -380,4 +436,14 @@ void GeneratedCodeCache::DeleteEntryImpl(const std::string& key) {
backend_->DoomEntry(key, net::LOWEST, net::CompletionOnceCallback()); backend_->DoomEntry(key, net::LOWEST, net::CompletionOnceCallback());
} }
void GeneratedCodeCache::DoPendingClearCache(
net::CompletionCallback user_callback) {
int result = backend_->DoomAllEntries(user_callback);
if (result != net::ERR_IO_PENDING) {
// Call the callback here because we returned ERR_IO_PENDING for initial
// request.
std::move(user_callback).Run(result);
}
}
} // namespace content } // namespace content
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h" #include "net/base/io_buffer.h"
#include "net/disk_cache/disk_cache.h" #include "net/disk_cache/disk_cache.h"
#include "url/origin.h" #include "url/origin.h"
...@@ -53,6 +54,13 @@ class CONTENT_EXPORT GeneratedCodeCache { ...@@ -53,6 +54,13 @@ class CONTENT_EXPORT GeneratedCodeCache {
// Delete the entry corresponding to <url, origin> // Delete the entry corresponding to <url, origin>
void DeleteEntry(const GURL& url, const url::Origin& origin); void DeleteEntry(const GURL& url, const url::Origin& origin);
// Clear code cache.
// TODO(mythria): Add support to conditional clearing based on URL
// and time range.
// TODO(mythria): Also check if we can avoid retruning an error code and
// always call the callback to be consistent with other methods.
int ClearCache(net::CompletionCallback callback);
const base::FilePath& path() const { return path_; } const base::FilePath& path() const { return path_; }
private: private:
...@@ -63,7 +71,7 @@ class CONTENT_EXPORT GeneratedCodeCache { ...@@ -63,7 +71,7 @@ class CONTENT_EXPORT GeneratedCodeCache {
enum BackendState { kUnInitialized, kInitializing, kInitialized, kFailed }; enum BackendState { kUnInitialized, kInitializing, kInitialized, kFailed };
// The operation requested. // The operation requested.
enum Operation { kFetch, kWrite, kDelete }; enum Operation { kFetch, kWrite, kDelete, kClearCache };
// Data streams corresponding to each entry. // Data streams corresponding to each entry.
enum { kDataIndex = 1 }; enum { kDataIndex = 1 };
...@@ -107,6 +115,9 @@ class CONTENT_EXPORT GeneratedCodeCache { ...@@ -107,6 +115,9 @@ class CONTENT_EXPORT GeneratedCodeCache {
// Delete entry from cache // Delete entry from cache
void DeleteEntryImpl(const std::string& key); void DeleteEntryImpl(const std::string& key);
void DoPendingClearCache(net::CompletionCallback callback);
void PendingClearComplete(net::CompletionCallback callback, int rv);
std::unique_ptr<disk_cache::Backend> backend_; std::unique_ptr<disk_cache::Backend> backend_;
BackendState backend_state_; BackendState backend_state_;
......
...@@ -73,6 +73,13 @@ class GeneratedCodeCacheTest : public testing::Test { ...@@ -73,6 +73,13 @@ class GeneratedCodeCacheTest : public testing::Test {
generated_code_cache_->FetchEntry(url, origin, callback); generated_code_cache_->FetchEntry(url, origin, callback);
} }
void ClearCache() {
generated_code_cache_->ClearCache(base::BindRepeating(
&GeneratedCodeCacheTest::ClearCacheComplete, base::Unretained(this)));
}
void ClearCacheComplete(int rv) {}
void FetchEntryCallback(scoped_refptr<net::IOBufferWithSize> buffer) { void FetchEntryCallback(scoped_refptr<net::IOBufferWithSize> buffer) {
if (!buffer || !buffer->data()) { if (!buffer || !buffer->data()) {
received_ = true; received_ = true;
...@@ -273,6 +280,7 @@ TEST_F(GeneratedCodeCacheTest, FetchFailsForInvalidOrigin) { ...@@ -273,6 +280,7 @@ TEST_F(GeneratedCodeCacheTest, FetchFailsForInvalidOrigin) {
FetchFromCache(url, origin); FetchFromCache(url, origin);
scoped_task_environment_.RunUntilIdle(); scoped_task_environment_.RunUntilIdle();
ASSERT_TRUE(received_); ASSERT_TRUE(received_);
ASSERT_TRUE(received_null_); ASSERT_TRUE(received_null_);
} }
...@@ -290,4 +298,18 @@ TEST_F(GeneratedCodeCacheTest, FetchFailsForInvalidURL) { ...@@ -290,4 +298,18 @@ TEST_F(GeneratedCodeCacheTest, FetchFailsForInvalidURL) {
ASSERT_TRUE(received_); ASSERT_TRUE(received_);
ASSERT_TRUE(received_null_); ASSERT_TRUE(received_null_);
} }
TEST_F(GeneratedCodeCacheTest, ClearCache) {
GURL url("http://example.com/script.js");
url::Origin origin = url::Origin::Create(GURL("http://example.com"));
InitializeCache();
ClearCache();
scoped_task_environment_.RunUntilIdle();
FetchFromCache(url, origin);
scoped_task_environment_.RunUntilIdle();
ASSERT_TRUE(received_);
ASSERT_TRUE(received_null_);
}
} // namespace content } // namespace content
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment