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

Side by Side Diff: components/dom_distiller/core/task_tracker.cc

Issue 189833002: Add a DistilledContentStore (and an in-memory impl) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/dom_distiller/core/task_tracker.h" 5 #include "components/dom_distiller/core/task_tracker.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "components/dom_distiller/core/distilled_content_store.h"
9 #include "components/dom_distiller/core/proto/distilled_article.pb.h" 10 #include "components/dom_distiller/core/proto/distilled_article.pb.h"
10 #include "components/dom_distiller/core/proto/distilled_page.pb.h" 11 #include "components/dom_distiller/core/proto/distilled_page.pb.h"
11 12
12 namespace dom_distiller { 13 namespace dom_distiller {
13 14
14 ViewerHandle::ViewerHandle(CancelCallback callback) 15 ViewerHandle::ViewerHandle(CancelCallback callback)
15 : cancel_callback_(callback) {} 16 : cancel_callback_(callback) {}
16 17
17 ViewerHandle::~ViewerHandle() { 18 ViewerHandle::~ViewerHandle() {
18 if (!cancel_callback_.is_null()) { 19 if (!cancel_callback_.is_null()) {
19 cancel_callback_.Run(); 20 cancel_callback_.Run();
20 } 21 }
21 } 22 }
22 23
23 TaskTracker::TaskTracker(const ArticleEntry& entry, CancelCallback callback) 24 TaskTracker::TaskTracker(const ArticleEntry& entry,
25 CancelCallback callback,
26 DistilledContentStore* content_store)
24 : cancel_callback_(callback), 27 : cancel_callback_(callback),
28 content_store_(content_store),
29 blob_fetcher_running_(false),
25 entry_(entry), 30 entry_(entry),
26 distilled_article_(), 31 distilled_article_(),
27 content_ready_(false), 32 content_ready_(false),
28 destruction_allowed_(true), 33 destruction_allowed_(true),
29 weak_ptr_factory_(this) {} 34 weak_ptr_factory_(this) {}
30 35
31 TaskTracker::~TaskTracker() { 36 TaskTracker::~TaskTracker() {
32 DCHECK(destruction_allowed_); 37 DCHECK(destruction_allowed_);
33 DCHECK(viewers_.empty()); 38 DCHECK(viewers_.empty());
34 } 39 }
35 40
36 void TaskTracker::StartDistiller(DistillerFactory* factory) { 41 void TaskTracker::StartDistiller(DistillerFactory* factory) {
37 if (distiller_) { 42 if (distiller_) {
38 return; 43 return;
39 } 44 }
40 if (entry_.pages_size() == 0) { 45 if (entry_.pages_size() == 0) {
41 return; 46 return;
42 } 47 }
43
44 GURL url(entry_.pages(0).url()); 48 GURL url(entry_.pages(0).url());
45 DCHECK(url.is_valid()); 49 DCHECK(url.is_valid());
46 50
47 distiller_ = factory->CreateDistiller(); 51 distiller_ = factory->CreateDistiller();
48 distiller_->DistillPage(url, 52 distiller_->DistillPage(url,
49 base::Bind(&TaskTracker::OnDistillerFinished, 53 base::Bind(&TaskTracker::OnDistillerFinished,
50 weak_ptr_factory_.GetWeakPtr()), 54 weak_ptr_factory_.GetWeakPtr()),
51 base::Bind(&TaskTracker::OnArticleDistillationUpdated, 55 base::Bind(&TaskTracker::OnArticleDistillationUpdated,
52 weak_ptr_factory_.GetWeakPtr())); 56 weak_ptr_factory_.GetWeakPtr()));
53 } 57 }
54 58
55 void TaskTracker::StartBlobFetcher() { 59 void TaskTracker::StartBlobFetcher() {
56 // TODO(cjhopman): There needs to be some local storage for the distilled 60 if (content_store_) {
57 // blob. When that happens, this should start some task to fetch the blob for 61 content_store_->LoadContent(entry_,
58 // |entry_| and asynchronously notify |this| when it is done. 62 base::Bind(&TaskTracker::OnBlobFetched,
63 weak_ptr_factory_.GetWeakPtr()));
64 }
59 } 65 }
60 66
61 void TaskTracker::AddSaveCallback(const SaveCallback& callback) { 67 void TaskTracker::AddSaveCallback(const SaveCallback& callback) {
62 DCHECK(!callback.is_null()); 68 DCHECK(!callback.is_null());
63 save_callbacks_.push_back(callback); 69 save_callbacks_.push_back(callback);
64 if (content_ready_) { 70 if (content_ready_) {
65 // Distillation for this task has already completed, and so it can be 71 // Distillation for this task has already completed, and so it can be
66 // immediately saved. 72 // immediately saved.
67 ScheduleSaveCallbacks(true); 73 ScheduleSaveCallbacks(true);
68 } 74 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 MaybeCancel(); 110 MaybeCancel();
105 } 111 }
106 } 112 }
107 113
108 void TaskTracker::MaybeCancel() { 114 void TaskTracker::MaybeCancel() {
109 if (!save_callbacks_.empty() || !viewers_.empty()) { 115 if (!save_callbacks_.empty() || !viewers_.empty()) {
110 // There's still work to be done. 116 // There's still work to be done.
111 return; 117 return;
112 } 118 }
113 119
120 CancelPendingSources();
121
114 base::AutoReset<bool> dont_delete_this_in_callback(&destruction_allowed_, 122 base::AutoReset<bool> dont_delete_this_in_callback(&destruction_allowed_,
115 false); 123 false);
116 cancel_callback_.Run(this); 124 cancel_callback_.Run(this);
117 } 125 }
118 126
119 void TaskTracker::CancelSaveCallbacks() { ScheduleSaveCallbacks(false); } 127 void TaskTracker::CancelSaveCallbacks() { ScheduleSaveCallbacks(false); }
120 128
121 void TaskTracker::ScheduleSaveCallbacks(bool distillation_succeeded) { 129 void TaskTracker::ScheduleSaveCallbacks(bool distillation_succeeded) {
122 base::MessageLoop::current()->PostTask( 130 base::MessageLoop::current()->PostTask(
123 FROM_HERE, 131 FROM_HERE,
124 base::Bind(&TaskTracker::DoSaveCallbacks, 132 base::Bind(&TaskTracker::DoSaveCallbacks,
125 weak_ptr_factory_.GetWeakPtr(), 133 weak_ptr_factory_.GetWeakPtr(),
126 distillation_succeeded)); 134 distillation_succeeded));
127 } 135 }
128 136
129 void TaskTracker::DoSaveCallbacks(bool distillation_succeeded) { 137 void TaskTracker::OnDistillerFinished(
138 scoped_ptr<DistilledArticleProto> distilled_article) {
139 if (content_ready_) {
140 return;
141 }
142
143 DistilledArticleReady(distilled_article.Pass());
144 if (content_ready_) {
145 AddDistilledContentToStore(*distilled_article_);
146 }
147
148 ContentSourceFinished();
149 }
150
151 void TaskTracker::CancelPendingSources() {
152 base::MessageLoop::current()->DeleteSoon(FROM_HERE, distiller_.release());
153 }
154
155 void TaskTracker::OnBlobFetched(
156 bool success,
157 scoped_ptr<DistilledArticleProto> distilled_article) {
158 blob_fetcher_running_ = false;
159
160 if (content_ready_) {
161 return;
162 }
163
164 DistilledArticleReady(distilled_article.Pass());
165
166 ContentSourceFinished();
167 }
168
169 bool TaskTracker::IsAnySourceRunning() const {
170 return distiller_ || blob_fetcher_running_;
171 }
172
173 void TaskTracker::ContentSourceFinished() {
174 if (content_ready_) {
175 CancelPendingSources();
176 } else if (!IsAnySourceRunning()) {
177 distilled_article_.reset(new DistilledArticleProto());
178 NotifyViewersAndCallbacks();
179 }
180 }
181
182 void TaskTracker::DistilledArticleReady(
183 scoped_ptr<DistilledArticleProto> distilled_article) {
184 DCHECK(!content_ready_);
185
186 if (distilled_article->pages_size() == 0) {
187 return;
188 }
189
190 content_ready_ = true;
191
192 distilled_article_ = distilled_article.Pass();
193 entry_.set_title(distilled_article_->title());
194 entry_.clear_pages();
195 for (int i = 0; i < distilled_article_->pages_size(); ++i) {
196 sync_pb::ArticlePage* page = entry_.add_pages();
197 page->set_url(distilled_article_->pages(i).url());
198 }
199
200 NotifyViewersAndCallbacks();
201 }
202
203 void TaskTracker::NotifyViewersAndCallbacks() {
204 for (size_t i = 0; i < viewers_.size(); ++i) {
205 NotifyViewer(viewers_[i]);
206 }
207
208 // Already inside a callback run SaveCallbacks directly.
209 DoSaveCallbacks(content_ready_);
210 }
211
212 void TaskTracker::NotifyViewer(ViewRequestDelegate* delegate) {
213 delegate->OnArticleReady(distilled_article_.get());
214 }
215
216 void TaskTracker::DoSaveCallbacks(bool success) {
130 if (!save_callbacks_.empty()) { 217 if (!save_callbacks_.empty()) {
131 for (size_t i = 0; i < save_callbacks_.size(); ++i) { 218 for (size_t i = 0; i < save_callbacks_.size(); ++i) {
132 DCHECK(!save_callbacks_[i].is_null()); 219 DCHECK(!save_callbacks_[i].is_null());
133 save_callbacks_[i].Run( 220 save_callbacks_[i].Run(
134 entry_, distilled_article_.get(), distillation_succeeded); 221 entry_, distilled_article_.get(), success);
135 } 222 }
136 223
137 save_callbacks_.clear(); 224 save_callbacks_.clear();
138 MaybeCancel(); 225 MaybeCancel();
139 } 226 }
140 } 227 }
141 228
142 void TaskTracker::NotifyViewer(ViewRequestDelegate* delegate) {
143 DCHECK(content_ready_);
144 delegate->OnArticleReady(distilled_article_.get());
145 }
146
147 void TaskTracker::OnDistillerFinished(
148 scoped_ptr<DistilledArticleProto> distilled_article) {
149 OnDistilledArticleReady(distilled_article.Pass());
150 }
151
152 void TaskTracker::OnDistilledArticleReady(
153 scoped_ptr<DistilledArticleProto> distilled_article) {
154 distilled_article_ = distilled_article.Pass();
155 bool distillation_successful = false;
156 if (distilled_article_->pages_size() > 0) {
157 distillation_successful = true;
158 entry_.set_title(distilled_article_->title());
159 // Reset the pages.
160 entry_.clear_pages();
161 for (int i = 0; i < distilled_article_->pages_size(); ++i) {
162 sync_pb::ArticlePage* page = entry_.add_pages();
163 page->set_url(distilled_article_->pages(i).url());
164 }
165 }
166
167 content_ready_ = true;
168
169 for (size_t i = 0; i < viewers_.size(); ++i) {
170 NotifyViewer(viewers_[i]);
171 }
172
173 // Already inside a callback run SaveCallbacks directly.
174 DoSaveCallbacks(distillation_successful);
175 }
176
177 void TaskTracker::OnArticleDistillationUpdated( 229 void TaskTracker::OnArticleDistillationUpdated(
178 const ArticleDistillationUpdate& article_update) { 230 const ArticleDistillationUpdate& article_update) {
179 for (size_t i = 0; i < viewers_.size(); ++i) { 231 for (size_t i = 0; i < viewers_.size(); ++i) {
180 viewers_[i]->OnArticleUpdated(article_update); 232 viewers_[i]->OnArticleUpdated(article_update);
181 } 233 }
182 } 234 }
183 235
236 void TaskTracker::AddDistilledContentToStore(
237 const DistilledArticleProto& content) {
238 if (content_store_) {
239 content_store_->SaveContent(
240 entry_, content, DistilledContentStore::SaveCallback());
241 }
242 }
243
244
184 } // namespace dom_distiller 245 } // namespace dom_distiller
OLDNEW
« no previous file with comments | « components/dom_distiller/core/task_tracker.h ('k') | components/dom_distiller/core/task_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698