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,
// being initialized.
class GeneratedCodeCache::PendingOperation {
public:
PendingOperation(Operation op,
std::string key,
scoped_refptr<net::IOBufferWithSize>);
PendingOperation(Operation op, std::string key, const ReadDataCallback&);
PendingOperation(Operation op, std::string key);
static std::unique_ptr<PendingOperation> CreateWritePendingOp(
std::string key,
scoped_refptr<net::IOBufferWithSize>);
static std::unique_ptr<PendingOperation> CreateFetchPendingOp(
std::string key,
const ReadDataCallback&);
static std::unique_ptr<PendingOperation> CreateDeletePendingOp(
std::string key);
static std::unique_ptr<PendingOperation> CreateClearCachePendingOp(
net::CompletionCallback callback);
~PendingOperation();
Operation operation() const { return op_; }
const std::string& key() const { return key_; }
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:
PendingOperation(Operation op,
std::string key,
scoped_refptr<net::IOBufferWithSize>,
const ReadDataCallback&,
net::CompletionCallback);
const Operation op_;
const std::string key_;
const scoped_refptr<net::IOBufferWithSize> data_;
const ReadDataCallback callback_;
ReadDataCallback read_callback_;
net::CompletionCallback callback_;
};
GeneratedCodeCache::PendingOperation::PendingOperation(
Operation op,
std::unique_ptr<GeneratedCodeCache::PendingOperation>
GeneratedCodeCache::PendingOperation::CreateWritePendingOp(
std::string key,
scoped_refptr<net::IOBufferWithSize> buffer)
: op_(op),
key_(std::move(key)),
data_(buffer),
callback_(ReadDataCallback()) {}
scoped_refptr<net::IOBufferWithSize> buffer) {
return base::WrapUnique(
new PendingOperation(Operation::kWrite, std::move(key), buffer,
ReadDataCallback(), net::CompletionCallback()));
}
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(
Operation op,
std::string key,
const ReadDataCallback& callback)
: op_(op),
key_(std::move(key)),
data_(scoped_refptr<net::IOBufferWithSize>()),
callback_(callback) {}
GeneratedCodeCache::PendingOperation::PendingOperation(Operation op,
std::string key)
scoped_refptr<net::IOBufferWithSize> buffer,
const ReadDataCallback& read_callback,
net::CompletionCallback callback)
: op_(op),
key_(std::move(key)),
data_(scoped_refptr<net::IOBufferWithSize>()),
callback_(ReadDataCallback()) {}
data_(buffer),
read_callback_(read_callback),
callback_(std::move(callback)) {}
GeneratedCodeCache::PendingOperation::~PendingOperation() = default;
......@@ -131,8 +166,9 @@ void GeneratedCodeCache::WriteData(
if (backend_state_ != kInitialized) {
// Insert it into the list of pending operations while the backend is
// still being opened.
pending_ops_.push_back(std::make_unique<PendingOperation>(
Operation::kWrite, std::move(key), buffer));
pending_ops_.push_back(
GeneratedCodeCache::PendingOperation::CreateWritePendingOp(
std::move(key), buffer));
return;
}
......@@ -159,8 +195,9 @@ void GeneratedCodeCache::FetchEntry(const GURL& url,
if (backend_state_ != kInitialized) {
// Insert it into the list of pending operations while the backend is
// still being opened.
pending_ops_.push_back(std::make_unique<PendingOperation>(
Operation::kFetch, std::move(key), read_data_callback));
pending_ops_.push_back(
GeneratedCodeCache::PendingOperation::CreateFetchPendingOp(
std::move(key), read_data_callback));
return;
}
......@@ -183,13 +220,29 @@ void GeneratedCodeCache::DeleteEntry(const GURL& url,
// Insert it into the list of pending operations while the backend is
// still being opened.
pending_ops_.push_back(
std::make_unique<PendingOperation>(Operation::kDelete, std::move(key)));
GeneratedCodeCache::PendingOperation::CreateDeletePendingOp(
std::move(key)));
return;
}
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,
int max_size_bytes)
: backend_state_(kUnInitialized),
......@@ -242,7 +295,7 @@ void GeneratedCodeCache::IssuePendingOperations() {
for (auto const& op : pending_ops_) {
switch (op->operation()) {
case kFetch:
FetchEntryImpl(op->key(), op->callback());
FetchEntryImpl(op->key(), op->ReleaseReadCallback());
break;
case kWrite:
WriteDataImpl(op->key(), op->data());
......@@ -250,6 +303,9 @@ void GeneratedCodeCache::IssuePendingOperations() {
case kDelete:
DeleteEntryImpl(op->key());
break;
case kClearCache:
DoPendingClearCache(op->ReleaseCallback());
break;
}
}
pending_ops_.clear();
......@@ -380,4 +436,14 @@ void GeneratedCodeCache::DeleteEntryImpl(const std::string& key) {
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
......@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/disk_cache/disk_cache.h"
#include "url/origin.h"
......@@ -53,6 +54,13 @@ class CONTENT_EXPORT GeneratedCodeCache {
// Delete the entry corresponding to <url, 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_; }
private:
......@@ -63,7 +71,7 @@ class CONTENT_EXPORT GeneratedCodeCache {
enum BackendState { kUnInitialized, kInitializing, kInitialized, kFailed };
// The operation requested.
enum Operation { kFetch, kWrite, kDelete };
enum Operation { kFetch, kWrite, kDelete, kClearCache };
// Data streams corresponding to each entry.
enum { kDataIndex = 1 };
......@@ -107,6 +115,9 @@ class CONTENT_EXPORT GeneratedCodeCache {
// Delete entry from cache
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_;
BackendState backend_state_;
......
......@@ -73,6 +73,13 @@ class GeneratedCodeCacheTest : public testing::Test {
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) {
if (!buffer || !buffer->data()) {
received_ = true;
......@@ -273,6 +280,7 @@ TEST_F(GeneratedCodeCacheTest, FetchFailsForInvalidOrigin) {
FetchFromCache(url, origin);
scoped_task_environment_.RunUntilIdle();
ASSERT_TRUE(received_);
ASSERT_TRUE(received_null_);
}
......@@ -290,4 +298,18 @@ TEST_F(GeneratedCodeCacheTest, FetchFailsForInvalidURL) {
ASSERT_TRUE(received_);
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
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