Bug 1305780 - P1. Implement the update fail scheme for v4. r=gcp

MozReview-Commit-ID: LeVpVIUdmjc

--HG--
extra : rebase_source : bfc189b5a3f1cfc17bd269bcb7e7edad826769a3
This commit is contained in:
DimiL 2016-10-19 12:52:05 +08:00
Родитель de12f55089
Коммит 48ddedb04e
4 изменённых файлов: 68 добавлений и 43 удалений

Просмотреть файл

@ -19,6 +19,7 @@
#include "mozilla/Logging.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/Base64.h"
#include "mozilla/Unused.h"
// MOZ_LOG=UrlClassifierDbService:5
extern mozilla::LazyLogModule gUrlClassifierDbServiceLog;
@ -349,22 +350,36 @@ Classifier::Reset()
}
void
Classifier::ResetTables(const nsTArray<nsCString>& aTables)
Classifier::ResetTables(ClearType aType, const nsTArray<nsCString>& aTables)
{
// Clear lookup cache
MarkSpoiled(aTables);
for (uint32_t i = 0; i < aTables.Length(); i++) {
LOG(("Resetting table: %s", aTables[i].get()));
// Spoil this table by marking it as no known freshness
mTableFreshness.Remove(aTables[i]);
LookupCache *cache = GetLookupCache(aTables[i]);
if (cache) {
// Remove any cached Completes for this table if clear type is Clear_Cache
if (aType == Clear_Cache) {
cache->ClearCache();
} else {
cache->ClearAll();
}
}
}
// Clear on-disk database
DeleteTables(aTables);
// Clear on-disk database if clear type is Clear_All
if (aType == Clear_All) {
DeleteTables(mRootStoreDirectory, aTables);
RegenActiveTables();
RegenActiveTables();
}
}
void
Classifier::DeleteTables(const nsTArray<nsCString>& aTables)
Classifier::DeleteTables(nsIFile* aDirectory, const nsTArray<nsCString>& aTables)
{
nsCOMPtr<nsISimpleEnumerator> entries;
nsresult rv = mRootStoreDirectory->GetDirectoryEntries(getter_AddRefs(entries));
nsresult rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
NS_ENSURE_SUCCESS_VOID(rv);
bool hasMore;
@ -376,6 +391,16 @@ Classifier::DeleteTables(const nsTArray<nsCString>& aTables)
nsCOMPtr<nsIFile> file = do_QueryInterface(supports);
NS_ENSURE_TRUE_VOID(file);
// If |file| is a directory, recurse to find its entries as well.
bool isDirectory;
if (NS_FAILED(file->IsDirectory(&isDirectory))) {
continue;
}
if (isDirectory) {
DeleteTables(file, aTables);
continue;
}
nsCString leafName;
rv = file->GetNativeLeafName(leafName);
NS_ENSURE_SUCCESS_VOID(rv);
@ -391,6 +416,20 @@ Classifier::DeleteTables(const nsTArray<nsCString>& aTables)
NS_ENSURE_SUCCESS_VOID(rv);
}
void
Classifier::AbortUpdateAndReset(const nsCString& aTable)
{
LOG(("Abort updating table %s.", aTable.get()));
// ResetTables will clear both in-memory & on-disk data.
ResetTables(Clear_All, nsTArray<nsCString> { aTable });
// Remove the backup and delete directory since we are aborting
// from an update.
Unused << RemoveBackupTables();
Unused << CleanToDelete();
}
void
Classifier::TableRequest(nsACString& aResult)
{
@ -550,7 +589,7 @@ Classifier::ApplyUpdates(nsTArray<TableUpdate*>* aUpdates)
if (NS_FAILED(rv)) {
if (rv != NS_ERROR_OUT_OF_MEMORY) {
Reset();
AbortUpdateAndReset(updateTable);
}
return rv;
}
@ -602,22 +641,6 @@ Classifier::ApplyFullHashes(nsTArray<TableUpdate*>* aUpdates)
return NS_OK;
}
nsresult
Classifier::MarkSpoiled(const nsTArray<nsCString>& aTables)
{
for (uint32_t i = 0; i < aTables.Length(); i++) {
LOG(("Spoiling table: %s", aTables[i].get()));
// Spoil this table by marking it as no known freshness
mTableFreshness.Remove(aTables[i]);
// Remove any cached Completes for this table
LookupCache *cache = GetLookupCache(aTables[i]);
if (cache) {
cache->ClearCache();
}
}
return NS_OK;
}
int64_t
Classifier::GetLastUpdateTime(const nsACString& aTableName)
{

Просмотреть файл

@ -32,9 +32,15 @@ public:
void Reset();
/**
* Clear In-Memory & On-Disk data for specific tables
* Clear data for specific tables.
* If ClearType is Clear_Cache, this function will only clear cache in lookup
* cache, otherwise, it will clear data in lookup cache and data stored on disk.
*/
void ResetTables(const nsTArray<nsCString>& aTables);
enum ClearType {
Clear_Cache,
Clear_All,
};
void ResetTables(ClearType aType, const nsTArray<nsCString>& aTables);
/**
* Get the list of active tables and their chunks in a format
@ -66,11 +72,6 @@ public:
*/
nsresult ApplyFullHashes(nsTArray<TableUpdate*>* aUpdates);
/**
* Failed update. Spoil the entries so we don't block hosts
* unnecessarily
*/
nsresult MarkSpoiled(const nsTArray<nsCString>& aTables);
void SetLastUpdateTime(const nsACString& aTableName, uint64_t updateTime);
int64_t GetLastUpdateTime(const nsACString& aTableName);
nsresult CacheCompletions(const CacheResultArray& aResults);
@ -101,7 +102,8 @@ public:
private:
void DropStores();
void DeleteTables(const nsTArray<nsCString>& aTables);
void DeleteTables(nsIFile* aDirectory, const nsTArray<nsCString>& aTables);
void AbortUpdateAndReset(const nsCString& aTable);
nsresult CreateStoreDirectory();
nsresult SetupPathNames();

Просмотреть файл

@ -126,6 +126,8 @@ public:
virtual nsresult Has(const Completion& aCompletion,
bool* aHas, bool* aComplete) = 0;
virtual void ClearAll();
template<typename T>
static T* Cast(LookupCache* aThat) {
return ((aThat && T::VER == aThat->Ver()) ? reinterpret_cast<T*>(aThat) : nullptr);
@ -142,8 +144,6 @@ private:
virtual int Ver() const = 0;
protected:
virtual void ClearAll();
bool mPrimed;
nsCString mTableName;
nsCOMPtr<nsIFile> mRootStoreDirectory;

Просмотреть файл

@ -566,7 +566,7 @@ nsUrlClassifierDBServiceWorker::FinishStream()
if (NS_SUCCEEDED(mUpdateStatus)) {
if (mProtocolParser->ResetRequested()) {
mClassifier->ResetTables(mUpdateTables);
mClassifier->ResetTables(Classifier::Clear_All, mUpdateTables);
}
}
@ -598,7 +598,7 @@ nsUrlClassifierDBServiceWorker::FinishUpdate()
LOG(("Treating NS_ERROR_NOT_IMPLEMENTED a successful update "
"but still mark it spoiled."));
mUpdateObserver->UpdateSuccess(0);
mClassifier->MarkSpoiled(mUpdateTables);
mClassifier->ResetTables(Classifier::Clear_Cache, mUpdateTables);
} else {
if (LOG_ENABLED()) {
nsAutoCString errorName;
@ -608,10 +608,10 @@ nsUrlClassifierDBServiceWorker::FinishUpdate()
mUpdateObserver->UpdateError(mUpdateStatus);
/*
* mark the tables as spoiled, we don't want to block hosts
* longer than normal because our update failed
* mark the tables as spoiled(clear cache in LookupCache), we don't want to
* block hosts longer than normal because our update failed
*/
mClassifier->MarkSpoiled(mUpdateTables);
mClassifier->ResetTables(Classifier::Clear_Cache, mUpdateTables);
}
mUpdateObserver = nullptr;
@ -685,10 +685,10 @@ nsUrlClassifierDBServiceWorker::CancelUpdate()
mUpdateObserver->UpdateError(mUpdateStatus);
/*
* mark the tables as spoiled, we don't want to block hosts
* longer than normal because our update failed
* mark the tables as spoiled(clear cache in LookupCache), we don't want to
* block hosts longer than normal because our update failed
*/
mClassifier->MarkSpoiled(mUpdateTables);
mClassifier->ResetTables(Classifier::Clear_Cache, mUpdateTables);
ResetStream();
ResetUpdate();