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

Side by Side Diff: components/sync_sessions/sessions_sync_manager.cc

Issue 2958303002: [Sync] Maintain a global_id mapping to update UserEvents that references navigations (Closed)
Patch Set: Rebase Created 3 years, 5 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/sync_sessions/sessions_sync_manager.h" 5 #include "components/sync_sessions/sessions_sync_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/format_macros.h" 10 #include "base/format_macros.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 const int kMaxSyncNavigationCount = 6; 44 const int kMaxSyncNavigationCount = 6;
45 45
46 // The URL at which the set of synced tabs is displayed. We treat it differently 46 // The URL at which the set of synced tabs is displayed. We treat it differently
47 // from all other URL's as accessing it triggers a sync refresh of Sessions. 47 // from all other URL's as accessing it triggers a sync refresh of Sessions.
48 const char kNTPOpenTabSyncURL[] = "chrome://newtab/#open_tabs"; 48 const char kNTPOpenTabSyncURL[] = "chrome://newtab/#open_tabs";
49 49
50 // Default number of days without activity after which a session is considered 50 // Default number of days without activity after which a session is considered
51 // stale and becomes a candidate for garbage collection. 51 // stale and becomes a candidate for garbage collection.
52 const int kDefaultStaleSessionThresholdDays = 14; // 2 weeks. 52 const int kDefaultStaleSessionThresholdDays = 14; // 2 weeks.
53 53
54 // Clean up navigation tracking when we have over this many global_ids.
55 const size_t kNavigationTrackingCleanupThreshold = 100;
56
57 // When we clean up navigation tracking, delete this many global_ids.
58 const int kNavigationTrackingCleanupAmount = 10;
59
60 // Used to record conflict information into histogram Sync.GlobalIdConflict.
61 enum SyncGlobalIdConflict {
62 CONFLICT = 0,
63 NO_CONFLICT_NEW_ID,
64 NO_CONFLICT_SAME_IDS,
65 CONFLICT_MAX,
66 };
67
54 // Comparator function for use with std::sort that will sort tabs by 68 // Comparator function for use with std::sort that will sort tabs by
55 // descending timestamp (i.e., most recent first). 69 // descending timestamp (i.e., most recent first).
56 bool TabsRecencyComparator(const sessions::SessionTab* t1, 70 bool TabsRecencyComparator(const sessions::SessionTab* t1,
57 const sessions::SessionTab* t2) { 71 const sessions::SessionTab* t2) {
58 return t1->timestamp > t2->timestamp; 72 return t1->timestamp > t2->timestamp;
59 } 73 }
60 74
61 // Comparator function for use with std::sort that will sort sessions by 75 // Comparator function for use with std::sort that will sort sessions by
62 // descending modified_time (i.e., most recent first). 76 // descending modified_time (i.e., most recent first).
63 bool SessionsRecencyComparator(const SyncedSession* s1, 77 bool SessionsRecencyComparator(const SyncedSession* s1,
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 GURL virtual_url = 585 GURL virtual_url =
572 modified_tab->GetVirtualURLAtIndex(modified_tab->GetCurrentEntryIndex()); 586 modified_tab->GetVirtualURLAtIndex(modified_tab->GetCurrentEntryIndex());
573 if (virtual_url.is_valid() && 587 if (virtual_url.is_valid() &&
574 virtual_url.spec() == kNTPOpenTabSyncURL) { 588 virtual_url.spec() == kNTPOpenTabSyncURL) {
575 DVLOG(1) << "Triggering sync refresh for sessions datatype."; 589 DVLOG(1) << "Triggering sync refresh for sessions datatype.";
576 if (!datatype_refresh_callback_.is_null()) 590 if (!datatype_refresh_callback_.is_null())
577 datatype_refresh_callback_.Run(); 591 datatype_refresh_callback_.Run();
578 } 592 }
579 } 593 }
580 594
595 sessions::SerializedNavigationEntry current;
596 modified_tab->GetSerializedNavigationAtIndex(
vabr (Chromium) 2017/07/22 08:22:22 This might be on the path of the crash in https://
597 modified_tab->GetCurrentEntryIndex(), &current);
598 TrackNavigationIds(current);
599
581 if (local_tab_pool_out_of_sync_) { 600 if (local_tab_pool_out_of_sync_) {
582 // If our tab pool is corrupt, pay the price of a full re-association to 601 // If our tab pool is corrupt, pay the price of a full re-association to
583 // fix things up. This takes care of the new tab modification as well. 602 // fix things up. This takes care of the new tab modification as well.
584 bool rebuild_association_succeeded = RebuildAssociations(); 603 bool rebuild_association_succeeded = RebuildAssociations();
585 DCHECK(!rebuild_association_succeeded || !local_tab_pool_out_of_sync_); 604 DCHECK(!rebuild_association_succeeded || !local_tab_pool_out_of_sync_);
586 return; 605 return;
587 } 606 }
588 607
589 syncer::SyncChangeList changes; 608 syncer::SyncChangeList changes;
590 AssociateTab(modified_tab, &changes); 609 AssociateTab(modified_tab, &changes);
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 DVLOG(1) << "Found stale session " << session_tag << " with age " 1297 DVLOG(1) << "Found stale session " << session_tag << " with age "
1279 << session_age_in_days << ", deleting."; 1298 << session_age_in_days << ", deleting.";
1280 DeleteForeignSessionInternal(session_tag, &changes); 1299 DeleteForeignSessionInternal(session_tag, &changes);
1281 } 1300 }
1282 } 1301 }
1283 1302
1284 if (!changes.empty()) 1303 if (!changes.empty())
1285 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); 1304 sync_processor_->ProcessSyncChanges(FROM_HERE, changes);
1286 } 1305 }
1287 1306
1307 void SessionsSyncManager::AddGlobalIdChangeObserver(
1308 syncer::GlobalIdChange callback) {
1309 global_id_change_observers_.push_back(std::move(callback));
1310 }
1311
1312 int64_t SessionsSyncManager::GetLatestGlobalId(int64_t global_id) {
1313 auto g2u_iter = global_to_unique_.find(global_id);
1314 if (g2u_iter != global_to_unique_.end()) {
1315 auto u2g_iter = unique_to_current_global_.find(g2u_iter->second);
1316 if (u2g_iter != unique_to_current_global_.end()) {
1317 return u2g_iter->second;
1318 }
1319 }
1320 return global_id;
1321 }
1322
1288 // static 1323 // static
1289 std::string SessionsSyncManager::TagHashFromSpecifics( 1324 std::string SessionsSyncManager::TagHashFromSpecifics(
1290 const sync_pb::SessionSpecifics& specifics) { 1325 const sync_pb::SessionSpecifics& specifics) {
1291 return syncer::GenerateSyncableHash(syncer::SESSIONS, 1326 return syncer::GenerateSyncableHash(syncer::SESSIONS,
1292 TagFromSpecifics(specifics)); 1327 TagFromSpecifics(specifics));
1293 } 1328 }
1294 1329
1330 void SessionsSyncManager::TrackNavigationIds(
1331 const sessions::SerializedNavigationEntry& current) {
1332 // The expectation is that global_id will update for a given unique_id, which
1333 // should accurately and uniquely represent a single navigation. It is
1334 // theoretically possible for two unique_ids to map to the same global_id, but
1335 // hopefully rare enough that it doesn't cause much harm. Lets record metrics
1336 // verify this theory.
1337 int64_t global_id = current.timestamp().ToInternalValue();
1338 // It is possible that the global_id has not been set yet for this navigation.
1339 // In this case there's nothing here for us to track yet.
1340 if (global_id == 0) {
1341 return;
1342 }
1343
1344 int unique_id = current.unique_id();
1345 DCHECK_NE(0, unique_id);
1346
1347 auto g2u_iter = global_to_unique_.find(global_id);
1348 if (g2u_iter == global_to_unique_.end()) {
1349 global_to_unique_.insert(g2u_iter, std::make_pair(global_id, unique_id));
1350 UMA_HISTOGRAM_ENUMERATION("Sync.GlobalIdConflict", NO_CONFLICT_NEW_ID,
1351 CONFLICT_MAX);
1352 } else if (g2u_iter->second != unique_id) {
1353 UMA_HISTOGRAM_ENUMERATION("Sync.GlobalIdConflict", CONFLICT, CONFLICT_MAX);
1354 } else {
1355 UMA_HISTOGRAM_ENUMERATION("Sync.GlobalIdConflict", NO_CONFLICT_SAME_IDS,
1356 CONFLICT_MAX);
1357 }
1358
1359 auto u2g_iter = unique_to_current_global_.find(unique_id);
1360 if (u2g_iter == unique_to_current_global_.end()) {
1361 unique_to_current_global_.insert(u2g_iter,
1362 std::make_pair(unique_id, global_id));
1363 } else if (u2g_iter->second != global_id) {
1364 // Remember the old_global_id before we insert and invalidate out iter.
1365 int64_t old_global_id = u2g_iter->second;
1366
1367 // TODO(skym): Use insert_or_assign with hint once on C++17.
1368 unique_to_current_global_[unique_id] = global_id;
1369
1370 // This should be done after updating unique_to_current_global_ in case one
1371 // of our observers calls into GetLatestGlobalId().
1372 for (auto& observer : global_id_change_observers_) {
1373 observer.Run(old_global_id, global_id);
1374 }
1375 }
1376
1377 CleanupNavigationTracking();
1378 }
1379
1380 void SessionsSyncManager::CleanupNavigationTracking() {
1381 DCHECK(kNavigationTrackingCleanupThreshold >
1382 kNavigationTrackingCleanupAmount);
1383
1384 // |global_to_unique_| is implicitly ordered by least recently created, which
1385 // means we can drop from the beginning.
1386 if (global_to_unique_.size() > kNavigationTrackingCleanupThreshold) {
1387 auto iter = global_to_unique_.begin();
1388 std::advance(iter, kNavigationTrackingCleanupAmount);
1389 global_to_unique_.erase(global_to_unique_.begin(), iter);
1390
1391 // While |unique_id|s do get bigger for the most part, this isn't a great
1392 // thing to make assumptions about, and an old tab may get refreshed often
1393 // and still be very important. So instead just delete anything that's
1394 // orphaned from |global_to_unique_|.
1395 base::EraseIf(unique_to_current_global_,
1396 [this](const std::pair<int, int64_t> kv) {
1397 return !base::ContainsKey(global_to_unique_, kv.second);
1398 });
1399 }
1400 }
1401
1295 }; // namespace sync_sessions 1402 }; // namespace sync_sessions
OLDNEW
« no previous file with comments | « components/sync_sessions/sessions_sync_manager.h ('k') | components/sync_sessions/sessions_sync_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698