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

Side by Side Diff: components/reading_list/reading_list_entry.cc

Issue 2511723002: Enable RL sync by default on iOS (Closed)
Patch Set: rebase Created 4 years 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/reading_list/reading_list_entry.h"
6
7 #include "base/json/json_string_value_serializer.h"
8 #include "base/memory/ptr_util.h"
9 #include "components/reading_list/offline_url_utils.h"
10 #include "components/reading_list/proto/reading_list.pb.h"
11 #include "components/sync/protocol/reading_list_specifics.pb.h"
12 #include "net/base/backoff_entry_serializer.h"
13
14 // The backoff time is the following: 10min, 10min, 1h, 2h, 2h..., starting
15 // after the first failure.
16 const net::BackoffEntry::Policy ReadingListEntry::kBackoffPolicy = {
17 // Number of initial errors (in sequence) to ignore before applying
18 // exponential back-off rules.
19 2,
20
21 // Initial delay for exponential back-off in ms.
22 10 * 60 * 1000, // 10 minutes.
23
24 // Factor by which the waiting time will be multiplied.
25 6,
26
27 // Fuzzing percentage. ex: 10% will spread requests randomly
28 // between 90%-100% of the calculated time.
29 0.1, // 10%.
30
31 // Maximum amount of time we are willing to delay our request in ms.
32 2 * 3600 * 1000, // 2 hours.
33
34 // Time to keep an entry from being discarded even when it
35 // has no significant state, -1 to never discard.
36 -1,
37
38 true, // Don't use initial delay unless the last request was an error.
39 };
40
41 ReadingListEntry::ReadingListEntry(const GURL& url, const std::string& title)
42 : ReadingListEntry(url, title, nullptr){};
43
44 ReadingListEntry::ReadingListEntry(const GURL& url,
45 const std::string& title,
46 std::unique_ptr<net::BackoffEntry> backoff)
47 : ReadingListEntry(url,
48 title,
49 0,
50 0,
51 WAITING,
52 base::FilePath(),
53 0,
54 std::move(backoff)) {}
55
56 ReadingListEntry::ReadingListEntry(
57 const GURL& url,
58 const std::string& title,
59 int64_t creation_time,
60 int64_t update_time,
61 ReadingListEntry::DistillationState distilled_state,
62 const base::FilePath& distilled_path,
63 int failed_download_counter,
64 std::unique_ptr<net::BackoffEntry> backoff)
65 : url_(url),
66 title_(title),
67 distilled_path_(distilled_path),
68 distilled_state_(distilled_state),
69 failed_download_counter_(failed_download_counter),
70 creation_time_us_(creation_time),
71 update_time_us_(update_time) {
72 if (backoff) {
73 backoff_ = std::move(backoff);
74 } else {
75 backoff_ = base::MakeUnique<net::BackoffEntry>(&kBackoffPolicy);
76 }
77 if (creation_time_us_ == 0) {
78 DCHECK(update_time_us_ == 0);
79 creation_time_us_ =
80 (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds();
81 update_time_us_ = creation_time_us_;
82 }
83 DCHECK(!url.is_empty());
84 DCHECK(url.is_valid());
85 }
86
87 ReadingListEntry::ReadingListEntry(ReadingListEntry&& entry)
88 : url_(std::move(entry.url_)),
89 title_(std::move(entry.title_)),
90 distilled_path_(std::move(entry.distilled_path_)),
91 distilled_state_(std::move(entry.distilled_state_)),
92 backoff_(std::move(entry.backoff_)),
93 failed_download_counter_(std::move(entry.failed_download_counter_)),
94 creation_time_us_(std::move(entry.creation_time_us_)),
95 update_time_us_(std::move(entry.update_time_us_)) {}
96
97 ReadingListEntry::~ReadingListEntry() {}
98
99 const GURL& ReadingListEntry::URL() const {
100 return url_;
101 }
102
103 const std::string& ReadingListEntry::Title() const {
104 return title_;
105 }
106
107 ReadingListEntry::DistillationState ReadingListEntry::DistilledState() const {
108 return distilled_state_;
109 }
110
111 const base::FilePath& ReadingListEntry::DistilledPath() const {
112 return distilled_path_;
113 }
114
115 base::TimeDelta ReadingListEntry::TimeUntilNextTry() const {
116 return backoff_->GetTimeUntilRelease();
117 }
118
119 int ReadingListEntry::FailedDownloadCounter() const {
120 return failed_download_counter_;
121 }
122
123 ReadingListEntry& ReadingListEntry::operator=(ReadingListEntry&& other) {
124 url_ = std::move(other.url_);
125 title_ = std::move(other.title_);
126 distilled_path_ = std::move(other.distilled_path_);
127 distilled_state_ = std::move(other.distilled_state_);
128 backoff_ = std::move(other.backoff_);
129 failed_download_counter_ = std::move(other.failed_download_counter_);
130 creation_time_us_ = std::move(other.creation_time_us_);
131 update_time_us_ = std::move(other.update_time_us_);
132 return *this;
133 }
134
135 bool ReadingListEntry::operator==(const ReadingListEntry& other) const {
136 return url_ == other.url_;
137 }
138
139 void ReadingListEntry::SetTitle(const std::string& title) {
140 title_ = title;
141 }
142
143 void ReadingListEntry::SetDistilledPath(const base::FilePath& path) {
144 DCHECK(!path.empty());
145 distilled_path_ = path;
146 distilled_state_ = PROCESSED;
147 backoff_->Reset();
148 failed_download_counter_ = 0;
149 }
150
151 void ReadingListEntry::SetDistilledState(DistillationState distilled_state) {
152 DCHECK(distilled_state != PROCESSED); // use SetDistilledPath instead.
153 DCHECK(distilled_state != WAITING);
154 // Increase time until next retry exponentially if the state change from a
155 // non-error state to an error state.
156 if ((distilled_state == WILL_RETRY || distilled_state == ERROR) &&
157 distilled_state_ != WILL_RETRY && distilled_state_ != ERROR) {
158 backoff_->InformOfRequest(false);
159 failed_download_counter_++;
160 }
161
162 distilled_state_ = distilled_state;
163 distilled_path_ = base::FilePath();
164 }
165
166 int64_t ReadingListEntry::UpdateTime() const {
167 return update_time_us_;
168 }
169
170 int64_t ReadingListEntry::CreationTime() const {
171 return creation_time_us_;
172 }
173
174 void ReadingListEntry::MarkEntryUpdated() {
175 update_time_us_ =
176 (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds();
177 }
178
179 // static
180 std::unique_ptr<ReadingListEntry> ReadingListEntry::FromReadingListLocal(
181 const reading_list::ReadingListLocal& pb_entry) {
182 if (!pb_entry.has_url()) {
183 return nullptr;
184 }
185 GURL url(pb_entry.url());
186 if (url.is_empty() || !url.is_valid()) {
187 return nullptr;
188 }
189 std::string title;
190 if (pb_entry.has_title()) {
191 title = pb_entry.title();
192 }
193
194 int64_t creation_time_us = 0;
195 if (pb_entry.has_creation_time_us()) {
196 creation_time_us = pb_entry.creation_time_us();
197 }
198
199 int64_t update_time_us = 0;
200 if (pb_entry.has_update_time_us()) {
201 update_time_us = pb_entry.update_time_us();
202 }
203
204 ReadingListEntry::DistillationState distillation_state =
205 ReadingListEntry::WAITING;
206 if (pb_entry.has_distillation_state()) {
207 switch (pb_entry.distillation_state()) {
208 case reading_list::ReadingListLocal::WAITING:
209 distillation_state = ReadingListEntry::WAITING;
210 break;
211 case reading_list::ReadingListLocal::PROCESSING:
212 distillation_state = ReadingListEntry::PROCESSING;
213 break;
214 case reading_list::ReadingListLocal::PROCESSED:
215 distillation_state = ReadingListEntry::PROCESSED;
216 break;
217 case reading_list::ReadingListLocal::WILL_RETRY:
218 distillation_state = ReadingListEntry::WILL_RETRY;
219 break;
220 case reading_list::ReadingListLocal::ERROR:
221 distillation_state = ReadingListEntry::ERROR;
222 break;
223 }
224 }
225
226 base::FilePath distilled_path;
227 if (pb_entry.has_distilled_path()) {
228 distilled_path = base::FilePath(pb_entry.distilled_path());
229 }
230
231 int64_t failed_download_counter = 0;
232 if (pb_entry.has_failed_download_counter()) {
233 failed_download_counter = pb_entry.failed_download_counter();
234 }
235
236 std::unique_ptr<net::BackoffEntry> backoff;
237 if (pb_entry.has_backoff()) {
238 JSONStringValueDeserializer deserializer(pb_entry.backoff());
239 std::unique_ptr<base::Value> value(
240 deserializer.Deserialize(nullptr, nullptr));
241 if (value) {
242 backoff = net::BackoffEntrySerializer::DeserializeFromValue(
243 *value, &kBackoffPolicy, nullptr, base::Time::Now());
244 }
245 }
246
247 return base::WrapUnique<ReadingListEntry>(new ReadingListEntry(
248 url, title, creation_time_us, update_time_us, distillation_state,
249 distilled_path, failed_download_counter, std::move(backoff)));
250 }
251
252 // static
253 std::unique_ptr<ReadingListEntry> ReadingListEntry::FromReadingListSpecifics(
254 const sync_pb::ReadingListSpecifics& pb_entry) {
255 if (!pb_entry.has_url()) {
256 return nullptr;
257 }
258 GURL url(pb_entry.url());
259 if (url.is_empty() || !url.is_valid()) {
260 return nullptr;
261 }
262 std::string title;
263 if (pb_entry.has_title()) {
264 title = pb_entry.title();
265 }
266
267 int64_t creation_time_us = 0;
268 if (pb_entry.has_creation_time_us()) {
269 creation_time_us = pb_entry.creation_time_us();
270 }
271
272 int64_t update_time_us = 0;
273 if (pb_entry.has_update_time_us()) {
274 update_time_us = pb_entry.update_time_us();
275 }
276
277 return base::WrapUnique<ReadingListEntry>(
278 new ReadingListEntry(url, title, creation_time_us, update_time_us,
279 WAITING, base::FilePath(), 0, nullptr));
280 }
281
282 void ReadingListEntry::MergeLocalStateFrom(ReadingListEntry& other) {
283 distilled_path_ = std::move(other.distilled_path_);
284 distilled_state_ = std::move(other.distilled_state_);
285 backoff_ = std::move(other.backoff_);
286 failed_download_counter_ = std::move(other.failed_download_counter_);
287 }
288
289 std::unique_ptr<reading_list::ReadingListLocal>
290 ReadingListEntry::AsReadingListLocal(bool read) const {
291 std::unique_ptr<reading_list::ReadingListLocal> pb_entry =
292 base::MakeUnique<reading_list::ReadingListLocal>();
293
294 // URL is used as the key for the database and sync as there is only one entry
295 // per URL.
296 pb_entry->set_entry_id(URL().spec());
297 pb_entry->set_title(Title());
298 pb_entry->set_url(URL().spec());
299 pb_entry->set_creation_time_us(CreationTime());
300 pb_entry->set_update_time_us(UpdateTime());
301
302 if (read) {
303 pb_entry->set_status(reading_list::ReadingListLocal::READ);
304 } else {
305 pb_entry->set_status(reading_list::ReadingListLocal::UNREAD);
306 }
307
308 reading_list::ReadingListLocal::DistillationState distilation_state;
309 switch (DistilledState()) {
310 case ReadingListEntry::WAITING:
311 distilation_state = reading_list::ReadingListLocal::WAITING;
312 break;
313 case ReadingListEntry::PROCESSING:
314 distilation_state = reading_list::ReadingListLocal::PROCESSING;
315 break;
316 case ReadingListEntry::PROCESSED:
317 distilation_state = reading_list::ReadingListLocal::PROCESSED;
318 break;
319 case ReadingListEntry::WILL_RETRY:
320 distilation_state = reading_list::ReadingListLocal::WILL_RETRY;
321 break;
322 case ReadingListEntry::ERROR:
323 distilation_state = reading_list::ReadingListLocal::ERROR;
324 break;
325 }
326 pb_entry->set_distillation_state(distilation_state);
327 if (!DistilledPath().empty()) {
328 pb_entry->set_distilled_path(DistilledPath().value());
329 }
330 pb_entry->set_failed_download_counter(failed_download_counter_);
331
332 if (backoff_) {
333 std::unique_ptr<base::Value> backoff =
334 net::BackoffEntrySerializer::SerializeToValue(*backoff_,
335 base::Time::Now());
336
337 std::string output;
338 JSONStringValueSerializer serializer(&output);
339 serializer.Serialize(*backoff);
340 pb_entry->set_backoff(output);
341 }
342 return pb_entry;
343 }
344
345 std::unique_ptr<sync_pb::ReadingListSpecifics>
346 ReadingListEntry::AsReadingListSpecifics(bool read) const {
347 std::unique_ptr<sync_pb::ReadingListSpecifics> pb_entry =
348 base::MakeUnique<sync_pb::ReadingListSpecifics>();
349
350 // URL is used as the key for the database and sync as there is only one entry
351 // per URL.
352 pb_entry->set_entry_id(URL().spec());
353 pb_entry->set_title(Title());
354 pb_entry->set_url(URL().spec());
355 pb_entry->set_creation_time_us(CreationTime());
356 pb_entry->set_update_time_us(UpdateTime());
357
358 if (read) {
359 pb_entry->set_status(sync_pb::ReadingListSpecifics::READ);
360 } else {
361 pb_entry->set_status(sync_pb::ReadingListSpecifics::UNREAD);
362 }
363
364 return pb_entry;
365 }
366
367 bool ReadingListEntry::CompareEntryUpdateTime(const ReadingListEntry& lhs,
368 const ReadingListEntry& rhs) {
369 return lhs.UpdateTime() > rhs.UpdateTime();
370 }
OLDNEW
« no previous file with comments | « components/reading_list/reading_list_entry.h ('k') | components/reading_list/reading_list_entry_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698