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

Side by Side Diff: components/offline_pages/offline_page_metadata_store_sql.cc

Issue 2497703002: [Offline pages] Resetting offline page metadata store to handle LOAD/INIT failures (Closed)
Patch Set: Addressing comments form self-review 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 "components/offline_pages/offline_page_metadata_store_sql.h" 5 #include "components/offline_pages/offline_page_metadata_store_sql.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h" 9 #include "base/files/file_util.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 const std::vector<OfflinePageItem>& result) { 260 const std::vector<OfflinePageItem>& result) {
261 // TODO(fgorski): Switch to SQL specific UMA metrics. 261 // TODO(fgorski): Switch to SQL specific UMA metrics.
262 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus", status, 262 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus", status,
263 OfflinePageMetadataStore::LOAD_STATUS_COUNT); 263 OfflinePageMetadataStore::LOAD_STATUS_COUNT);
264 if (status == OfflinePageMetadataStore::LOAD_SUCCEEDED) { 264 if (status == OfflinePageMetadataStore::LOAD_SUCCEEDED) {
265 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount", 265 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount",
266 static_cast<int32_t>(result.size())); 266 static_cast<int32_t>(result.size()));
267 } else { 267 } else {
268 DVLOG(1) << "Offline pages database loading failed: " << status; 268 DVLOG(1) << "Offline pages database loading failed: " << status;
269 } 269 }
270 runner->PostTask(FROM_HERE, base::Bind(callback, status, result)); 270 runner->PostTask(FROM_HERE, base::Bind(callback, result));
271 } 271 }
272 272
273 void OpenConnectionSync(sql::Connection* db, 273 void OpenConnectionSync(sql::Connection* db,
274 scoped_refptr<base::SingleThreadTaskRunner> runner, 274 scoped_refptr<base::SingleThreadTaskRunner> runner,
275 const base::FilePath& path, 275 const base::FilePath& path,
276 const base::Callback<void(StoreState)>& callback) { 276 const base::Callback<void(StoreState)>& callback) {
277 StoreState state = 277 StoreState state =
278 InitDatabase(db, path) ? StoreState::LOADED : StoreState::FAILED_LOADING; 278 InitDatabase(db, path) ? StoreState::LOADED : StoreState::FAILED_LOADING;
279 runner->PostTask(FROM_HERE, base::Bind(callback, state)); 279 runner->PostTask(FROM_HERE, base::Bind(callback, state));
280 } 280 }
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 } 427 }
428 428
429 runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result))); 429 runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result)));
430 } 430 }
431 431
432 void ResetSync(sql::Connection* db, 432 void ResetSync(sql::Connection* db,
433 const base::FilePath& db_file_path, 433 const base::FilePath& db_file_path,
434 scoped_refptr<base::SingleThreadTaskRunner> runner, 434 scoped_refptr<base::SingleThreadTaskRunner> runner,
435 const base::Callback<void(StoreState)>& callback) { 435 const base::Callback<void(StoreState)>& callback) {
436 // This method deletes the content of the whole store and reinitializes it. 436 // This method deletes the content of the whole store and reinitializes it.
437 bool success = db->Raze(); 437 bool success = true;
438 db->Close(); 438 if (db) {
439 success = db->Raze();
440 db->Close();
441 }
442 success = base::DeleteFile(db_file_path, true /*recursive*/) && success;
439 StoreState state; 443 StoreState state;
440 if (success) { 444 if (success) {
441 state = InitDatabase(db, db_file_path) ? StoreState::LOADED 445 state = InitDatabase(db, db_file_path) ? StoreState::LOADED
jianli 2016/11/15 21:48:38 I think we should first get back to main thread up
fgorski 2016/11/15 23:14:12 Done.
442 : StoreState::FAILED_LOADING; 446 : StoreState::FAILED_LOADING;
443 } else { 447 } else {
444 state = StoreState::FAILED_RESET; 448 state = StoreState::FAILED_RESET;
445 } 449 }
446 runner->PostTask(FROM_HERE, base::Bind(callback, state)); 450 runner->PostTask(FROM_HERE, base::Bind(callback, state));
447 } 451 }
448 452
449 } // anonymous namespace 453 } // anonymous namespace
450 454
451 OfflinePageMetadataStoreSQL::OfflinePageMetadataStoreSQL( 455 OfflinePageMetadataStoreSQL::OfflinePageMetadataStoreSQL(
452 scoped_refptr<base::SequencedTaskRunner> background_task_runner, 456 scoped_refptr<base::SequencedTaskRunner> background_task_runner,
453 const base::FilePath& path) 457 const base::FilePath& path)
454 : background_task_runner_(std::move(background_task_runner)), 458 : background_task_runner_(std::move(background_task_runner)),
455 db_file_path_(path.AppendASCII("OfflinePages.db")), 459 db_file_path_(path.AppendASCII("OfflinePages.db")),
456 state_(StoreState::NOT_LOADED), 460 state_(StoreState::NOT_LOADED),
457 weak_ptr_factory_(this) { 461 weak_ptr_factory_(this) {
458 OpenConnection();
459 } 462 }
460 463
461 OfflinePageMetadataStoreSQL::~OfflinePageMetadataStoreSQL() { 464 OfflinePageMetadataStoreSQL::~OfflinePageMetadataStoreSQL() {
462 if (db_.get() && 465 if (db_.get() &&
463 !background_task_runner_->DeleteSoon(FROM_HERE, db_.release())) { 466 !background_task_runner_->DeleteSoon(FROM_HERE, db_.release())) {
464 DLOG(WARNING) << "SQL database will not be deleted."; 467 DLOG(WARNING) << "SQL database will not be deleted.";
465 } 468 }
466 } 469 }
467 470
471 void OfflinePageMetadataStoreSQL::Initialize(
472 const InitializeCallback& callback) {
473 DCHECK(!db_);
474 db_.reset(new sql::Connection());
475 background_task_runner_->PostTask(
476 FROM_HERE,
477 base::Bind(&OpenConnectionSync, db_.get(),
478 base::ThreadTaskRunnerHandle::Get(), db_file_path_,
479 base::Bind(&OfflinePageMetadataStoreSQL::OnOpenConnectionDone,
480 weak_ptr_factory_.GetWeakPtr(), callback)));
481 }
482
468 void OfflinePageMetadataStoreSQL::GetOfflinePages( 483 void OfflinePageMetadataStoreSQL::GetOfflinePages(
469 const LoadCallback& callback) { 484 const LoadCallback& callback) {
470 if (!CheckDb(base::Bind( 485 if (!CheckDb(base::Bind(callback, std::vector<OfflinePageItem>()))) {
471 callback, STORE_INIT_FAILED, std::vector<OfflinePageItem>()))) {
472 return; 486 return;
473 } 487 }
474 488
475 background_task_runner_->PostTask( 489 background_task_runner_->PostTask(
476 FROM_HERE, base::Bind(&GetOfflinePagesSync, db_.get(), 490 FROM_HERE, base::Bind(&GetOfflinePagesSync, db_.get(),
477 base::ThreadTaskRunnerHandle::Get(), callback)); 491 base::ThreadTaskRunnerHandle::Get(), callback));
478 } 492 }
479 493
480 void OfflinePageMetadataStoreSQL::AddOfflinePage( 494 void OfflinePageMetadataStoreSQL::AddOfflinePage(
481 const OfflinePageItem& offline_page, 495 const OfflinePageItem& offline_page,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 base::ThreadTaskRunnerHandle::Get(), state(), offline_ids, 530 base::ThreadTaskRunnerHandle::Get(), state(), offline_ids,
517 ItemActionStatus::NOT_FOUND /* will be ignored */, callback); 531 ItemActionStatus::NOT_FOUND /* will be ignored */, callback);
518 return; 532 return;
519 } 533 }
520 534
521 background_task_runner_->PostTask( 535 background_task_runner_->PostTask(
522 FROM_HERE, base::Bind(&RemoveOfflinePagesSync, offline_ids, db_.get(), 536 FROM_HERE, base::Bind(&RemoveOfflinePagesSync, offline_ids, db_.get(),
523 base::ThreadTaskRunnerHandle::Get(), callback)); 537 base::ThreadTaskRunnerHandle::Get(), callback));
524 } 538 }
525 539
526 void OfflinePageMetadataStoreSQL::Reset(const ResetCallback& callback) { 540 void OfflinePageMetadataStoreSQL::Reset(const InitializeCallback& callback) {
527 if (!CheckDb(base::Bind(callback, false)))
528 return;
529
530 background_task_runner_->PostTask( 541 background_task_runner_->PostTask(
531 FROM_HERE, 542 FROM_HERE,
532 base::Bind(&ResetSync, db_.get(), db_file_path_, 543 base::Bind(&ResetSync, db_.get(), db_file_path_,
533 base::ThreadTaskRunnerHandle::Get(), 544 base::ThreadTaskRunnerHandle::Get(),
534 base::Bind(&OfflinePageMetadataStoreSQL::OnResetDone, 545 base::Bind(&OfflinePageMetadataStoreSQL::OnOpenConnectionDone,
535 weak_ptr_factory_.GetWeakPtr(), callback))); 546 weak_ptr_factory_.GetWeakPtr(), callback)));
536 } 547 }
537 548
538 StoreState OfflinePageMetadataStoreSQL::state() const { 549 StoreState OfflinePageMetadataStoreSQL::state() const {
539 return state_; 550 return state_;
540 } 551 }
541 552
542 void OfflinePageMetadataStoreSQL::SetStateForTesting(StoreState state, 553 void OfflinePageMetadataStoreSQL::SetStateForTesting(StoreState state,
543 bool reset_db) { 554 bool reset_db) {
544 state_ = state; 555 state_ = state;
545 if (reset_db) 556 if (reset_db)
546 db_.reset(nullptr); 557 db_.reset(nullptr);
547 } 558 }
548 559
549 void OfflinePageMetadataStoreSQL::OpenConnection() { 560 void OfflinePageMetadataStoreSQL::OnOpenConnectionDone(
550 DCHECK(!db_); 561 const InitializeCallback& callback,
551 db_.reset(new sql::Connection()); 562 StoreState state) {
552 background_task_runner_->PostTask(
553 FROM_HERE,
554 base::Bind(&OpenConnectionSync, db_.get(),
555 base::ThreadTaskRunnerHandle::Get(), db_file_path_,
556 base::Bind(&OfflinePageMetadataStoreSQL::OnOpenConnectionDone,
557 weak_ptr_factory_.GetWeakPtr())));
558 }
559
560 void OfflinePageMetadataStoreSQL::OnOpenConnectionDone(StoreState state) {
561 DCHECK(db_.get()); 563 DCHECK(db_.get());
562 564
563 state_ = state; 565 state_ = state;
564 566
565 // Unfortunately we were not able to open DB connection. 567 // Unfortunately we were not able to open DB connection.
566 if (state != StoreState::LOADED) 568 if (state != StoreState::LOADED)
567 db_.reset(); 569 db_.reset(nullptr);
568 570
569 // TODO(fgorski): This might be a place to start store recovery. Alternatively 571 callback.Run(state);
570 // that can be attempted in the OfflinePageModel.
571 }
572
573 void OfflinePageMetadataStoreSQL::OnResetDone(const ResetCallback& callback,
574 StoreState state) {
575 OnOpenConnectionDone(state);
576 callback.Run(state == StoreState::LOADED);
577 } 572 }
578 573
579 bool OfflinePageMetadataStoreSQL::CheckDb(const base::Closure& callback) { 574 bool OfflinePageMetadataStoreSQL::CheckDb(const base::Closure& callback) {
580 if (!db_.get() || state_ != StoreState::LOADED) { 575 if (!db_.get() || state_ != StoreState::LOADED) {
581 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); 576 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
582 return false; 577 return false;
583 } 578 }
584 return true; 579 return true;
585 } 580 }
586 581
587 } // namespace offline_pages 582 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698